4ebcdc73a09d6a769724d676e8508c1ff3c48e40
[openwrt/staging/stintel.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 --- /dev/null
531 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
532 @@ -0,0 +1,173 @@
533 +menuconfig FSL_SDK_DPAA_ETH
534 + tristate "DPAA Ethernet"
535 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && FSL_SDK_FMAN && !FSL_DPAA_ETH
536 + select PHYLIB
537 + help
538 + Data Path Acceleration Architecture Ethernet driver,
539 + supporting the Freescale QorIQ chips.
540 + Depends on Freescale Buffer Manager and Queue Manager
541 + driver and Frame Manager Driver.
542 +
543 +if FSL_SDK_DPAA_ETH
544 +
545 +config FSL_DPAA_HOOKS
546 + bool "DPAA Ethernet driver hooks"
547 +
548 +config FSL_DPAA_CEETM
549 + bool "DPAA CEETM QoS"
550 + depends on NET_SCHED
551 + default n
552 + help
553 + Enable QoS offloading support through the CEETM hardware block.
554 +
555 +config FSL_DPAA_OFFLINE_PORTS
556 + bool "Offline Ports support"
557 + depends on FSL_SDK_DPAA_ETH
558 + default y
559 + help
560 + The Offline Parsing / Host Command ports (short: OH ports, of Offline ports) provide
561 + most of the functionality of the regular, online ports, except they receive their
562 + frames from a core or an accelerator on the SoC, via QMan frame queues,
563 + rather than directly from the network.
564 + Offline ports are configured via PCD (Parse-Classify-Distribute) schemes, just like
565 + any online FMan port. They deliver the processed frames to frame queues, according
566 + to the applied PCD configurations.
567 +
568 + Choosing this feature will not impact the functionality and/or performance of the system,
569 + so it is safe to have it.
570 +
571 +config FSL_DPAA_ADVANCED_DRIVERS
572 + bool "Advanced DPAA Ethernet drivers"
573 + depends on FSL_SDK_DPAA_ETH
574 + default y
575 + help
576 + Besides the standard DPAA Ethernet driver the DPAA Proxy initialization driver
577 + is needed to support advanced scenarios. Select this to also build the advanced
578 + drivers.
579 +
580 +config FSL_DPAA_ETH_JUMBO_FRAME
581 + bool "Optimize for jumbo frames"
582 + default n
583 + help
584 + Optimize the DPAA Ethernet driver throughput for large frames
585 + termination traffic (e.g. 4K and above).
586 + NOTE: This option can only be used if FSL_FM_MAX_FRAME_SIZE
587 + is set to 9600 bytes.
588 + Using this option in combination with small frames increases
589 + significantly the driver's memory footprint and may even deplete
590 + the system memory. Also, the skb truesize is altered and messages
591 + from the stack that warn against this are bypassed.
592 + This option is not available on LS1043.
593 +
594 +config FSL_DPAA_TS
595 + bool "Linux compliant timestamping"
596 + depends on FSL_SDK_DPAA_ETH
597 + default n
598 + help
599 + Enable Linux API compliant timestamping support.
600 +
601 +config FSL_DPAA_1588
602 + bool "IEEE 1588-compliant timestamping"
603 + depends on FSL_SDK_DPAA_ETH
604 + select FSL_DPAA_TS
605 + default n
606 + help
607 + Enable IEEE1588 support code.
608 +
609 +config FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
610 + bool "Use driver's Tx queue selection mechanism"
611 + default y
612 + depends on FSL_SDK_DPAA_ETH
613 + help
614 + The DPAA-Ethernet driver defines a ndo_select_queue() callback for optimal selection
615 + of the egress FQ. That will override the XPS support for this netdevice.
616 + If for whatever reason you want to be in control of the egress FQ-to-CPU selection and mapping,
617 + or simply don't want to use the driver's ndo_select_queue() callback, then unselect this
618 + and use the standard XPS support instead.
619 +
620 +config FSL_DPAA_ETH_MAX_BUF_COUNT
621 + int "Maximum nuber of buffers in private bpool"
622 + depends on FSL_SDK_DPAA_ETH
623 + range 64 2048
624 + default "128"
625 + help
626 + The maximum number of buffers to be by default allocated in the DPAA-Ethernet private port's
627 + buffer pool. One needn't normally modify this, as it has probably been tuned for performance
628 + already. This cannot be lower than DPAA_ETH_REFILL_THRESHOLD.
629 +
630 +config FSL_DPAA_ETH_REFILL_THRESHOLD
631 + int "Private bpool refill threshold"
632 + depends on FSL_SDK_DPAA_ETH
633 + range 32 FSL_DPAA_ETH_MAX_BUF_COUNT
634 + default "80"
635 + help
636 + The DPAA-Ethernet driver will start replenishing buffer pools whose count
637 + falls below this threshold. This must be related to DPAA_ETH_MAX_BUF_COUNT. One needn't normally
638 + modify this value unless one has very specific performance reasons.
639 +
640 +config FSL_DPAA_CS_THRESHOLD_1G
641 + hex "Egress congestion threshold on 1G ports"
642 + depends on FSL_SDK_DPAA_ETH
643 + range 0x1000 0x10000000
644 + default "0x06000000"
645 + help
646 + The size in bytes of the egress Congestion State notification threshold on 1G ports.
647 + The 1G dTSECs can quite easily be flooded by cores doing Tx in a tight loop
648 + (e.g. by sending UDP datagrams at "while(1) speed"),
649 + and the larger the frame size, the more acute the problem.
650 + So we have to find a balance between these factors:
651 + - avoiding the device staying congested for a prolonged time (risking
652 + the netdev watchdog to fire - see also the tx_timeout module param);
653 + - affecting performance of protocols such as TCP, which otherwise
654 + behave well under the congestion notification mechanism;
655 + - preventing the Tx cores from tightly-looping (as if the congestion
656 + threshold was too low to be effective);
657 + - running out of memory if the CS threshold is set too high.
658 +
659 +config FSL_DPAA_CS_THRESHOLD_10G
660 + hex "Egress congestion threshold on 10G ports"
661 + depends on FSL_SDK_DPAA_ETH
662 + range 0x1000 0x20000000
663 + default "0x10000000"
664 + help
665 + The size in bytes of the egress Congestion State notification threshold on 10G ports.
666 +
667 +config FSL_DPAA_INGRESS_CS_THRESHOLD
668 + hex "Ingress congestion threshold on FMan ports"
669 + depends on FSL_SDK_DPAA_ETH
670 + default "0x10000000"
671 + help
672 + The size in bytes of the ingress tail-drop threshold on FMan ports.
673 + Traffic piling up above this value will be rejected by QMan and discarded by FMan.
674 +
675 +config FSL_DPAA_ETH_DEBUGFS
676 + bool "DPAA Ethernet debugfs interface"
677 + depends on DEBUG_FS && FSL_SDK_DPAA_ETH
678 + default y
679 + help
680 + This option compiles debugfs code for the DPAA Ethernet driver.
681 +
682 +config FSL_DPAA_ETH_DEBUG
683 + bool "DPAA Ethernet Debug Support"
684 + depends on FSL_SDK_DPAA_ETH
685 + default n
686 + help
687 + This option compiles debug code for the DPAA Ethernet driver.
688 +
689 +config FSL_DPAA_DBG_LOOP
690 + bool "DPAA Ethernet Debug loopback"
691 + depends on FSL_DPAA_ETH_DEBUGFS && FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
692 + default n
693 + help
694 + This option allows to divert all received traffic on a certain interface A towards a
695 + selected interface B. This option is used to benchmark the HW + Ethernet driver in
696 + isolation from the Linux networking stack. The loops are controlled by debugfs entries,
697 + one for each interface. By default all loops are disabled (target value is -1). I.e. to
698 + change the loop setting for interface 4 and divert all received traffic to interface 5
699 + write Tx interface number in the receive interface debugfs file:
700 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
701 + 4->-1
702 + # echo 5 > /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
703 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
704 + 4->5
705 +endif # FSL_SDK_DPAA_ETH
706 --- /dev/null
707 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile
708 @@ -0,0 +1,46 @@
709 +#
710 +# Makefile for the Freescale Ethernet controllers
711 +#
712 +ccflags-y += -DVERSION=\"\"
713 +#
714 +# Include netcomm SW specific definitions
715 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
716 +
717 +ccflags-y += -I$(NET_DPA)
718 +
719 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_mac.o fsl_dpa.o
720 +obj-$(CONFIG_PTP_1588_CLOCK_DPAA) += dpaa_ptp.o
721 +
722 +fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o
723 +ifeq ($(CONFIG_FSL_DPAA_DBG_LOOP),y)
724 +fsl_dpa-objs += dpaa_debugfs.o
725 +endif
726 +ifeq ($(CONFIG_FSL_DPAA_1588),y)
727 +fsl_dpa-objs += dpaa_1588.o
728 +endif
729 +ifeq ($(CONFIG_FSL_DPAA_CEETM),y)
730 +ccflags-y += -Idrivers/net/ethernet/freescale/sdk_fman/src/wrapper
731 +fsl_dpa-objs += dpaa_eth_ceetm.o
732 +endif
733 +
734 +fsl_mac-objs += mac.o mac-api.o
735 +
736 +# Advanced drivers
737 +ifeq ($(CONFIG_FSL_DPAA_ADVANCED_DRIVERS),y)
738 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_advanced.o
739 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_proxy.o
740 +
741 +fsl_advanced-objs += dpaa_eth_base.o
742 +# suport for multiple drivers per kernel module comes in kernel 3.14
743 +# so we are forced to generate several modules for the advanced drivers
744 +fsl_proxy-objs += dpaa_eth_proxy.o
745 +
746 +ifeq ($(CONFIG_FSL_DPAA_OFFLINE_PORTS),y)
747 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_oh.o
748 +
749 +fsl_oh-objs += offline_port.o
750 +endif
751 +endif
752 +
753 +# Needed by the tracing framework
754 +CFLAGS_dpaa_eth.o := -I$(src)
755 --- /dev/null
756 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
757 @@ -0,0 +1,580 @@
758 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
759 + * Copyright (C) 2009 IXXAT Automation, GmbH
760 + *
761 + * DPAA Ethernet Driver -- IEEE 1588 interface functionality
762 + *
763 + * This program is free software; you can redistribute it and/or modify
764 + * it under the terms of the GNU General Public License as published by
765 + * the Free Software Foundation; either version 2 of the License, or
766 + * (at your option) any later version.
767 + *
768 + * This program is distributed in the hope that it will be useful,
769 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
770 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
771 + * GNU General Public License for more details.
772 + *
773 + * You should have received a copy of the GNU General Public License along
774 + * with this program; if not, write to the Free Software Foundation, Inc.,
775 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
776 + *
777 + */
778 +#include <linux/io.h>
779 +#include <linux/device.h>
780 +#include <linux/fs.h>
781 +#include <linux/vmalloc.h>
782 +#include <linux/spinlock.h>
783 +#include <linux/ip.h>
784 +#include <linux/ipv6.h>
785 +#include <linux/udp.h>
786 +#include <asm/div64.h>
787 +#include "dpaa_eth.h"
788 +#include "dpaa_eth_common.h"
789 +#include "dpaa_1588.h"
790 +#include "mac.h"
791 +
792 +static int dpa_ptp_init_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
793 +{
794 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
795 +
796 + circ_buf->buf = vmalloc(sizeof(struct dpa_ptp_data) * size);
797 + if (!circ_buf->buf)
798 + return 1;
799 +
800 + circ_buf->head = 0;
801 + circ_buf->tail = 0;
802 + ptp_buf->size = size;
803 + spin_lock_init(&ptp_buf->ptp_lock);
804 +
805 + return 0;
806 +}
807 +
808 +static void dpa_ptp_reset_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
809 +{
810 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
811 +
812 + circ_buf->head = 0;
813 + circ_buf->tail = 0;
814 + ptp_buf->size = size;
815 +}
816 +
817 +static int dpa_ptp_insert(struct dpa_ptp_circ_buf *ptp_buf,
818 + struct dpa_ptp_data *data)
819 +{
820 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
821 + int size = ptp_buf->size;
822 + struct dpa_ptp_data *tmp;
823 + unsigned long flags;
824 + int head, tail;
825 +
826 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
827 +
828 + head = circ_buf->head;
829 + tail = circ_buf->tail;
830 +
831 + if (CIRC_SPACE(head, tail, size) <= 0)
832 + circ_buf->tail = (tail + 1) & (size - 1);
833 +
834 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + head;
835 + memcpy(tmp, data, sizeof(struct dpa_ptp_data));
836 +
837 + circ_buf->head = (head + 1) & (size - 1);
838 +
839 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
840 +
841 + return 0;
842 +}
843 +
844 +static int dpa_ptp_is_ident_match(struct dpa_ptp_ident *dst,
845 + struct dpa_ptp_ident *src)
846 +{
847 + int ret;
848 +
849 + if ((dst->version != src->version) || (dst->msg_type != src->msg_type))
850 + return 0;
851 +
852 + if ((dst->netw_prot == src->netw_prot)
853 + || src->netw_prot == DPA_PTP_PROT_DONTCARE) {
854 + if (dst->seq_id != src->seq_id)
855 + return 0;
856 +
857 + ret = memcmp(dst->snd_port_id, src->snd_port_id,
858 + DPA_PTP_SOURCE_PORT_LENGTH);
859 + if (ret)
860 + return 0;
861 + else
862 + return 1;
863 + }
864 +
865 + return 0;
866 +}
867 +
868 +static int dpa_ptp_find_and_remove(struct dpa_ptp_circ_buf *ptp_buf,
869 + struct dpa_ptp_ident *ident,
870 + struct dpa_ptp_time *ts)
871 +{
872 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
873 + int size = ptp_buf->size;
874 + int head, tail, idx;
875 + unsigned long flags;
876 + struct dpa_ptp_data *tmp, *tmp2;
877 + struct dpa_ptp_ident *tmp_ident;
878 +
879 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
880 +
881 + head = circ_buf->head;
882 + tail = idx = circ_buf->tail;
883 +
884 + if (CIRC_CNT(head, tail, size) == 0) {
885 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
886 + return 1;
887 + }
888 +
889 + while (idx != head) {
890 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
891 + tmp_ident = &tmp->ident;
892 + if (dpa_ptp_is_ident_match(tmp_ident, ident))
893 + break;
894 + idx = (idx + 1) & (size - 1);
895 + }
896 +
897 + if (idx == head) {
898 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
899 + return 1;
900 + }
901 +
902 + ts->sec = tmp->ts.sec;
903 + ts->nsec = tmp->ts.nsec;
904 +
905 + if (idx != tail) {
906 + if (CIRC_CNT(idx, tail, size) > TS_ACCUMULATION_THRESHOLD) {
907 + tail = circ_buf->tail =
908 + (idx - TS_ACCUMULATION_THRESHOLD) & (size - 1);
909 + }
910 +
911 + while (CIRC_CNT(idx, tail, size) > 0) {
912 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
913 + idx = (idx - 1) & (size - 1);
914 + tmp2 = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
915 + *tmp = *tmp2;
916 + }
917 + }
918 + circ_buf->tail = (tail + 1) & (size - 1);
919 +
920 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
921 +
922 + return 0;
923 +}
924 +
925 +/* Parse the PTP packets
926 + *
927 + * The PTP header can be found in an IPv4 packet, IPv6 patcket or in
928 + * an IEEE802.3 ethernet frame. This function returns the position of
929 + * the PTP packet or NULL if no PTP found
930 + */
931 +static u8 *dpa_ptp_parse_packet(struct sk_buff *skb, u16 *eth_type)
932 +{
933 + u8 *pos = skb->data + ETH_ALEN + ETH_ALEN;
934 + u8 *ptp_loc = NULL;
935 + u8 msg_type;
936 + u32 access_len = ETH_ALEN + ETH_ALEN + DPA_ETYPE_LEN;
937 + struct iphdr *iph;
938 + struct udphdr *udph;
939 + struct ipv6hdr *ipv6h;
940 +
941 + /* when we can receive S/G frames we need to check the data we want to
942 + * access is in the linear skb buffer
943 + */
944 + if (!pskb_may_pull(skb, access_len))
945 + return NULL;
946 +
947 + *eth_type = *((u16 *)pos);
948 +
949 + /* Check if inner tag is here */
950 + if (*eth_type == ETH_P_8021Q) {
951 + access_len += DPA_VLAN_TAG_LEN;
952 +
953 + if (!pskb_may_pull(skb, access_len))
954 + return NULL;
955 +
956 + pos += DPA_VLAN_TAG_LEN;
957 + *eth_type = *((u16 *)pos);
958 + }
959 +
960 + pos += DPA_ETYPE_LEN;
961 +
962 + switch (*eth_type) {
963 + /* Transport of PTP over Ethernet */
964 + case ETH_P_1588:
965 + ptp_loc = pos;
966 +
967 + if (!pskb_may_pull(skb, access_len + PTP_OFFS_MSG_TYPE + 1))
968 + return NULL;
969 +
970 + msg_type = *((u8 *)(ptp_loc + PTP_OFFS_MSG_TYPE)) & 0xf;
971 + if ((msg_type == PTP_MSGTYPE_SYNC)
972 + || (msg_type == PTP_MSGTYPE_DELREQ)
973 + || (msg_type == PTP_MSGTYPE_PDELREQ)
974 + || (msg_type == PTP_MSGTYPE_PDELRESP))
975 + return ptp_loc;
976 + break;
977 + /* Transport of PTP over IPv4 */
978 + case ETH_P_IP:
979 + iph = (struct iphdr *)pos;
980 + access_len += sizeof(struct iphdr);
981 +
982 + if (!pskb_may_pull(skb, access_len))
983 + return NULL;
984 +
985 + if (ntohs(iph->protocol) != IPPROTO_UDP)
986 + return NULL;
987 +
988 + access_len += iph->ihl * 4 - sizeof(struct iphdr) +
989 + sizeof(struct udphdr);
990 +
991 + if (!pskb_may_pull(skb, access_len))
992 + return NULL;
993 +
994 + pos += iph->ihl * 4;
995 + udph = (struct udphdr *)pos;
996 + if (ntohs(udph->dest) != 319)
997 + return NULL;
998 + ptp_loc = pos + sizeof(struct udphdr);
999 + break;
1000 + /* Transport of PTP over IPv6 */
1001 + case ETH_P_IPV6:
1002 + ipv6h = (struct ipv6hdr *)pos;
1003 +
1004 + access_len += sizeof(struct ipv6hdr) + sizeof(struct udphdr);
1005 +
1006 + if (ntohs(ipv6h->nexthdr) != IPPROTO_UDP)
1007 + return NULL;
1008 +
1009 + pos += sizeof(struct ipv6hdr);
1010 + udph = (struct udphdr *)pos;
1011 + if (ntohs(udph->dest) != 319)
1012 + return NULL;
1013 + ptp_loc = pos + sizeof(struct udphdr);
1014 + break;
1015 + default:
1016 + break;
1017 + }
1018 +
1019 + return ptp_loc;
1020 +}
1021 +
1022 +static int dpa_ptp_store_stamp(const struct dpa_priv_s *priv,
1023 + struct sk_buff *skb, void *data, enum port_type rx_tx,
1024 + struct dpa_ptp_data *ptp_data)
1025 +{
1026 + u64 nsec;
1027 + u32 mod;
1028 + u8 *ptp_loc;
1029 + u16 eth_type;
1030 +
1031 + ptp_loc = dpa_ptp_parse_packet(skb, &eth_type);
1032 + if (!ptp_loc)
1033 + return -EINVAL;
1034 +
1035 + switch (eth_type) {
1036 + case ETH_P_IP:
1037 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV4;
1038 + break;
1039 + case ETH_P_IPV6:
1040 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV6;
1041 + break;
1042 + case ETH_P_1588:
1043 + ptp_data->ident.netw_prot = DPA_PTP_PROT_802_3;
1044 + break;
1045 + default:
1046 + return -EINVAL;
1047 + }
1048 +
1049 + if (!pskb_may_pull(skb, ptp_loc - skb->data + PTP_OFFS_SEQ_ID + 2))
1050 + return -EINVAL;
1051 +
1052 + ptp_data->ident.version = *(ptp_loc + PTP_OFFS_VER_PTP) & 0xf;
1053 + ptp_data->ident.msg_type = *(ptp_loc + PTP_OFFS_MSG_TYPE) & 0xf;
1054 + ptp_data->ident.seq_id = *((u16 *)(ptp_loc + PTP_OFFS_SEQ_ID));
1055 + memcpy(ptp_data->ident.snd_port_id, ptp_loc + PTP_OFFS_SRCPRTID,
1056 + DPA_PTP_SOURCE_PORT_LENGTH);
1057 +
1058 + nsec = dpa_get_timestamp_ns(priv, rx_tx, data);
1059 + mod = do_div(nsec, NANOSEC_PER_SECOND);
1060 + ptp_data->ts.sec = nsec;
1061 + ptp_data->ts.nsec = mod;
1062 +
1063 + return 0;
1064 +}
1065 +
1066 +void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1067 + struct sk_buff *skb, void *data)
1068 +{
1069 + struct dpa_ptp_tsu *tsu = priv->tsu;
1070 + struct dpa_ptp_data ptp_tx_data;
1071 +
1072 + if (dpa_ptp_store_stamp(priv, skb, data, TX, &ptp_tx_data))
1073 + return;
1074 +
1075 + dpa_ptp_insert(&tsu->tx_timestamps, &ptp_tx_data);
1076 +}
1077 +
1078 +void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1079 + struct sk_buff *skb, void *data)
1080 +{
1081 + struct dpa_ptp_tsu *tsu = priv->tsu;
1082 + struct dpa_ptp_data ptp_rx_data;
1083 +
1084 + if (dpa_ptp_store_stamp(priv, skb, data, RX, &ptp_rx_data))
1085 + return;
1086 +
1087 + dpa_ptp_insert(&tsu->rx_timestamps, &ptp_rx_data);
1088 +}
1089 +
1090 +static uint8_t dpa_get_tx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1091 + struct dpa_ptp_ident *ident,
1092 + struct dpa_ptp_time *ts)
1093 +{
1094 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1095 + struct dpa_ptp_time tmp;
1096 + int flag;
1097 +
1098 + flag = dpa_ptp_find_and_remove(&tsu->tx_timestamps, ident, &tmp);
1099 + if (!flag) {
1100 + ts->sec = tmp.sec;
1101 + ts->nsec = tmp.nsec;
1102 + return 0;
1103 + }
1104 +
1105 + return -1;
1106 +}
1107 +
1108 +static uint8_t dpa_get_rx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1109 + struct dpa_ptp_ident *ident,
1110 + struct dpa_ptp_time *ts)
1111 +{
1112 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1113 + struct dpa_ptp_time tmp;
1114 + int flag;
1115 +
1116 + flag = dpa_ptp_find_and_remove(&tsu->rx_timestamps, ident, &tmp);
1117 + if (!flag) {
1118 + ts->sec = tmp.sec;
1119 + ts->nsec = tmp.nsec;
1120 + return 0;
1121 + }
1122 +
1123 + return -1;
1124 +}
1125 +
1126 +static void dpa_set_fiper_alarm(struct dpa_ptp_tsu *tsu,
1127 + struct dpa_ptp_time *cnt_time)
1128 +{
1129 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1130 + u64 tmp, fiper;
1131 +
1132 + if (mac_dev->fm_rtc_disable)
1133 + mac_dev->fm_rtc_disable(get_fm_handle(tsu->dpa_priv->net_dev));
1134 +
1135 + /* TMR_FIPER1 will pulse every second after ALARM1 expired */
1136 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1137 + fiper = NANOSEC_PER_SECOND - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
1138 + if (mac_dev->fm_rtc_set_alarm)
1139 + mac_dev->fm_rtc_set_alarm(get_fm_handle(tsu->dpa_priv->net_dev),
1140 + 0, tmp);
1141 + if (mac_dev->fm_rtc_set_fiper)
1142 + mac_dev->fm_rtc_set_fiper(get_fm_handle(tsu->dpa_priv->net_dev),
1143 + 0, fiper);
1144 +
1145 + if (mac_dev->fm_rtc_enable)
1146 + mac_dev->fm_rtc_enable(get_fm_handle(tsu->dpa_priv->net_dev));
1147 +}
1148 +
1149 +static void dpa_get_curr_cnt(struct dpa_ptp_tsu *tsu,
1150 + struct dpa_ptp_time *curr_time)
1151 +{
1152 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1153 + u64 tmp;
1154 + u32 mod;
1155 +
1156 + if (mac_dev->fm_rtc_get_cnt)
1157 + mac_dev->fm_rtc_get_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1158 + &tmp);
1159 +
1160 + mod = do_div(tmp, NANOSEC_PER_SECOND);
1161 + curr_time->sec = (u32)tmp;
1162 + curr_time->nsec = mod;
1163 +}
1164 +
1165 +static void dpa_set_1588cnt(struct dpa_ptp_tsu *tsu,
1166 + struct dpa_ptp_time *cnt_time)
1167 +{
1168 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1169 + u64 tmp;
1170 +
1171 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1172 +
1173 + if (mac_dev->fm_rtc_set_cnt)
1174 + mac_dev->fm_rtc_set_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1175 + tmp);
1176 +
1177 + /* Restart fiper two seconds later */
1178 + cnt_time->sec += 2;
1179 + cnt_time->nsec = 0;
1180 + dpa_set_fiper_alarm(tsu, cnt_time);
1181 +}
1182 +
1183 +static void dpa_get_drift(struct dpa_ptp_tsu *tsu, u32 *addend)
1184 +{
1185 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1186 + u32 drift;
1187 +
1188 + if (mac_dev->fm_rtc_get_drift)
1189 + mac_dev->fm_rtc_get_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1190 + &drift);
1191 +
1192 + *addend = drift;
1193 +}
1194 +
1195 +static void dpa_set_drift(struct dpa_ptp_tsu *tsu, u32 addend)
1196 +{
1197 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1198 +
1199 + if (mac_dev->fm_rtc_set_drift)
1200 + mac_dev->fm_rtc_set_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1201 + addend);
1202 +}
1203 +
1204 +static void dpa_flush_timestamp(struct dpa_ptp_tsu *tsu)
1205 +{
1206 + dpa_ptp_reset_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1207 + dpa_ptp_reset_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1208 +}
1209 +
1210 +int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd)
1211 +{
1212 + struct dpa_priv_s *priv = netdev_priv(dev);
1213 + struct dpa_ptp_tsu *tsu = priv->tsu;
1214 + struct mac_device *mac_dev = priv->mac_dev;
1215 + struct dpa_ptp_data ptp_data;
1216 + struct dpa_ptp_data *ptp_data_user;
1217 + struct dpa_ptp_time act_time;
1218 + u32 addend;
1219 + int retval = 0;
1220 +
1221 + if (!tsu || !tsu->valid)
1222 + return -ENODEV;
1223 +
1224 + switch (cmd) {
1225 + case PTP_ENBL_TXTS_IOCTL:
1226 + tsu->hwts_tx_en_ioctl = 1;
1227 + if (mac_dev->fm_rtc_enable)
1228 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
1229 + if (mac_dev->ptp_enable)
1230 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
1231 + break;
1232 + case PTP_DSBL_TXTS_IOCTL:
1233 + tsu->hwts_tx_en_ioctl = 0;
1234 + if (mac_dev->fm_rtc_disable)
1235 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
1236 + if (mac_dev->ptp_disable)
1237 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
1238 + break;
1239 + case PTP_ENBL_RXTS_IOCTL:
1240 + tsu->hwts_rx_en_ioctl = 1;
1241 + break;
1242 + case PTP_DSBL_RXTS_IOCTL:
1243 + tsu->hwts_rx_en_ioctl = 0;
1244 + break;
1245 + case PTP_GET_RX_TIMESTAMP:
1246 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1247 + if (copy_from_user(&ptp_data.ident,
1248 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1249 + return -EINVAL;
1250 +
1251 + if (dpa_get_rx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1252 + return -EAGAIN;
1253 +
1254 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1255 + &ptp_data.ts, sizeof(ptp_data.ts)))
1256 + return -EFAULT;
1257 + break;
1258 + case PTP_GET_TX_TIMESTAMP:
1259 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1260 + if (copy_from_user(&ptp_data.ident,
1261 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1262 + return -EINVAL;
1263 +
1264 + if (dpa_get_tx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1265 + return -EAGAIN;
1266 +
1267 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1268 + &ptp_data.ts, sizeof(ptp_data.ts)))
1269 + return -EFAULT;
1270 + break;
1271 + case PTP_GET_TIME:
1272 + dpa_get_curr_cnt(tsu, &act_time);
1273 + if (copy_to_user(ifr->ifr_data, &act_time, sizeof(act_time)))
1274 + return -EFAULT;
1275 + break;
1276 + case PTP_SET_TIME:
1277 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1278 + return -EINVAL;
1279 + dpa_set_1588cnt(tsu, &act_time);
1280 + break;
1281 + case PTP_GET_ADJ:
1282 + dpa_get_drift(tsu, &addend);
1283 + if (copy_to_user(ifr->ifr_data, &addend, sizeof(addend)))
1284 + return -EFAULT;
1285 + break;
1286 + case PTP_SET_ADJ:
1287 + if (copy_from_user(&addend, ifr->ifr_data, sizeof(addend)))
1288 + return -EINVAL;
1289 + dpa_set_drift(tsu, addend);
1290 + break;
1291 + case PTP_SET_FIPER_ALARM:
1292 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1293 + return -EINVAL;
1294 + dpa_set_fiper_alarm(tsu, &act_time);
1295 + break;
1296 + case PTP_CLEANUP_TS:
1297 + dpa_flush_timestamp(tsu);
1298 + break;
1299 + default:
1300 + return -EINVAL;
1301 + }
1302 +
1303 + return retval;
1304 +}
1305 +
1306 +int dpa_ptp_init(struct dpa_priv_s *priv)
1307 +{
1308 + struct dpa_ptp_tsu *tsu;
1309 +
1310 + /* Allocate memory for PTP structure */
1311 + tsu = kzalloc(sizeof(struct dpa_ptp_tsu), GFP_KERNEL);
1312 + if (!tsu)
1313 + return -ENOMEM;
1314 +
1315 + tsu->valid = TRUE;
1316 + tsu->dpa_priv = priv;
1317 +
1318 + dpa_ptp_init_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1319 + dpa_ptp_init_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1320 +
1321 + priv->tsu = tsu;
1322 +
1323 + return 0;
1324 +}
1325 +EXPORT_SYMBOL(dpa_ptp_init);
1326 +
1327 +void dpa_ptp_cleanup(struct dpa_priv_s *priv)
1328 +{
1329 + struct dpa_ptp_tsu *tsu = priv->tsu;
1330 +
1331 + tsu->valid = FALSE;
1332 + vfree(tsu->rx_timestamps.circ_buf.buf);
1333 + vfree(tsu->tx_timestamps.circ_buf.buf);
1334 +
1335 + kfree(tsu);
1336 +}
1337 +EXPORT_SYMBOL(dpa_ptp_cleanup);
1338 --- /dev/null
1339 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
1340 @@ -0,0 +1,138 @@
1341 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
1342 + *
1343 + * This program is free software; you can redistribute it and/or modify
1344 + * it under the terms of the GNU General Public License as published by
1345 + * the Free Software Foundation; either version 2 of the License, or
1346 + * (at your option) any later version.
1347 + *
1348 + * This program is distributed in the hope that it will be useful,
1349 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1350 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1351 + * GNU General Public License for more details.
1352 + *
1353 + * You should have received a copy of the GNU General Public License along
1354 + * with this program; if not, write to the Free Software Foundation, Inc.,
1355 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1356 + *
1357 + */
1358 +#ifndef __DPAA_1588_H__
1359 +#define __DPAA_1588_H__
1360 +
1361 +#include <linux/netdevice.h>
1362 +#include <linux/etherdevice.h>
1363 +#include <linux/circ_buf.h>
1364 +#include <linux/fsl_qman.h>
1365 +
1366 +#define DEFAULT_PTP_RX_BUF_SZ 256
1367 +#define DEFAULT_PTP_TX_BUF_SZ 256
1368 +
1369 +/* 1588 private ioctl calls */
1370 +#define PTP_ENBL_TXTS_IOCTL SIOCDEVPRIVATE
1371 +#define PTP_DSBL_TXTS_IOCTL (SIOCDEVPRIVATE + 1)
1372 +#define PTP_ENBL_RXTS_IOCTL (SIOCDEVPRIVATE + 2)
1373 +#define PTP_DSBL_RXTS_IOCTL (SIOCDEVPRIVATE + 3)
1374 +#define PTP_GET_TX_TIMESTAMP (SIOCDEVPRIVATE + 4)
1375 +#define PTP_GET_RX_TIMESTAMP (SIOCDEVPRIVATE + 5)
1376 +#define PTP_SET_TIME (SIOCDEVPRIVATE + 6)
1377 +#define PTP_GET_TIME (SIOCDEVPRIVATE + 7)
1378 +#define PTP_SET_FIPER_ALARM (SIOCDEVPRIVATE + 8)
1379 +#define PTP_SET_ADJ (SIOCDEVPRIVATE + 9)
1380 +#define PTP_GET_ADJ (SIOCDEVPRIVATE + 10)
1381 +#define PTP_CLEANUP_TS (SIOCDEVPRIVATE + 11)
1382 +
1383 +/* PTP V2 message type */
1384 +enum {
1385 + PTP_MSGTYPE_SYNC = 0x0,
1386 + PTP_MSGTYPE_DELREQ = 0x1,
1387 + PTP_MSGTYPE_PDELREQ = 0x2,
1388 + PTP_MSGTYPE_PDELRESP = 0x3,
1389 + PTP_MSGTYPE_FLWUP = 0x8,
1390 + PTP_MSGTYPE_DELRESP = 0x9,
1391 + PTP_MSGTYPE_PDELRES_FLWUP = 0xA,
1392 + PTP_MSGTYPE_ANNOUNCE = 0xB,
1393 + PTP_MSGTYPE_SGNLNG = 0xC,
1394 + PTP_MSGTYPE_MNGMNT = 0xD,
1395 +};
1396 +
1397 +/* Byte offset of data in the PTP V2 headers */
1398 +#define PTP_OFFS_MSG_TYPE 0
1399 +#define PTP_OFFS_VER_PTP 1
1400 +#define PTP_OFFS_MSG_LEN 2
1401 +#define PTP_OFFS_DOM_NMB 4
1402 +#define PTP_OFFS_FLAGS 6
1403 +#define PTP_OFFS_CORFIELD 8
1404 +#define PTP_OFFS_SRCPRTID 20
1405 +#define PTP_OFFS_SEQ_ID 30
1406 +#define PTP_OFFS_CTRL 32
1407 +#define PTP_OFFS_LOGMEAN 33
1408 +
1409 +#define PTP_IP_OFFS 14
1410 +#define PTP_UDP_OFFS 34
1411 +#define PTP_HEADER_OFFS 42
1412 +#define PTP_MSG_TYPE_OFFS (PTP_HEADER_OFFS + PTP_OFFS_MSG_TYPE)
1413 +#define PTP_SPORT_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SRCPRTID)
1414 +#define PTP_SEQ_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SEQ_ID)
1415 +#define PTP_CTRL_OFFS (PTP_HEADER_OFFS + PTP_OFFS_CTRL)
1416 +
1417 +/* 1588-2008 network protocol enumeration values */
1418 +#define DPA_PTP_PROT_IPV4 1
1419 +#define DPA_PTP_PROT_IPV6 2
1420 +#define DPA_PTP_PROT_802_3 3
1421 +#define DPA_PTP_PROT_DONTCARE 0xFFFF
1422 +
1423 +#define DPA_PTP_SOURCE_PORT_LENGTH 10
1424 +#define DPA_PTP_HEADER_SZE 34
1425 +#define DPA_ETYPE_LEN 2
1426 +#define DPA_VLAN_TAG_LEN 4
1427 +#define NANOSEC_PER_SECOND 1000000000
1428 +
1429 +/* The threshold between the current found one and the oldest one */
1430 +#define TS_ACCUMULATION_THRESHOLD 50
1431 +
1432 +/* Struct needed to identify a timestamp */
1433 +struct dpa_ptp_ident {
1434 + u8 version;
1435 + u8 msg_type;
1436 + u16 netw_prot;
1437 + u16 seq_id;
1438 + u8 snd_port_id[DPA_PTP_SOURCE_PORT_LENGTH];
1439 +};
1440 +
1441 +/* Timestamp format in 1588-2008 */
1442 +struct dpa_ptp_time {
1443 + u64 sec; /* just 48 bit used */
1444 + u32 nsec;
1445 +};
1446 +
1447 +/* needed for timestamp data over ioctl */
1448 +struct dpa_ptp_data {
1449 + struct dpa_ptp_ident ident;
1450 + struct dpa_ptp_time ts;
1451 +};
1452 +
1453 +struct dpa_ptp_circ_buf {
1454 + struct circ_buf circ_buf;
1455 + u32 size;
1456 + spinlock_t ptp_lock;
1457 +};
1458 +
1459 +/* PTP TSU control structure */
1460 +struct dpa_ptp_tsu {
1461 + struct dpa_priv_s *dpa_priv;
1462 + bool valid;
1463 + struct dpa_ptp_circ_buf rx_timestamps;
1464 + struct dpa_ptp_circ_buf tx_timestamps;
1465 +
1466 + /* HW timestamping over ioctl enabled flag */
1467 + int hwts_tx_en_ioctl;
1468 + int hwts_rx_en_ioctl;
1469 +};
1470 +
1471 +extern int dpa_ptp_init(struct dpa_priv_s *priv);
1472 +extern void dpa_ptp_cleanup(struct dpa_priv_s *priv);
1473 +extern void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1474 + struct sk_buff *skb, void *data);
1475 +extern void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1476 + struct sk_buff *skb, void *data);
1477 +extern int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd);
1478 +#endif
1479 --- /dev/null
1480 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
1481 @@ -0,0 +1,180 @@
1482 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1483 + *
1484 + * Redistribution and use in source and binary forms, with or without
1485 + * modification, are permitted provided that the following conditions are met:
1486 + * * Redistributions of source code must retain the above copyright
1487 + * notice, this list of conditions and the following disclaimer.
1488 + * * Redistributions in binary form must reproduce the above copyright
1489 + * notice, this list of conditions and the following disclaimer in the
1490 + * documentation and/or other materials provided with the distribution.
1491 + * * Neither the name of Freescale Semiconductor nor the
1492 + * names of its contributors may be used to endorse or promote products
1493 + * derived from this software without specific prior written permission.
1494 + *
1495 + *
1496 + * ALTERNATIVELY, this software may be distributed under the terms of the
1497 + * GNU General Public License ("GPL") as published by the Free Software
1498 + * Foundation, either version 2 of that License or (at your option) any
1499 + * later version.
1500 + *
1501 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1502 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1503 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1504 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1505 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1506 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1507 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1508 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1509 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1510 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1511 + */
1512 +
1513 +#include <linux/module.h>
1514 +#include <linux/fsl_qman.h> /* struct qm_mcr_querycgr */
1515 +#include <linux/debugfs.h>
1516 +#include "dpaa_debugfs.h"
1517 +#include "dpaa_eth.h" /* struct dpa_priv_s, dpa_percpu_priv_s, dpa_bp */
1518 +
1519 +#define DPA_DEBUGFS_DESCRIPTION "FSL DPAA Ethernet debugfs entries"
1520 +#define DPA_ETH_DEBUGFS_ROOT "fsl_dpa"
1521 +
1522 +static struct dentry *dpa_debugfs_root;
1523 +
1524 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file);
1525 +static ssize_t dpa_loop_write(struct file *f,
1526 + const char __user *buf, size_t count, loff_t *off);
1527 +
1528 +static const struct file_operations dpa_debugfs_lp_fops = {
1529 + .open = dpa_debugfs_loop_open,
1530 + .write = dpa_loop_write,
1531 + .read = seq_read,
1532 + .llseek = seq_lseek,
1533 + .release = single_release,
1534 +};
1535 +
1536 +static int dpa_debugfs_loop_show(struct seq_file *file, void *offset)
1537 +{
1538 + struct dpa_priv_s *priv;
1539 +
1540 + BUG_ON(offset == NULL);
1541 +
1542 + priv = netdev_priv((struct net_device *)file->private);
1543 + seq_printf(file, "%d->%d\n", priv->loop_id, priv->loop_to);
1544 +
1545 + return 0;
1546 +}
1547 +
1548 +static int user_input_convert(const char __user *user_buf, size_t count,
1549 + long *val)
1550 +{
1551 + char buf[12];
1552 +
1553 + if (count > sizeof(buf) - 1)
1554 + return -EINVAL;
1555 + if (copy_from_user(buf, user_buf, count))
1556 + return -EFAULT;
1557 + buf[count] = '\0';
1558 + if (kstrtol(buf, 0, val))
1559 + return -EINVAL;
1560 + return 0;
1561 +}
1562 +
1563 +static ssize_t dpa_loop_write(struct file *f,
1564 + const char __user *buf, size_t count, loff_t *off)
1565 +{
1566 + struct dpa_priv_s *priv;
1567 + struct net_device *netdev;
1568 + struct seq_file *sf;
1569 + int ret;
1570 + long val;
1571 +
1572 + ret = user_input_convert(buf, count, &val);
1573 + if (ret)
1574 + return ret;
1575 +
1576 + sf = (struct seq_file *)f->private_data;
1577 + netdev = (struct net_device *)sf->private;
1578 + priv = netdev_priv(netdev);
1579 +
1580 + priv->loop_to = ((val < 0) || (val > 20)) ? -1 : val;
1581 +
1582 + return count;
1583 +}
1584 +
1585 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file)
1586 +{
1587 + int _errno;
1588 + const struct net_device *net_dev;
1589 +
1590 + _errno = single_open(file, dpa_debugfs_loop_show, inode->i_private);
1591 + if (unlikely(_errno < 0)) {
1592 + net_dev = (struct net_device *)inode->i_private;
1593 +
1594 + if (netif_msg_drv((struct dpa_priv_s *)netdev_priv(net_dev)))
1595 + netdev_err(net_dev, "single_open() = %d\n",
1596 + _errno);
1597 + }
1598 +
1599 + return _errno;
1600 +}
1601 +
1602 +
1603 +int dpa_netdev_debugfs_create(struct net_device *net_dev)
1604 +{
1605 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1606 + static int cnt;
1607 + char loop_file_name[100];
1608 +
1609 + if (unlikely(dpa_debugfs_root == NULL)) {
1610 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): \t%s\n",
1611 + KBUILD_BASENAME".c", __LINE__, __func__,
1612 + "root debugfs missing, possible module ordering issue");
1613 + return -ENOMEM;
1614 + }
1615 +
1616 + sprintf(loop_file_name, "eth%d_loop", ++cnt);
1617 + priv->debugfs_loop_file = debugfs_create_file(loop_file_name,
1618 + S_IRUGO,
1619 + dpa_debugfs_root,
1620 + net_dev,
1621 + &dpa_debugfs_lp_fops);
1622 + if (unlikely(priv->debugfs_loop_file == NULL)) {
1623 + netdev_err(net_dev, "debugfs_create_file(%s/%s)",
1624 + dpa_debugfs_root->d_iname,
1625 + loop_file_name);
1626 +
1627 + return -ENOMEM;
1628 + }
1629 + return 0;
1630 +}
1631 +
1632 +void dpa_netdev_debugfs_remove(struct net_device *net_dev)
1633 +{
1634 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1635 +
1636 + debugfs_remove(priv->debugfs_loop_file);
1637 +}
1638 +
1639 +int __init dpa_debugfs_module_init(void)
1640 +{
1641 + int _errno = 0;
1642 +
1643 + pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION "\n");
1644 +
1645 + dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT, NULL);
1646 +
1647 + if (unlikely(dpa_debugfs_root == NULL)) {
1648 + _errno = -ENOMEM;
1649 + pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
1650 + KBUILD_BASENAME".c", __LINE__, __func__);
1651 + pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
1652 + DPA_ETH_DEBUGFS_ROOT, _errno);
1653 + }
1654 +
1655 + return _errno;
1656 +}
1657 +
1658 +void __exit dpa_debugfs_module_exit(void)
1659 +{
1660 + debugfs_remove(dpa_debugfs_root);
1661 +}
1662 --- /dev/null
1663 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
1664 @@ -0,0 +1,43 @@
1665 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1666 + *
1667 + * Redistribution and use in source and binary forms, with or without
1668 + * modification, are permitted provided that the following conditions are met:
1669 + * * Redistributions of source code must retain the above copyright
1670 + * notice, this list of conditions and the following disclaimer.
1671 + * * Redistributions in binary form must reproduce the above copyright
1672 + * notice, this list of conditions and the following disclaimer in the
1673 + * documentation and/or other materials provided with the distribution.
1674 + * * Neither the name of Freescale Semiconductor nor the
1675 + * names of its contributors may be used to endorse or promote products
1676 + * derived from this software without specific prior written permission.
1677 + *
1678 + *
1679 + * ALTERNATIVELY, this software may be distributed under the terms of the
1680 + * GNU General Public License ("GPL") as published by the Free Software
1681 + * Foundation, either version 2 of that License or (at your option) any
1682 + * later version.
1683 + *
1684 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1685 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1686 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1687 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1688 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1689 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1690 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1691 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1692 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1693 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1694 + */
1695 +
1696 +#ifndef DPAA_DEBUGFS_H_
1697 +#define DPAA_DEBUGFS_H_
1698 +
1699 +#include <linux/netdevice.h>
1700 +#include <linux/dcache.h> /* struct dentry needed in dpaa_eth.h */
1701 +
1702 +int dpa_netdev_debugfs_create(struct net_device *net_dev);
1703 +void dpa_netdev_debugfs_remove(struct net_device *net_dev);
1704 +int __init dpa_debugfs_module_init(void);
1705 +void __exit dpa_debugfs_module_exit(void);
1706 +
1707 +#endif /* DPAA_DEBUGFS_H_ */
1708 --- /dev/null
1709 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
1710 @@ -0,0 +1,1213 @@
1711 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1712 + *
1713 + * Redistribution and use in source and binary forms, with or without
1714 + * modification, are permitted provided that the following conditions are met:
1715 + * * Redistributions of source code must retain the above copyright
1716 + * notice, this list of conditions and the following disclaimer.
1717 + * * Redistributions in binary form must reproduce the above copyright
1718 + * notice, this list of conditions and the following disclaimer in the
1719 + * documentation and/or other materials provided with the distribution.
1720 + * * Neither the name of Freescale Semiconductor nor the
1721 + * names of its contributors may be used to endorse or promote products
1722 + * derived from this software without specific prior written permission.
1723 + *
1724 + *
1725 + * ALTERNATIVELY, this software may be distributed under the terms of the
1726 + * GNU General Public License ("GPL") as published by the Free Software
1727 + * Foundation, either version 2 of that License or (at your option) any
1728 + * later version.
1729 + *
1730 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1731 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1732 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1733 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1734 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1735 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1736 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1737 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1738 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1739 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1740 + */
1741 +
1742 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
1743 +#define pr_fmt(fmt) \
1744 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
1745 + KBUILD_BASENAME".c", __LINE__, __func__
1746 +#else
1747 +#define pr_fmt(fmt) \
1748 + KBUILD_MODNAME ": " fmt
1749 +#endif
1750 +
1751 +#include <linux/init.h>
1752 +#include <linux/module.h>
1753 +#include <linux/of_mdio.h>
1754 +#include <linux/of_net.h>
1755 +#include <linux/kthread.h>
1756 +#include <linux/io.h>
1757 +#include <linux/if_arp.h> /* arp_hdr_len() */
1758 +#include <linux/if_vlan.h> /* VLAN_HLEN */
1759 +#include <linux/icmp.h> /* struct icmphdr */
1760 +#include <linux/ip.h> /* struct iphdr */
1761 +#include <linux/ipv6.h> /* struct ipv6hdr */
1762 +#include <linux/udp.h> /* struct udphdr */
1763 +#include <linux/tcp.h> /* struct tcphdr */
1764 +#include <linux/net.h> /* net_ratelimit() */
1765 +#include <linux/if_ether.h> /* ETH_P_IP and ETH_P_IPV6 */
1766 +#include <linux/highmem.h>
1767 +#include <linux/percpu.h>
1768 +#include <linux/dma-mapping.h>
1769 +#include <linux/fsl_bman.h>
1770 +#ifdef CONFIG_SOC_BUS
1771 +#include <linux/sys_soc.h> /* soc_device_match */
1772 +#endif
1773 +
1774 +#include "fsl_fman.h"
1775 +#include "fm_ext.h"
1776 +#include "fm_port_ext.h"
1777 +
1778 +#include "mac.h"
1779 +#include "dpaa_eth.h"
1780 +#include "dpaa_eth_common.h"
1781 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1782 +#include "dpaa_debugfs.h"
1783 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
1784 +
1785 +/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files
1786 + * using trace events only need to #include <trace/events/sched.h>
1787 + */
1788 +#define CREATE_TRACE_POINTS
1789 +#include "dpaa_eth_trace.h"
1790 +
1791 +#define DPA_NAPI_WEIGHT 64
1792 +
1793 +/* Valid checksum indication */
1794 +#define DPA_CSUM_VALID 0xFFFF
1795 +
1796 +#define DPA_DESCRIPTION "FSL DPAA Ethernet driver"
1797 +
1798 +MODULE_LICENSE("Dual BSD/GPL");
1799 +
1800 +MODULE_AUTHOR("Andy Fleming <afleming@freescale.com>");
1801 +
1802 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
1803 +
1804 +static uint8_t debug = -1;
1805 +module_param(debug, byte, S_IRUGO);
1806 +MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
1807 +
1808 +/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
1809 +static uint16_t tx_timeout = 1000;
1810 +module_param(tx_timeout, ushort, S_IRUGO);
1811 +MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
1812 +
1813 +static const char rtx[][3] = {
1814 + [RX] = "RX",
1815 + [TX] = "TX"
1816 +};
1817 +
1818 +#ifndef CONFIG_PPC
1819 +bool dpaa_errata_a010022;
1820 +EXPORT_SYMBOL(dpaa_errata_a010022);
1821 +#endif
1822 +
1823 +/* BM */
1824 +
1825 +#define DPAA_ETH_MAX_PAD (L1_CACHE_BYTES * 8)
1826 +
1827 +static uint8_t dpa_priv_common_bpid;
1828 +
1829 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1830 +struct net_device *dpa_loop_netdevs[20];
1831 +#endif
1832 +
1833 +#ifdef CONFIG_PM
1834 +
1835 +static int dpaa_suspend(struct device *dev)
1836 +{
1837 + struct net_device *net_dev;
1838 + struct dpa_priv_s *priv;
1839 + struct mac_device *mac_dev;
1840 + int err = 0;
1841 +
1842 + net_dev = dev_get_drvdata(dev);
1843 +
1844 + if (net_dev->flags & IFF_UP) {
1845 + priv = netdev_priv(net_dev);
1846 + mac_dev = priv->mac_dev;
1847 +
1848 + if (priv->wol & DPAA_WOL_MAGIC) {
1849 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1850 + priv->mac_dev->get_mac_handle(mac_dev), true);
1851 + if (err) {
1852 + netdev_err(net_dev, "set_wol() = %d\n", err);
1853 + goto set_wol_failed;
1854 + }
1855 + }
1856 +
1857 + err = fm_port_suspend(mac_dev->port_dev[RX]);
1858 + if (err) {
1859 + netdev_err(net_dev, "fm_port_suspend(RX) = %d\n", err);
1860 + goto rx_port_suspend_failed;
1861 + }
1862 +
1863 + err = fm_port_suspend(mac_dev->port_dev[TX]);
1864 + if (err) {
1865 + netdev_err(net_dev, "fm_port_suspend(TX) = %d\n", err);
1866 + goto tx_port_suspend_failed;
1867 + }
1868 + }
1869 +
1870 + return 0;
1871 +
1872 +tx_port_suspend_failed:
1873 + fm_port_resume(mac_dev->port_dev[RX]);
1874 +rx_port_suspend_failed:
1875 + if (priv->wol & DPAA_WOL_MAGIC) {
1876 + priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1877 + priv->mac_dev->get_mac_handle(mac_dev), false);
1878 + }
1879 +set_wol_failed:
1880 + return err;
1881 +}
1882 +
1883 +static int dpaa_resume(struct device *dev)
1884 +{
1885 + struct net_device *net_dev;
1886 + struct dpa_priv_s *priv;
1887 + struct mac_device *mac_dev;
1888 + int err = 0;
1889 +
1890 + net_dev = dev_get_drvdata(dev);
1891 +
1892 + if (net_dev->flags & IFF_UP) {
1893 + priv = netdev_priv(net_dev);
1894 + mac_dev = priv->mac_dev;
1895 +
1896 + err = fm_mac_resume(mac_dev->get_mac_handle(mac_dev));
1897 + if (err) {
1898 + netdev_err(net_dev, "fm_mac_resume = %d\n", err);
1899 + goto resume_failed;
1900 + }
1901 +
1902 + err = fm_port_resume(mac_dev->port_dev[TX]);
1903 + if (err) {
1904 + netdev_err(net_dev, "fm_port_resume(TX) = %d\n", err);
1905 + goto resume_failed;
1906 + }
1907 +
1908 + err = fm_port_resume(mac_dev->port_dev[RX]);
1909 + if (err) {
1910 + netdev_err(net_dev, "fm_port_resume(RX) = %d\n", err);
1911 + goto resume_failed;
1912 + }
1913 +
1914 + if (priv->wol & DPAA_WOL_MAGIC) {
1915 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1916 + priv->mac_dev->get_mac_handle(mac_dev), false);
1917 + if (err) {
1918 + netdev_err(net_dev, "set_wol() = %d\n", err);
1919 + goto resume_failed;
1920 + }
1921 + }
1922 + }
1923 +
1924 + return 0;
1925 +
1926 +resume_failed:
1927 + return err;
1928 +}
1929 +
1930 +static const struct dev_pm_ops dpaa_pm_ops = {
1931 + .suspend = dpaa_suspend,
1932 + .resume = dpaa_resume,
1933 +};
1934 +
1935 +#define DPAA_PM_OPS (&dpaa_pm_ops)
1936 +
1937 +#else /* CONFIG_PM */
1938 +
1939 +#define DPAA_PM_OPS NULL
1940 +
1941 +#endif /* CONFIG_PM */
1942 +
1943 +/* Checks whether the checksum field in Parse Results array is valid
1944 + * (equals 0xFFFF) and increments the .cse counter otherwise
1945 + */
1946 +static inline void
1947 +dpa_csum_validation(const struct dpa_priv_s *priv,
1948 + struct dpa_percpu_priv_s *percpu_priv,
1949 + const struct qm_fd *fd)
1950 +{
1951 + dma_addr_t addr = qm_fd_addr(fd);
1952 + struct dpa_bp *dpa_bp = priv->dpa_bp;
1953 + void *frm = phys_to_virt(addr);
1954 + fm_prs_result_t *parse_result;
1955 +
1956 + if (unlikely(!frm))
1957 + return;
1958 +
1959 + dma_sync_single_for_cpu(dpa_bp->dev, addr, DPA_RX_PRIV_DATA_SIZE +
1960 + DPA_PARSE_RESULTS_SIZE, DMA_BIDIRECTIONAL);
1961 +
1962 + parse_result = (fm_prs_result_t *)(frm + DPA_RX_PRIV_DATA_SIZE);
1963 +
1964 + if (parse_result->cksum != DPA_CSUM_VALID)
1965 + percpu_priv->rx_errors.cse++;
1966 +}
1967 +
1968 +static void _dpa_rx_error(struct net_device *net_dev,
1969 + const struct dpa_priv_s *priv,
1970 + struct dpa_percpu_priv_s *percpu_priv,
1971 + const struct qm_fd *fd,
1972 + u32 fqid)
1973 +{
1974 + /* limit common, possibly innocuous Rx FIFO Overflow errors'
1975 + * interference with zero-loss convergence benchmark results.
1976 + */
1977 + if (likely(fd->status & FM_FD_STAT_ERR_PHYSICAL))
1978 + pr_warn_once("fsl-dpa: non-zero error counters in fman statistics (sysfs)\n");
1979 + else
1980 + if (netif_msg_hw(priv) && net_ratelimit())
1981 + netdev_dbg(net_dev, "Err FD status = 0x%08x\n",
1982 + fd->status & FM_FD_STAT_RX_ERRORS);
1983 +#ifdef CONFIG_FSL_DPAA_HOOKS
1984 + if (dpaa_eth_hooks.rx_error &&
1985 + dpaa_eth_hooks.rx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
1986 + /* it's up to the hook to perform resource cleanup */
1987 + return;
1988 +#endif
1989 + percpu_priv->stats.rx_errors++;
1990 +
1991 + if (fd->status & FM_PORT_FRM_ERR_DMA)
1992 + percpu_priv->rx_errors.dme++;
1993 + if (fd->status & FM_PORT_FRM_ERR_PHYSICAL)
1994 + percpu_priv->rx_errors.fpe++;
1995 + if (fd->status & FM_PORT_FRM_ERR_SIZE)
1996 + percpu_priv->rx_errors.fse++;
1997 + if (fd->status & FM_PORT_FRM_ERR_PRS_HDR_ERR)
1998 + percpu_priv->rx_errors.phe++;
1999 + if (fd->status & FM_FD_STAT_L4CV)
2000 + dpa_csum_validation(priv, percpu_priv, fd);
2001 +
2002 + dpa_fd_release(net_dev, fd);
2003 +}
2004 +
2005 +static void _dpa_tx_error(struct net_device *net_dev,
2006 + const struct dpa_priv_s *priv,
2007 + struct dpa_percpu_priv_s *percpu_priv,
2008 + const struct qm_fd *fd,
2009 + u32 fqid)
2010 +{
2011 + struct sk_buff *skb;
2012 +
2013 + if (netif_msg_hw(priv) && net_ratelimit())
2014 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2015 + fd->status & FM_FD_STAT_TX_ERRORS);
2016 +#ifdef CONFIG_FSL_DPAA_HOOKS
2017 + if (dpaa_eth_hooks.tx_error &&
2018 + dpaa_eth_hooks.tx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
2019 + /* now the hook must ensure proper cleanup */
2020 + return;
2021 +#endif
2022 + percpu_priv->stats.tx_errors++;
2023 +
2024 + /* If we intended the buffers from this frame to go into the bpools
2025 + * when the FMan transmit was done, we need to put it in manually.
2026 + */
2027 + if (fd->bpid != 0xff) {
2028 + dpa_fd_release(net_dev, fd);
2029 + return;
2030 + }
2031 +
2032 + skb = _dpa_cleanup_tx_fd(priv, fd);
2033 + dev_kfree_skb(skb);
2034 +}
2035 +
2036 +/* Helper function to factor out frame validation logic on all Rx paths. Its
2037 + * purpose is to extract from the Parse Results structure information about
2038 + * the integrity of the frame, its checksum, the length of the parsed headers
2039 + * and whether the frame is suitable for GRO.
2040 + *
2041 + * Assumes no parser errors, since any error frame is dropped before this
2042 + * function is called.
2043 + *
2044 + * @skb will have its ip_summed field overwritten;
2045 + * @use_gro will only be written with 0, if the frame is definitely not
2046 + * GRO-able; otherwise, it will be left unchanged;
2047 + * @hdr_size will be written with a safe value, at least the size of the
2048 + * headers' length.
2049 + */
2050 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
2051 + const struct qm_fd *fd,
2052 + struct sk_buff *skb, int *use_gro)
2053 +{
2054 + if (fd->status & FM_FD_STAT_L4CV) {
2055 + /* The parser has run and performed L4 checksum validation.
2056 + * We know there were no parser errors (and implicitly no
2057 + * L4 csum error), otherwise we wouldn't be here.
2058 + */
2059 + skb->ip_summed = CHECKSUM_UNNECESSARY;
2060 +
2061 + /* Don't go through GRO for certain types of traffic that
2062 + * we know are not GRO-able, such as dgram-based protocols.
2063 + * In the worst-case scenarios, such as small-pkt terminating
2064 + * UDP, the extra GRO processing would be overkill.
2065 + *
2066 + * The only protocol the Parser supports that is also GRO-able
2067 + * is currently TCP.
2068 + */
2069 + if (!fm_l4_frame_is_tcp(parse_results))
2070 + *use_gro = 0;
2071 +
2072 + return;
2073 + }
2074 +
2075 + /* We're here because either the parser didn't run or the L4 checksum
2076 + * was not verified. This may include the case of a UDP frame with
2077 + * checksum zero or an L4 proto other than TCP/UDP
2078 + */
2079 + skb->ip_summed = CHECKSUM_NONE;
2080 +
2081 + /* Bypass GRO for unknown traffic or if no PCDs are applied */
2082 + *use_gro = 0;
2083 +}
2084 +
2085 +int dpaa_eth_poll(struct napi_struct *napi, int budget)
2086 +{
2087 + struct dpa_napi_portal *np =
2088 + container_of(napi, struct dpa_napi_portal, napi);
2089 +
2090 + int cleaned = qman_p_poll_dqrr(np->p, budget);
2091 +
2092 + if (cleaned < budget) {
2093 + int tmp;
2094 + napi_complete(napi);
2095 + tmp = qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2096 + DPA_BUG_ON(tmp);
2097 + }
2098 +
2099 + return cleaned;
2100 +}
2101 +EXPORT_SYMBOL(dpaa_eth_poll);
2102 +
2103 +static void __hot _dpa_tx_conf(struct net_device *net_dev,
2104 + const struct dpa_priv_s *priv,
2105 + struct dpa_percpu_priv_s *percpu_priv,
2106 + const struct qm_fd *fd,
2107 + u32 fqid)
2108 +{
2109 + struct sk_buff *skb;
2110 +
2111 + /* do we need the timestamp for the error frames? */
2112 +
2113 + if (unlikely(fd->status & FM_FD_STAT_TX_ERRORS) != 0) {
2114 + if (netif_msg_hw(priv) && net_ratelimit())
2115 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2116 + fd->status & FM_FD_STAT_TX_ERRORS);
2117 +
2118 + percpu_priv->stats.tx_errors++;
2119 + }
2120 +
2121 + /* hopefully we need not get the timestamp before the hook */
2122 +#ifdef CONFIG_FSL_DPAA_HOOKS
2123 + if (dpaa_eth_hooks.tx_confirm && dpaa_eth_hooks.tx_confirm(net_dev,
2124 + fd, fqid) == DPAA_ETH_STOLEN)
2125 + /* it's the hook that must now perform cleanup */
2126 + return;
2127 +#endif
2128 + /* This might not perfectly reflect the reality, if the core dequeuing
2129 + * the Tx confirmation is different from the one that did the enqueue,
2130 + * but at least it'll show up in the total count.
2131 + */
2132 + percpu_priv->tx_confirm++;
2133 +
2134 + skb = _dpa_cleanup_tx_fd(priv, fd);
2135 +
2136 + dev_kfree_skb(skb);
2137 +}
2138 +
2139 +enum qman_cb_dqrr_result
2140 +priv_rx_error_dqrr(struct qman_portal *portal,
2141 + struct qman_fq *fq,
2142 + const struct qm_dqrr_entry *dq)
2143 +{
2144 + struct net_device *net_dev;
2145 + struct dpa_priv_s *priv;
2146 + struct dpa_percpu_priv_s *percpu_priv;
2147 + int *count_ptr;
2148 +
2149 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2150 + priv = netdev_priv(net_dev);
2151 +
2152 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2153 + count_ptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
2154 +
2155 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2156 + return qman_cb_dqrr_stop;
2157 +
2158 + if (unlikely(dpaa_eth_refill_bpools(priv->dpa_bp, count_ptr)))
2159 + /* Unable to refill the buffer pool due to insufficient
2160 + * system memory. Just release the frame back into the pool,
2161 + * otherwise we'll soon end up with an empty buffer pool.
2162 + */
2163 + dpa_fd_release(net_dev, &dq->fd);
2164 + else
2165 + _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2166 +
2167 + return qman_cb_dqrr_consume;
2168 +}
2169 +
2170 +
2171 +enum qman_cb_dqrr_result __hot
2172 +priv_rx_default_dqrr(struct qman_portal *portal,
2173 + struct qman_fq *fq,
2174 + const struct qm_dqrr_entry *dq)
2175 +{
2176 + struct net_device *net_dev;
2177 + struct dpa_priv_s *priv;
2178 + struct dpa_percpu_priv_s *percpu_priv;
2179 + int *count_ptr;
2180 + struct dpa_bp *dpa_bp;
2181 +
2182 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2183 + priv = netdev_priv(net_dev);
2184 + dpa_bp = priv->dpa_bp;
2185 +
2186 + /* Trace the Rx fd */
2187 + trace_dpa_rx_fd(net_dev, fq, &dq->fd);
2188 +
2189 + /* IRQ handler, non-migratable; safe to use raw_cpu_ptr here */
2190 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2191 + count_ptr = raw_cpu_ptr(dpa_bp->percpu_count);
2192 +
2193 + if (unlikely(dpaa_eth_napi_schedule(percpu_priv, portal)))
2194 + return qman_cb_dqrr_stop;
2195 +
2196 + /* Vale of plenty: make sure we didn't run out of buffers */
2197 +
2198 + if (unlikely(dpaa_eth_refill_bpools(dpa_bp, count_ptr)))
2199 + /* Unable to refill the buffer pool due to insufficient
2200 + * system memory. Just release the frame back into the pool,
2201 + * otherwise we'll soon end up with an empty buffer pool.
2202 + */
2203 + dpa_fd_release(net_dev, &dq->fd);
2204 + else
2205 + _dpa_rx(net_dev, portal, priv, percpu_priv, &dq->fd, fq->fqid,
2206 + count_ptr);
2207 +
2208 + return qman_cb_dqrr_consume;
2209 +}
2210 +
2211 +enum qman_cb_dqrr_result
2212 +priv_tx_conf_error_dqrr(struct qman_portal *portal,
2213 + struct qman_fq *fq,
2214 + const struct qm_dqrr_entry *dq)
2215 +{
2216 + struct net_device *net_dev;
2217 + struct dpa_priv_s *priv;
2218 + struct dpa_percpu_priv_s *percpu_priv;
2219 +
2220 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2221 + priv = netdev_priv(net_dev);
2222 +
2223 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2224 +
2225 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2226 + return qman_cb_dqrr_stop;
2227 +
2228 + _dpa_tx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2229 +
2230 + return qman_cb_dqrr_consume;
2231 +}
2232 +
2233 +enum qman_cb_dqrr_result __hot
2234 +priv_tx_conf_default_dqrr(struct qman_portal *portal,
2235 + struct qman_fq *fq,
2236 + const struct qm_dqrr_entry *dq)
2237 +{
2238 + struct net_device *net_dev;
2239 + struct dpa_priv_s *priv;
2240 + struct dpa_percpu_priv_s *percpu_priv;
2241 +
2242 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2243 + priv = netdev_priv(net_dev);
2244 +
2245 + /* Trace the fd */
2246 + trace_dpa_tx_conf_fd(net_dev, fq, &dq->fd);
2247 +
2248 + /* Non-migratable context, safe to use raw_cpu_ptr */
2249 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2250 +
2251 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2252 + return qman_cb_dqrr_stop;
2253 +
2254 + _dpa_tx_conf(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2255 +
2256 + return qman_cb_dqrr_consume;
2257 +}
2258 +
2259 +void priv_ern(struct qman_portal *portal,
2260 + struct qman_fq *fq,
2261 + const struct qm_mr_entry *msg)
2262 +{
2263 + struct net_device *net_dev;
2264 + const struct dpa_priv_s *priv;
2265 + struct sk_buff *skb;
2266 + struct dpa_percpu_priv_s *percpu_priv;
2267 + struct qm_fd fd = msg->ern.fd;
2268 +
2269 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2270 + priv = netdev_priv(net_dev);
2271 + /* Non-migratable context, safe to use raw_cpu_ptr */
2272 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2273 +
2274 + percpu_priv->stats.tx_dropped++;
2275 + percpu_priv->stats.tx_fifo_errors++;
2276 + count_ern(percpu_priv, msg);
2277 +
2278 + /* If we intended this buffer to go into the pool
2279 + * when the FM was done, we need to put it in
2280 + * manually.
2281 + */
2282 + if (msg->ern.fd.bpid != 0xff) {
2283 + dpa_fd_release(net_dev, &fd);
2284 + return;
2285 + }
2286 +
2287 + skb = _dpa_cleanup_tx_fd(priv, &fd);
2288 + dev_kfree_skb_any(skb);
2289 +}
2290 +
2291 +const struct dpa_fq_cbs_t private_fq_cbs = {
2292 + .rx_defq = { .cb = { .dqrr = priv_rx_default_dqrr } },
2293 + .tx_defq = { .cb = { .dqrr = priv_tx_conf_default_dqrr } },
2294 + .rx_errq = { .cb = { .dqrr = priv_rx_error_dqrr } },
2295 + .tx_errq = { .cb = { .dqrr = priv_tx_conf_error_dqrr } },
2296 + .egress_ern = { .cb = { .ern = priv_ern } }
2297 +};
2298 +EXPORT_SYMBOL(private_fq_cbs);
2299 +
2300 +static void dpaa_eth_napi_enable(struct dpa_priv_s *priv)
2301 +{
2302 + struct dpa_percpu_priv_s *percpu_priv;
2303 + int i, j;
2304 +
2305 + for_each_possible_cpu(i) {
2306 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2307 +
2308 + for (j = 0; j < qman_portal_max; j++)
2309 + napi_enable(&percpu_priv->np[j].napi);
2310 + }
2311 +}
2312 +
2313 +static void dpaa_eth_napi_disable(struct dpa_priv_s *priv)
2314 +{
2315 + struct dpa_percpu_priv_s *percpu_priv;
2316 + int i, j;
2317 +
2318 + for_each_possible_cpu(i) {
2319 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2320 +
2321 + for (j = 0; j < qman_portal_max; j++)
2322 + napi_disable(&percpu_priv->np[j].napi);
2323 + }
2324 +}
2325 +
2326 +static int __cold dpa_eth_priv_start(struct net_device *net_dev)
2327 +{
2328 + int err;
2329 + struct dpa_priv_s *priv;
2330 +
2331 + priv = netdev_priv(net_dev);
2332 +
2333 + dpaa_eth_napi_enable(priv);
2334 +
2335 + err = dpa_start(net_dev);
2336 + if (err < 0)
2337 + dpaa_eth_napi_disable(priv);
2338 +
2339 + return err;
2340 +}
2341 +
2342 +
2343 +
2344 +static int __cold dpa_eth_priv_stop(struct net_device *net_dev)
2345 +{
2346 + int _errno;
2347 + struct dpa_priv_s *priv;
2348 +
2349 + _errno = dpa_stop(net_dev);
2350 + /* Allow NAPI to consume any frame still in the Rx/TxConfirm
2351 + * ingress queues. This is to avoid a race between the current
2352 + * context and ksoftirqd which could leave NAPI disabled while
2353 + * in fact there's still Rx traffic to be processed.
2354 + */
2355 + usleep_range(5000, 10000);
2356 +
2357 + priv = netdev_priv(net_dev);
2358 + dpaa_eth_napi_disable(priv);
2359 +
2360 + return _errno;
2361 +}
2362 +
2363 +#ifdef CONFIG_NET_POLL_CONTROLLER
2364 +static void dpaa_eth_poll_controller(struct net_device *net_dev)
2365 +{
2366 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2367 + struct dpa_percpu_priv_s *percpu_priv =
2368 + raw_cpu_ptr(priv->percpu_priv);
2369 + struct qman_portal *p;
2370 + const struct qman_portal_config *pc;
2371 + struct dpa_napi_portal *np;
2372 +
2373 + p = (struct qman_portal *)qman_get_affine_portal(smp_processor_id());
2374 + pc = qman_p_get_portal_config(p);
2375 + np = &percpu_priv->np[pc->index];
2376 +
2377 + qman_p_irqsource_remove(np->p, QM_PIRQ_DQRI);
2378 + qman_p_poll_dqrr(np->p, np->napi.weight);
2379 + qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2380 +}
2381 +#endif
2382 +
2383 +static const struct net_device_ops dpa_private_ops = {
2384 + .ndo_open = dpa_eth_priv_start,
2385 + .ndo_start_xmit = dpa_tx,
2386 + .ndo_stop = dpa_eth_priv_stop,
2387 + .ndo_tx_timeout = dpa_timeout,
2388 + .ndo_get_stats64 = dpa_get_stats64,
2389 + .ndo_set_mac_address = dpa_set_mac_address,
2390 + .ndo_validate_addr = eth_validate_addr,
2391 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
2392 + .ndo_select_queue = dpa_select_queue,
2393 +#endif
2394 + .ndo_change_mtu = dpa_change_mtu,
2395 + .ndo_set_rx_mode = dpa_set_rx_mode,
2396 + .ndo_init = dpa_ndo_init,
2397 + .ndo_set_features = dpa_set_features,
2398 + .ndo_fix_features = dpa_fix_features,
2399 + .ndo_do_ioctl = dpa_ioctl,
2400 +#ifdef CONFIG_NET_POLL_CONTROLLER
2401 + .ndo_poll_controller = dpaa_eth_poll_controller,
2402 +#endif
2403 +};
2404 +
2405 +static int dpa_private_napi_add(struct net_device *net_dev)
2406 +{
2407 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2408 + struct dpa_percpu_priv_s *percpu_priv;
2409 + int i, cpu;
2410 +
2411 + for_each_possible_cpu(cpu) {
2412 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2413 +
2414 + percpu_priv->np = devm_kzalloc(net_dev->dev.parent,
2415 + qman_portal_max * sizeof(struct dpa_napi_portal),
2416 + GFP_KERNEL);
2417 +
2418 + if (unlikely(percpu_priv->np == NULL)) {
2419 + dev_err(net_dev->dev.parent, "devm_kzalloc() failed\n");
2420 + return -ENOMEM;
2421 + }
2422 +
2423 + for (i = 0; i < qman_portal_max; i++)
2424 + netif_napi_add(net_dev, &percpu_priv->np[i].napi,
2425 + dpaa_eth_poll, DPA_NAPI_WEIGHT);
2426 + }
2427 +
2428 + return 0;
2429 +}
2430 +
2431 +void dpa_private_napi_del(struct net_device *net_dev)
2432 +{
2433 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2434 + struct dpa_percpu_priv_s *percpu_priv;
2435 + int i, cpu;
2436 +
2437 + for_each_possible_cpu(cpu) {
2438 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2439 +
2440 + if (percpu_priv->np) {
2441 + for (i = 0; i < qman_portal_max; i++)
2442 + netif_napi_del(&percpu_priv->np[i].napi);
2443 +
2444 + devm_kfree(net_dev->dev.parent, percpu_priv->np);
2445 + }
2446 + }
2447 +}
2448 +EXPORT_SYMBOL(dpa_private_napi_del);
2449 +
2450 +static int dpa_private_netdev_init(struct net_device *net_dev)
2451 +{
2452 + int i;
2453 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2454 + struct dpa_percpu_priv_s *percpu_priv;
2455 + const uint8_t *mac_addr;
2456 +
2457 + /* Although we access another CPU's private data here
2458 + * we do it at initialization so it is safe
2459 + */
2460 + for_each_possible_cpu(i) {
2461 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2462 + percpu_priv->net_dev = net_dev;
2463 + }
2464 +
2465 + net_dev->netdev_ops = &dpa_private_ops;
2466 + mac_addr = priv->mac_dev->addr;
2467 +
2468 + net_dev->mem_start = priv->mac_dev->res->start;
2469 + net_dev->mem_end = priv->mac_dev->res->end;
2470 +
2471 + net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
2472 + NETIF_F_LLTX);
2473 +
2474 + /* Advertise S/G and HIGHDMA support for private interfaces */
2475 + net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
2476 + /* Recent kernels enable GSO automatically, if
2477 + * we declare NETIF_F_SG. For conformity, we'll
2478 + * still declare GSO explicitly.
2479 + */
2480 + net_dev->features |= NETIF_F_GSO;
2481 +
2482 + /* Advertise GRO support */
2483 + net_dev->features |= NETIF_F_GRO;
2484 +
2485 + /* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */
2486 + net_dev->features |= NETIF_F_HW_ACCEL_MQ;
2487 +
2488 + return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
2489 +}
2490 +
2491 +static struct dpa_bp * __cold
2492 +dpa_priv_bp_probe(struct device *dev)
2493 +{
2494 + struct dpa_bp *dpa_bp;
2495 +
2496 + dpa_bp = devm_kzalloc(dev, sizeof(*dpa_bp), GFP_KERNEL);
2497 + if (unlikely(dpa_bp == NULL)) {
2498 + dev_err(dev, "devm_kzalloc() failed\n");
2499 + return ERR_PTR(-ENOMEM);
2500 + }
2501 +
2502 + dpa_bp->percpu_count = devm_alloc_percpu(dev, *dpa_bp->percpu_count);
2503 + dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
2504 +
2505 + dpa_bp->seed_cb = dpa_bp_priv_seed;
2506 + dpa_bp->free_buf_cb = _dpa_bp_free_pf;
2507 +
2508 + return dpa_bp;
2509 +}
2510 +
2511 +/* Place all ingress FQs (Rx Default, Rx Error, PCD FQs) in a dedicated CGR.
2512 + * We won't be sending congestion notifications to FMan; for now, we just use
2513 + * this CGR to generate enqueue rejections to FMan in order to drop the frames
2514 + * before they reach our ingress queues and eat up memory.
2515 + */
2516 +static int dpaa_eth_priv_ingress_cgr_init(struct dpa_priv_s *priv)
2517 +{
2518 + struct qm_mcc_initcgr initcgr;
2519 + u32 cs_th;
2520 + int err;
2521 +
2522 + err = qman_alloc_cgrid(&priv->ingress_cgr.cgrid);
2523 + if (err < 0) {
2524 + pr_err("Error %d allocating CGR ID\n", err);
2525 + goto out_error;
2526 + }
2527 +
2528 + /* Enable CS TD, but disable Congestion State Change Notifications. */
2529 + initcgr.we_mask = QM_CGR_WE_CS_THRES;
2530 + initcgr.cgr.cscn_en = QM_CGR_EN;
2531 + cs_th = CONFIG_FSL_DPAA_INGRESS_CS_THRESHOLD;
2532 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
2533 +
2534 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
2535 + initcgr.cgr.cstd_en = QM_CGR_EN;
2536 +
2537 + /* This is actually a hack, because this CGR will be associated with
2538 + * our affine SWP. However, we'll place our ingress FQs in it.
2539 + */
2540 + err = qman_create_cgr(&priv->ingress_cgr, QMAN_CGR_FLAG_USE_INIT,
2541 + &initcgr);
2542 + if (err < 0) {
2543 + pr_err("Error %d creating ingress CGR with ID %d\n", err,
2544 + priv->ingress_cgr.cgrid);
2545 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2546 + goto out_error;
2547 + }
2548 + pr_debug("Created ingress CGR %d for netdev with hwaddr %pM\n",
2549 + priv->ingress_cgr.cgrid, priv->mac_dev->addr);
2550 +
2551 + /* struct qman_cgr allows special cgrid values (i.e. outside the 0..255
2552 + * range), but we have no common initialization path between the
2553 + * different variants of the DPAA Eth driver, so we do it here rather
2554 + * than modifying every other variant than "private Eth".
2555 + */
2556 + priv->use_ingress_cgr = true;
2557 +
2558 +out_error:
2559 + return err;
2560 +}
2561 +
2562 +static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
2563 + size_t count)
2564 +{
2565 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2566 + int i;
2567 +
2568 + if (netif_msg_probe(priv))
2569 + dev_dbg(net_dev->dev.parent,
2570 + "Using private BM buffer pools\n");
2571 +
2572 + priv->bp_count = count;
2573 +
2574 + for (i = 0; i < count; i++) {
2575 + int err;
2576 + err = dpa_bp_alloc(&dpa_bp[i]);
2577 + if (err < 0) {
2578 + dpa_bp_free(priv);
2579 + priv->dpa_bp = NULL;
2580 + return err;
2581 + }
2582 +
2583 + priv->dpa_bp = &dpa_bp[i];
2584 + }
2585 +
2586 + dpa_priv_common_bpid = priv->dpa_bp->bpid;
2587 + return 0;
2588 +}
2589 +
2590 +static const struct of_device_id dpa_match[];
2591 +
2592 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2593 +static int dpa_new_loop_id(void)
2594 +{
2595 + static int if_id;
2596 +
2597 + return if_id++;
2598 +}
2599 +#endif
2600 +
2601 +static int
2602 +dpaa_eth_priv_probe(struct platform_device *_of_dev)
2603 +{
2604 + int err = 0, i, channel;
2605 + struct device *dev;
2606 + struct device_node *dpa_node;
2607 + struct dpa_bp *dpa_bp;
2608 + size_t count = 1;
2609 + struct net_device *net_dev = NULL;
2610 + struct dpa_priv_s *priv = NULL;
2611 + struct dpa_percpu_priv_s *percpu_priv;
2612 + struct fm_port_fqs port_fqs;
2613 + struct dpa_buffer_layout_s *buf_layout = NULL;
2614 + struct mac_device *mac_dev;
2615 +
2616 + dev = &_of_dev->dev;
2617 +
2618 + dpa_node = dev->of_node;
2619 +
2620 + if (!of_device_is_available(dpa_node))
2621 + return -ENODEV;
2622 +
2623 + /* Get the buffer pools assigned to this interface;
2624 + * run only once the default pool probing code
2625 + */
2626 + dpa_bp = (dpa_bpid2pool(dpa_priv_common_bpid)) ? :
2627 + dpa_priv_bp_probe(dev);
2628 + if (IS_ERR(dpa_bp))
2629 + return PTR_ERR(dpa_bp);
2630 +
2631 + /* Allocate this early, so we can store relevant information in
2632 + * the private area (needed by 1588 code in dpa_mac_probe)
2633 + */
2634 + net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES);
2635 + if (!net_dev) {
2636 + dev_err(dev, "alloc_etherdev_mq() failed\n");
2637 + goto alloc_etherdev_mq_failed;
2638 + }
2639 +
2640 + /* Do this here, so we can be verbose early */
2641 + SET_NETDEV_DEV(net_dev, dev);
2642 + dev_set_drvdata(dev, net_dev);
2643 +
2644 + priv = netdev_priv(net_dev);
2645 + priv->net_dev = net_dev;
2646 + strcpy(priv->if_type, "private");
2647 +
2648 + priv->msg_enable = netif_msg_init(debug, -1);
2649 +
2650 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2651 + priv->loop_id = dpa_new_loop_id();
2652 + priv->loop_to = -1; /* disabled by default */
2653 + dpa_loop_netdevs[priv->loop_id] = net_dev;
2654 +#endif
2655 +
2656 + mac_dev = dpa_mac_probe(_of_dev);
2657 + if (IS_ERR(mac_dev) || !mac_dev) {
2658 + err = PTR_ERR(mac_dev);
2659 + goto mac_probe_failed;
2660 + }
2661 +
2662 + /* We have physical ports, so we need to establish
2663 + * the buffer layout.
2664 + */
2665 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
2666 + GFP_KERNEL);
2667 + if (!buf_layout) {
2668 + dev_err(dev, "devm_kzalloc() failed\n");
2669 + goto alloc_failed;
2670 + }
2671 + dpa_set_buffers_layout(mac_dev, buf_layout);
2672 +
2673 + /* For private ports, need to compute the size of the default
2674 + * buffer pool, based on FMan port buffer layout;also update
2675 + * the maximum buffer size for private ports if necessary
2676 + */
2677 + dpa_bp->size = dpa_bp_size(&buf_layout[RX]);
2678 +
2679 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
2680 + /* We only want to use jumbo frame optimization if we actually have
2681 + * L2 MAX FRM set for jumbo frames as well.
2682 + */
2683 +#ifndef CONFIG_PPC
2684 + if (likely(!dpaa_errata_a010022))
2685 +#endif
2686 + if(fm_get_max_frm() < 9600)
2687 + dev_warn(dev,
2688 + "Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n");
2689 +#endif
2690 +
2691 + INIT_LIST_HEAD(&priv->dpa_fq_list);
2692 +
2693 + memset(&port_fqs, 0, sizeof(port_fqs));
2694 +
2695 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs, true, RX);
2696 + if (!err)
2697 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
2698 + &port_fqs, true, TX);
2699 +
2700 + if (err < 0)
2701 + goto fq_probe_failed;
2702 +
2703 + /* bp init */
2704 +
2705 + err = dpa_priv_bp_create(net_dev, dpa_bp, count);
2706 +
2707 + if (err < 0)
2708 + goto bp_create_failed;
2709 +
2710 + priv->mac_dev = mac_dev;
2711 +
2712 + channel = dpa_get_channel();
2713 +
2714 + if (channel < 0) {
2715 + err = channel;
2716 + goto get_channel_failed;
2717 + }
2718 +
2719 + priv->channel = (uint16_t)channel;
2720 + dpaa_eth_add_channel(priv->channel);
2721 +
2722 + dpa_fq_setup(priv, &private_fq_cbs, priv->mac_dev->port_dev[TX]);
2723 +
2724 + /* Create a congestion group for this netdev, with
2725 + * dynamically-allocated CGR ID.
2726 + * Must be executed after probing the MAC, but before
2727 + * assigning the egress FQs to the CGRs.
2728 + */
2729 + err = dpaa_eth_cgr_init(priv);
2730 + if (err < 0) {
2731 + dev_err(dev, "Error initializing CGR\n");
2732 + goto tx_cgr_init_failed;
2733 + }
2734 + err = dpaa_eth_priv_ingress_cgr_init(priv);
2735 + if (err < 0) {
2736 + dev_err(dev, "Error initializing ingress CGR\n");
2737 + goto rx_cgr_init_failed;
2738 + }
2739 +
2740 + /* Add the FQs to the interface, and make them active */
2741 + err = dpa_fqs_init(dev, &priv->dpa_fq_list, false);
2742 + if (err < 0)
2743 + goto fq_alloc_failed;
2744 +
2745 + priv->buf_layout = buf_layout;
2746 + priv->tx_headroom = dpa_get_headroom(&priv->buf_layout[TX]);
2747 + priv->rx_headroom = dpa_get_headroom(&priv->buf_layout[RX]);
2748 +
2749 + /* All real interfaces need their ports initialized */
2750 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
2751 + buf_layout, dev);
2752 +
2753 +#ifdef CONFIG_FMAN_PFC
2754 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
2755 + err = fm_port_set_pfc_priorities_mapping_to_qman_wq(
2756 + mac_dev->port_dev[TX], i, i);
2757 + if (unlikely(err != 0)) {
2758 + dev_err(dev, "Error maping PFC %u to WQ %u\n", i, i);
2759 + goto pfc_mapping_failed;
2760 + }
2761 + }
2762 +#endif
2763 +
2764 + priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
2765 +
2766 + if (priv->percpu_priv == NULL) {
2767 + dev_err(dev, "devm_alloc_percpu() failed\n");
2768 + err = -ENOMEM;
2769 + goto alloc_percpu_failed;
2770 + }
2771 + for_each_possible_cpu(i) {
2772 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2773 + memset(percpu_priv, 0, sizeof(*percpu_priv));
2774 + }
2775 +
2776 + /* Initialize NAPI */
2777 + err = dpa_private_napi_add(net_dev);
2778 +
2779 + if (err < 0)
2780 + goto napi_add_failed;
2781 +
2782 + err = dpa_private_netdev_init(net_dev);
2783 +
2784 + if (err < 0)
2785 + goto netdev_init_failed;
2786 +
2787 + dpaa_eth_sysfs_init(&net_dev->dev);
2788 +
2789 +#ifdef CONFIG_PM
2790 + device_set_wakeup_capable(dev, true);
2791 +#endif
2792 +
2793 + pr_info("fsl_dpa: Probed interface %s\n", net_dev->name);
2794 +
2795 + return 0;
2796 +
2797 +netdev_init_failed:
2798 +napi_add_failed:
2799 + dpa_private_napi_del(net_dev);
2800 +alloc_percpu_failed:
2801 +#ifdef CONFIG_FMAN_PFC
2802 +pfc_mapping_failed:
2803 +#endif
2804 + dpa_fq_free(dev, &priv->dpa_fq_list);
2805 +fq_alloc_failed:
2806 + qman_delete_cgr_safe(&priv->ingress_cgr);
2807 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2808 +rx_cgr_init_failed:
2809 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
2810 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
2811 +tx_cgr_init_failed:
2812 +get_channel_failed:
2813 + dpa_bp_free(priv);
2814 +bp_create_failed:
2815 +fq_probe_failed:
2816 +alloc_failed:
2817 +mac_probe_failed:
2818 + dev_set_drvdata(dev, NULL);
2819 + free_netdev(net_dev);
2820 +alloc_etherdev_mq_failed:
2821 + if (atomic_read(&dpa_bp->refs) == 0)
2822 + devm_kfree(dev, dpa_bp);
2823 +
2824 + return err;
2825 +}
2826 +
2827 +static const struct of_device_id dpa_match[] = {
2828 + {
2829 + .compatible = "fsl,dpa-ethernet"
2830 + },
2831 + {}
2832 +};
2833 +MODULE_DEVICE_TABLE(of, dpa_match);
2834 +
2835 +static struct platform_driver dpa_driver = {
2836 + .driver = {
2837 + .name = KBUILD_MODNAME,
2838 + .of_match_table = dpa_match,
2839 + .owner = THIS_MODULE,
2840 + .pm = DPAA_PM_OPS,
2841 + },
2842 + .probe = dpaa_eth_priv_probe,
2843 + .remove = dpa_remove
2844 +};
2845 +
2846 +#ifndef CONFIG_PPC
2847 +static bool __init __cold soc_has_errata_a010022(void)
2848 +{
2849 +#ifdef CONFIG_SOC_BUS
2850 + const struct soc_device_attribute soc_msi_matches[] = {
2851 + { .family = "QorIQ LS1043A",
2852 + .data = NULL },
2853 + { },
2854 + };
2855 +
2856 + if (soc_device_match(soc_msi_matches))
2857 + return true;
2858 +
2859 + return false;
2860 +#else
2861 + return true; /* cannot identify SoC */
2862 +#endif
2863 +}
2864 +#endif
2865 +
2866 +static int __init __cold dpa_load(void)
2867 +{
2868 + int _errno;
2869 +
2870 + pr_info(DPA_DESCRIPTION "\n");
2871 +
2872 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2873 + dpa_debugfs_module_init();
2874 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2875 +
2876 + /* initialise dpaa_eth mirror values */
2877 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
2878 + dpa_max_frm = fm_get_max_frm();
2879 + dpa_num_cpus = num_possible_cpus();
2880 +
2881 +#ifndef CONFIG_PPC
2882 + /* Detect if the current SoC requires the 4K alignment workaround */
2883 + dpaa_errata_a010022 = soc_has_errata_a010022();
2884 +#endif
2885 +
2886 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2887 + memset(dpa_loop_netdevs, 0, sizeof(dpa_loop_netdevs));
2888 +#endif
2889 +
2890 + _errno = platform_driver_register(&dpa_driver);
2891 + if (unlikely(_errno < 0)) {
2892 + pr_err(KBUILD_MODNAME
2893 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
2894 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
2895 + }
2896 +
2897 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2898 + KBUILD_BASENAME".c", __func__);
2899 +
2900 + return _errno;
2901 +}
2902 +module_init(dpa_load);
2903 +
2904 +static void __exit __cold dpa_unload(void)
2905 +{
2906 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
2907 + KBUILD_BASENAME".c", __func__);
2908 +
2909 + platform_driver_unregister(&dpa_driver);
2910 +
2911 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2912 + dpa_debugfs_module_exit();
2913 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2914 +
2915 + /* Only one channel is used and needs to be relased after all
2916 + * interfaces are removed
2917 + */
2918 + dpa_release_channel();
2919 +
2920 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2921 + KBUILD_BASENAME".c", __func__);
2922 +}
2923 +module_exit(dpa_unload);
2924 --- /dev/null
2925 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
2926 @@ -0,0 +1,687 @@
2927 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
2928 + *
2929 + * Redistribution and use in source and binary forms, with or without
2930 + * modification, are permitted provided that the following conditions are met:
2931 + * * Redistributions of source code must retain the above copyright
2932 + * notice, this list of conditions and the following disclaimer.
2933 + * * Redistributions in binary form must reproduce the above copyright
2934 + * notice, this list of conditions and the following disclaimer in the
2935 + * documentation and/or other materials provided with the distribution.
2936 + * * Neither the name of Freescale Semiconductor nor the
2937 + * names of its contributors may be used to endorse or promote products
2938 + * derived from this software without specific prior written permission.
2939 + *
2940 + *
2941 + * ALTERNATIVELY, this software may be distributed under the terms of the
2942 + * GNU General Public License ("GPL") as published by the Free Software
2943 + * Foundation, either version 2 of that License or (at your option) any
2944 + * later version.
2945 + *
2946 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
2947 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2948 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2949 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
2950 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2951 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2952 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2953 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2954 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2955 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2956 + */
2957 +
2958 +#ifndef __DPA_H
2959 +#define __DPA_H
2960 +
2961 +#include <linux/netdevice.h>
2962 +#include <linux/fsl_qman.h> /* struct qman_fq */
2963 +
2964 +#include "fm_ext.h"
2965 +#include "dpaa_eth_trace.h"
2966 +
2967 +extern int dpa_rx_extra_headroom;
2968 +extern int dpa_max_frm;
2969 +extern int dpa_num_cpus;
2970 +
2971 +#define dpa_get_rx_extra_headroom() dpa_rx_extra_headroom
2972 +#define dpa_get_max_frm() dpa_max_frm
2973 +
2974 +#define dpa_get_max_mtu() \
2975 + (dpa_get_max_frm() - (VLAN_ETH_HLEN + ETH_FCS_LEN))
2976 +
2977 +#define __hot
2978 +
2979 +/* Simple enum of FQ types - used for array indexing */
2980 +enum port_type {RX, TX};
2981 +
2982 +/* TODO: This structure should be renamed & moved to the FMD wrapper */
2983 +struct dpa_buffer_layout_s {
2984 + uint16_t priv_data_size;
2985 + bool parse_results;
2986 + bool time_stamp;
2987 + bool hash_results;
2988 + uint8_t manip_extra_space;
2989 + uint16_t data_align;
2990 +};
2991 +
2992 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
2993 +#define DPA_BUG_ON(cond) BUG_ON(cond)
2994 +#else
2995 +#define DPA_BUG_ON(cond)
2996 +#endif
2997 +
2998 +#define DPA_TX_PRIV_DATA_SIZE 16
2999 +#define DPA_PARSE_RESULTS_SIZE sizeof(fm_prs_result_t)
3000 +#define DPA_TIME_STAMP_SIZE 8
3001 +#define DPA_HASH_RESULTS_SIZE 8
3002 +#define DPA_RX_PRIV_DATA_SIZE (DPA_TX_PRIV_DATA_SIZE + \
3003 + dpa_get_rx_extra_headroom())
3004 +
3005 +#define FM_FD_STAT_RX_ERRORS \
3006 + (FM_PORT_FRM_ERR_DMA | FM_PORT_FRM_ERR_PHYSICAL | \
3007 + FM_PORT_FRM_ERR_SIZE | FM_PORT_FRM_ERR_CLS_DISCARD | \
3008 + FM_PORT_FRM_ERR_EXTRACTION | FM_PORT_FRM_ERR_NO_SCHEME | \
3009 + FM_PORT_FRM_ERR_ILL_PLCR | FM_PORT_FRM_ERR_PRS_TIMEOUT | \
3010 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | FM_PORT_FRM_ERR_PRS_HDR_ERR)
3011 +
3012 +#define FM_FD_STAT_TX_ERRORS \
3013 + (FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT | \
3014 + FM_PORT_FRM_ERR_LENGTH | FM_PORT_FRM_ERR_DMA)
3015 +
3016 +#ifndef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
3017 +/* The raw buffer size must be cacheline aligned.
3018 + * Normally we use 2K buffers.
3019 + */
3020 +#define DPA_BP_RAW_SIZE 2048
3021 +#else
3022 +/* For jumbo frame optimizations, use buffers large enough to accommodate
3023 + * 9.6K frames, FD maximum offset, skb sh_info overhead and some extra
3024 + * space to account for further alignments.
3025 + */
3026 +#define DPA_MAX_FRM_SIZE 9600
3027 +#ifdef CONFIG_PPC
3028 +#define DPA_BP_RAW_SIZE \
3029 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3030 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1))
3031 +#else /* CONFIG_PPC */
3032 +#define DPA_BP_RAW_SIZE ((unlikely(dpaa_errata_a010022)) ? 2048 : \
3033 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3034 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1)))
3035 +#endif /* CONFIG_PPC */
3036 +#endif /* CONFIG_FSL_DPAA_ETH_JUMBO_FRAME */
3037 +
3038 +/* This is what FMan is ever allowed to use.
3039 + * FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is
3040 + * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that,
3041 + * via SKB_WITH_OVERHEAD(). We can't rely on netdev_alloc_frag() giving us
3042 + * half-page-aligned buffers (can we?), so we reserve some more space
3043 + * for start-of-buffer alignment.
3044 + */
3045 +#define dpa_bp_size(buffer_layout) (SKB_WITH_OVERHEAD(DPA_BP_RAW_SIZE) - \
3046 + SMP_CACHE_BYTES)
3047 +/* We must ensure that skb_shinfo is always cacheline-aligned. */
3048 +#define DPA_SKB_SIZE(size) ((size) & ~(SMP_CACHE_BYTES - 1))
3049 +
3050 +/* Maximum size of a buffer for which recycling is allowed.
3051 + * We need an upper limit such that forwarded skbs that get reallocated on Tx
3052 + * aren't allowed to grow unboundedly. On the other hand, we need to make sure
3053 + * that skbs allocated by us will not fail to be recycled due to their size.
3054 + *
3055 + * For a requested size, the kernel allocator provides the next power of two
3056 + * sized block, which the stack will use as is, regardless of the actual size
3057 + * it required; since we must accommodate at most 9.6K buffers (L2 maximum
3058 + * supported frame size), set the recycling upper limit to 16K.
3059 + */
3060 +#define DPA_RECYCLE_MAX_SIZE 16384
3061 +
3062 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3063 +/*TODO: temporary for fman pcd testing */
3064 +#define FMAN_PCD_TESTS_MAX_NUM_RANGES 20
3065 +#endif
3066 +
3067 +#define DPAA_ETH_FQ_DELTA 0x10000
3068 +
3069 +#define DPAA_ETH_PCD_FQ_BASE(device_addr) \
3070 + (((device_addr) & 0x1fffff) >> 6)
3071 +
3072 +#define DPAA_ETH_PCD_FQ_HI_PRIO_BASE(device_addr) \
3073 + (DPAA_ETH_FQ_DELTA + DPAA_ETH_PCD_FQ_BASE(device_addr))
3074 +
3075 +/* Largest value that the FQD's OAL field can hold.
3076 + * This is DPAA-1.x specific.
3077 + * TODO: This rather belongs in fsl_qman.h
3078 + */
3079 +#define FSL_QMAN_MAX_OAL 127
3080 +
3081 +/* Maximum offset value for a contig or sg FD (represented on 9 bits) */
3082 +#define DPA_MAX_FD_OFFSET ((1 << 9) - 1)
3083 +
3084 +/* Default alignment for start of data in an Rx FD */
3085 +#define DPA_FD_DATA_ALIGNMENT 16
3086 +
3087 +/* Values for the L3R field of the FM Parse Results
3088 + */
3089 +/* L3 Type field: First IP Present IPv4 */
3090 +#define FM_L3_PARSE_RESULT_IPV4 0x8000
3091 +/* L3 Type field: First IP Present IPv6 */
3092 +#define FM_L3_PARSE_RESULT_IPV6 0x4000
3093 +
3094 +/* Values for the L4R field of the FM Parse Results
3095 + * See $8.8.4.7.20 - L4 HXS - L4 Results from DPAA-Rev2 Reference Manual.
3096 + */
3097 +/* L4 Type field: UDP */
3098 +#define FM_L4_PARSE_RESULT_UDP 0x40
3099 +/* L4 Type field: TCP */
3100 +#define FM_L4_PARSE_RESULT_TCP 0x20
3101 +/* FD status field indicating whether the FM Parser has attempted to validate
3102 + * the L4 csum of the frame.
3103 + * Note that having this bit set doesn't necessarily imply that the checksum
3104 + * is valid. One would have to check the parse results to find that out.
3105 + */
3106 +#define FM_FD_STAT_L4CV 0x00000004
3107 +
3108 +
3109 +#define FM_FD_STAT_ERR_PHYSICAL FM_PORT_FRM_ERR_PHYSICAL
3110 +
3111 +/* Check if the parsed frame was found to be a TCP segment.
3112 + *
3113 + * @parse_result_ptr must be of type (fm_prs_result_t *).
3114 + */
3115 +#define fm_l4_frame_is_tcp(parse_result_ptr) \
3116 + ((parse_result_ptr)->l4r & FM_L4_PARSE_RESULT_TCP)
3117 +
3118 +/* number of Tx queues to FMan */
3119 +#ifdef CONFIG_FMAN_PFC
3120 +#define DPAA_ETH_TX_QUEUES (NR_CPUS * CONFIG_FMAN_PFC_COS_COUNT)
3121 +#else
3122 +#define DPAA_ETH_TX_QUEUES NR_CPUS
3123 +#endif
3124 +
3125 +#define DPAA_ETH_RX_QUEUES 128
3126 +
3127 +/* Convenience macros for storing/retrieving the skb back-pointers. They must
3128 + * accommodate both recycling and confirmation paths - i.e. cases when the buf
3129 + * was allocated by ourselves, respectively by the stack. In the former case,
3130 + * we could store the skb at negative offset; in the latter case, we can't,
3131 + * so we'll use 0 as offset.
3132 + *
3133 + * NB: @off is an offset from a (struct sk_buff **) pointer!
3134 + */
3135 +#define DPA_WRITE_SKB_PTR(skb, skbh, addr, off) \
3136 +{ \
3137 + skbh = (struct sk_buff **)addr; \
3138 + *(skbh + (off)) = skb; \
3139 +}
3140 +#define DPA_READ_SKB_PTR(skb, skbh, addr, off) \
3141 +{ \
3142 + skbh = (struct sk_buff **)addr; \
3143 + skb = *(skbh + (off)); \
3144 +}
3145 +
3146 +#ifdef CONFIG_PM
3147 +/* Magic Packet wakeup */
3148 +#define DPAA_WOL_MAGIC 0x00000001
3149 +#endif
3150 +
3151 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3152 +struct pcd_range {
3153 + uint32_t base;
3154 + uint32_t count;
3155 +};
3156 +#endif
3157 +
3158 +/* More detailed FQ types - used for fine-grained WQ assignments */
3159 +enum dpa_fq_type {
3160 + FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */
3161 + FQ_TYPE_RX_ERROR, /* Rx Error FQs */
3162 + FQ_TYPE_RX_PCD, /* User-defined PCDs */
3163 + FQ_TYPE_TX, /* "Real" Tx FQs */
3164 + FQ_TYPE_TX_CONFIRM, /* Tx default Conf FQ (actually an Rx FQ) */
3165 + FQ_TYPE_TX_CONF_MQ, /* Tx conf FQs (one for each Tx FQ) */
3166 + FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */
3167 + FQ_TYPE_RX_PCD_HI_PRIO, /* User-defined high-priority PCDs */
3168 +};
3169 +
3170 +struct dpa_fq {
3171 + struct qman_fq fq_base;
3172 + struct list_head list;
3173 + struct net_device *net_dev;
3174 + bool init;
3175 + uint32_t fqid;
3176 + uint32_t flags;
3177 + uint16_t channel;
3178 + uint8_t wq;
3179 + enum dpa_fq_type fq_type;
3180 +};
3181 +
3182 +struct dpa_fq_cbs_t {
3183 + struct qman_fq rx_defq;
3184 + struct qman_fq tx_defq;
3185 + struct qman_fq rx_errq;
3186 + struct qman_fq tx_errq;
3187 + struct qman_fq egress_ern;
3188 +};
3189 +
3190 +struct fqid_cell {
3191 + uint32_t start;
3192 + uint32_t count;
3193 +};
3194 +
3195 +struct dpa_bp {
3196 + struct bman_pool *pool;
3197 + uint8_t bpid;
3198 + struct device *dev;
3199 + union {
3200 + /* The buffer pools used for the private ports are initialized
3201 + * with target_count buffers for each CPU; at runtime the
3202 + * number of buffers per CPU is constantly brought back to this
3203 + * level
3204 + */
3205 + int target_count;
3206 + /* The configured value for the number of buffers in the pool,
3207 + * used for shared port buffer pools
3208 + */
3209 + int config_count;
3210 + };
3211 + size_t size;
3212 + bool seed_pool;
3213 + /* physical address of the contiguous memory used by the pool to store
3214 + * the buffers
3215 + */
3216 + dma_addr_t paddr;
3217 + /* virtual address of the contiguous memory used by the pool to store
3218 + * the buffers
3219 + */
3220 + void __iomem *vaddr;
3221 + /* current number of buffers in the bpool alloted to this CPU */
3222 + int __percpu *percpu_count;
3223 + atomic_t refs;
3224 + /* some bpools need to be seeded before use by this cb */
3225 + int (*seed_cb)(struct dpa_bp *);
3226 + /* some bpools need to be emptied before freeing; this cb is used
3227 + * for freeing of individual buffers taken from the pool
3228 + */
3229 + void (*free_buf_cb)(void *addr);
3230 +};
3231 +
3232 +struct dpa_rx_errors {
3233 + u64 dme; /* DMA Error */
3234 + u64 fpe; /* Frame Physical Error */
3235 + u64 fse; /* Frame Size Error */
3236 + u64 phe; /* Header Error */
3237 + u64 cse; /* Checksum Validation Error */
3238 +};
3239 +
3240 +/* Counters for QMan ERN frames - one counter per rejection code */
3241 +struct dpa_ern_cnt {
3242 + u64 cg_tdrop; /* Congestion group taildrop */
3243 + u64 wred; /* WRED congestion */
3244 + u64 err_cond; /* Error condition */
3245 + u64 early_window; /* Order restoration, frame too early */
3246 + u64 late_window; /* Order restoration, frame too late */
3247 + u64 fq_tdrop; /* FQ taildrop */
3248 + u64 fq_retired; /* FQ is retired */
3249 + u64 orp_zero; /* ORP disabled */
3250 +};
3251 +
3252 +struct dpa_napi_portal {
3253 + struct napi_struct napi;
3254 + struct qman_portal *p;
3255 +};
3256 +
3257 +struct dpa_percpu_priv_s {
3258 + struct net_device *net_dev;
3259 + struct dpa_napi_portal *np;
3260 + u64 in_interrupt;
3261 + u64 tx_returned;
3262 + u64 tx_confirm;
3263 + /* fragmented (non-linear) skbuffs received from the stack */
3264 + u64 tx_frag_skbuffs;
3265 + /* number of S/G frames received */
3266 + u64 rx_sg;
3267 +
3268 + struct rtnl_link_stats64 stats;
3269 + struct dpa_rx_errors rx_errors;
3270 + struct dpa_ern_cnt ern_cnt;
3271 +};
3272 +
3273 +struct dpa_priv_s {
3274 + struct dpa_percpu_priv_s __percpu *percpu_priv;
3275 + struct dpa_bp *dpa_bp;
3276 + /* Store here the needed Tx headroom for convenience and speed
3277 + * (even though it can be computed based on the fields of buf_layout)
3278 + */
3279 + uint16_t tx_headroom;
3280 + struct net_device *net_dev;
3281 + struct mac_device *mac_dev;
3282 + struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES];
3283 + struct qman_fq *conf_fqs[DPAA_ETH_TX_QUEUES];
3284 +
3285 + size_t bp_count;
3286 +
3287 + uint16_t channel; /* "fsl,qman-channel-id" */
3288 + struct list_head dpa_fq_list;
3289 +
3290 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3291 + struct dentry *debugfs_loop_file;
3292 +#endif
3293 +
3294 + uint32_t msg_enable; /* net_device message level */
3295 +#ifdef CONFIG_FSL_DPAA_1588
3296 + struct dpa_ptp_tsu *tsu;
3297 +#endif
3298 +
3299 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3300 +/* TODO: this is temporary until pcd support is implemented in dpaa */
3301 + int priv_pcd_num_ranges;
3302 + struct pcd_range priv_pcd_ranges[FMAN_PCD_TESTS_MAX_NUM_RANGES];
3303 +#endif
3304 +
3305 + struct {
3306 + /**
3307 + * All egress queues to a given net device belong to one
3308 + * (and the same) congestion group.
3309 + */
3310 + struct qman_cgr cgr;
3311 + /* If congested, when it began. Used for performance stats. */
3312 + u32 congestion_start_jiffies;
3313 + /* Number of jiffies the Tx port was congested. */
3314 + u32 congested_jiffies;
3315 + /**
3316 + * Counter for the number of times the CGR
3317 + * entered congestion state
3318 + */
3319 + u32 cgr_congested_count;
3320 + } cgr_data;
3321 + /* Use a per-port CGR for ingress traffic. */
3322 + bool use_ingress_cgr;
3323 + struct qman_cgr ingress_cgr;
3324 +
3325 +#ifdef CONFIG_FSL_DPAA_TS
3326 + bool ts_tx_en; /* Tx timestamping enabled */
3327 + bool ts_rx_en; /* Rx timestamping enabled */
3328 +#endif /* CONFIG_FSL_DPAA_TS */
3329 +
3330 + struct dpa_buffer_layout_s *buf_layout;
3331 + uint16_t rx_headroom;
3332 + char if_type[30];
3333 +
3334 + void *peer;
3335 +#ifdef CONFIG_PM
3336 + u32 wol;
3337 +#endif
3338 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3339 + int loop_id;
3340 + int loop_to;
3341 +#endif
3342 +#ifdef CONFIG_FSL_DPAA_CEETM
3343 + bool ceetm_en; /* CEETM QoS enabled */
3344 +#endif
3345 +};
3346 +
3347 +struct fm_port_fqs {
3348 + struct dpa_fq *tx_defq;
3349 + struct dpa_fq *tx_errq;
3350 + struct dpa_fq *rx_defq;
3351 + struct dpa_fq *rx_errq;
3352 +};
3353 +
3354 +
3355 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3356 +extern struct net_device *dpa_loop_netdevs[20];
3357 +#endif
3358 +
3359 +/* functions with different implementation for SG and non-SG: */
3360 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp);
3361 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *count_ptr);
3362 +void __hot _dpa_rx(struct net_device *net_dev,
3363 + struct qman_portal *portal,
3364 + const struct dpa_priv_s *priv,
3365 + struct dpa_percpu_priv_s *percpu_priv,
3366 + const struct qm_fd *fd,
3367 + u32 fqid,
3368 + int *count_ptr);
3369 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev);
3370 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
3371 + struct qman_fq *egress_fq, struct qman_fq *conf_fq);
3372 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
3373 + const struct qm_fd *fd);
3374 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
3375 + const struct qm_fd *fd,
3376 + struct sk_buff *skb,
3377 + int *use_gro);
3378 +#ifndef CONFIG_FSL_DPAA_TS
3379 +bool dpa_skb_is_recyclable(struct sk_buff *skb);
3380 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
3381 + uint32_t min_size,
3382 + uint16_t min_offset,
3383 + unsigned char **new_buf_start);
3384 +#endif
3385 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
3386 + struct sk_buff *skb, struct qm_fd *fd,
3387 + int *count_ptr, int *offset);
3388 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
3389 + struct sk_buff *skb, struct qm_fd *fd);
3390 +int __cold __attribute__((nonnull))
3391 + _dpa_fq_free(struct device *dev, struct qman_fq *fq);
3392 +
3393 +/* Turn on HW checksum computation for this outgoing frame.
3394 + * If the current protocol is not something we support in this regard
3395 + * (or if the stack has already computed the SW checksum), we do nothing.
3396 + *
3397 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
3398 + * otherwise.
3399 + *
3400 + * Note that this function may modify the fd->cmd field and the skb data buffer
3401 + * (the Parse Results area).
3402 + */
3403 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
3404 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
3405 +
3406 +static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv,
3407 + struct qman_portal *portal)
3408 +{
3409 + /* In case of threaded ISR for RT enable kernel,
3410 + * in_irq() does not return appropriate value, so use
3411 + * in_serving_softirq to distinguish softirq or irq context.
3412 + */
3413 + if (unlikely(in_irq() || !in_serving_softirq())) {
3414 + /* Disable QMan IRQ and invoke NAPI */
3415 + int ret = qman_p_irqsource_remove(portal, QM_PIRQ_DQRI);
3416 + if (likely(!ret)) {
3417 + const struct qman_portal_config *pc =
3418 + qman_p_get_portal_config(portal);
3419 + struct dpa_napi_portal *np =
3420 + &percpu_priv->np[pc->index];
3421 +
3422 + np->p = portal;
3423 + napi_schedule(&np->napi);
3424 + percpu_priv->in_interrupt++;
3425 + return 1;
3426 + }
3427 + }
3428 + return 0;
3429 +}
3430 +
3431 +static inline ssize_t __const __must_check __attribute__((nonnull))
3432 +dpa_fd_length(const struct qm_fd *fd)
3433 +{
3434 + return fd->length20;
3435 +}
3436 +
3437 +static inline ssize_t __const __must_check __attribute__((nonnull))
3438 +dpa_fd_offset(const struct qm_fd *fd)
3439 +{
3440 + return fd->offset;
3441 +}
3442 +
3443 +static inline uint16_t dpa_get_headroom(struct dpa_buffer_layout_s *bl)
3444 +{
3445 + uint16_t headroom;
3446 + /* The frame headroom must accommodate:
3447 + * - the driver private data area
3448 + * - parse results, hash results, timestamp if selected
3449 + * - manip extra space
3450 + * If either hash results or time stamp are selected, both will
3451 + * be copied to/from the frame headroom, as TS is located between PR and
3452 + * HR in the IC and IC copy size has a granularity of 16bytes
3453 + * (see description of FMBM_RICP and FMBM_TICP registers in DPAARM)
3454 + *
3455 + * Also make sure the headroom is a multiple of data_align bytes
3456 + */
3457 + headroom = (uint16_t)(bl->priv_data_size +
3458 + (bl->parse_results ? DPA_PARSE_RESULTS_SIZE : 0) +
3459 + (bl->hash_results || bl->time_stamp ?
3460 + DPA_TIME_STAMP_SIZE + DPA_HASH_RESULTS_SIZE : 0) +
3461 + bl->manip_extra_space);
3462 +
3463 + return bl->data_align ? ALIGN(headroom, bl->data_align) : headroom;
3464 +}
3465 +
3466 +int fm_mac_dump_regs(struct mac_device *h_dev, char *buf, int n);
3467 +int fm_mac_dump_rx_stats(struct mac_device *h_dev, char *buf, int n);
3468 +int fm_mac_dump_tx_stats(struct mac_device *h_dev, char *buf, int n);
3469 +
3470 +void dpaa_eth_sysfs_remove(struct device *dev);
3471 +void dpaa_eth_sysfs_init(struct device *dev);
3472 +int dpaa_eth_poll(struct napi_struct *napi, int budget);
3473 +
3474 +void dpa_private_napi_del(struct net_device *net_dev);
3475 +
3476 +/* Equivalent to a memset(0), but works faster */
3477 +static inline void clear_fd(struct qm_fd *fd)
3478 +{
3479 + fd->opaque_addr = 0;
3480 + fd->opaque = 0;
3481 + fd->cmd = 0;
3482 +}
3483 +
3484 +static inline int _dpa_tx_fq_to_id(const struct dpa_priv_s *priv,
3485 + struct qman_fq *tx_fq)
3486 +{
3487 + int i;
3488 +
3489 + for (i = 0; i < DPAA_ETH_TX_QUEUES; i++)
3490 + if (priv->egress_fqs[i] == tx_fq)
3491 + return i;
3492 +
3493 + return -EINVAL;
3494 +}
3495 +
3496 +static inline int __hot dpa_xmit(struct dpa_priv_s *priv,
3497 + struct rtnl_link_stats64 *percpu_stats,
3498 + struct qm_fd *fd, struct qman_fq *egress_fq,
3499 + struct qman_fq *conf_fq)
3500 +{
3501 + int err, i;
3502 +
3503 + if (fd->bpid == 0xff)
3504 + fd->cmd |= qman_fq_fqid(conf_fq);
3505 +
3506 + /* Trace this Tx fd */
3507 + trace_dpa_tx_fd(priv->net_dev, egress_fq, fd);
3508 +
3509 + for (i = 0; i < 100000; i++) {
3510 + err = qman_enqueue(egress_fq, fd, 0);
3511 + if (err != -EBUSY)
3512 + break;
3513 + }
3514 +
3515 + if (unlikely(err < 0)) {
3516 + /* TODO differentiate b/w -EBUSY (EQCR full) and other codes? */
3517 + percpu_stats->tx_errors++;
3518 + percpu_stats->tx_fifo_errors++;
3519 + return err;
3520 + }
3521 +
3522 + percpu_stats->tx_packets++;
3523 + percpu_stats->tx_bytes += dpa_fd_length(fd);
3524 +
3525 + return 0;
3526 +}
3527 +
3528 +/* Use multiple WQs for FQ assignment:
3529 + * - Tx Confirmation queues go to WQ1.
3530 + * - Rx Default, Tx and PCD queues go to WQ3 (no differentiation between
3531 + * Rx and Tx traffic, or between Rx Default and Rx PCD frames).
3532 + * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance
3533 + * to be scheduled, in case there are many more FQs in WQ3).
3534 + * This ensures that Tx-confirmed buffers are timely released. In particular,
3535 + * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they
3536 + * are greatly outnumbered by other FQs in the system (usually PCDs), while
3537 + * dequeue scheduling is round-robin.
3538 + */
3539 +static inline void _dpa_assign_wq(struct dpa_fq *fq)
3540 +{
3541 + switch (fq->fq_type) {
3542 + case FQ_TYPE_TX_CONFIRM:
3543 + case FQ_TYPE_TX_CONF_MQ:
3544 + fq->wq = 1;
3545 + break;
3546 + case FQ_TYPE_RX_DEFAULT:
3547 + case FQ_TYPE_TX:
3548 + fq->wq = 3;
3549 + break;
3550 + case FQ_TYPE_RX_ERROR:
3551 + case FQ_TYPE_TX_ERROR:
3552 + case FQ_TYPE_RX_PCD_HI_PRIO:
3553 + fq->wq = 2;
3554 + break;
3555 + case FQ_TYPE_RX_PCD:
3556 + fq->wq = 5;
3557 + break;
3558 + default:
3559 + WARN(1, "Invalid FQ type %d for FQID %d!\n",
3560 + fq->fq_type, fq->fqid);
3561 + }
3562 +}
3563 +
3564 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
3565 +/* Use in lieu of skb_get_queue_mapping() */
3566 +#ifdef CONFIG_FMAN_PFC
3567 +#define dpa_get_queue_mapping(skb) \
3568 + (((skb)->priority < CONFIG_FMAN_PFC_COS_COUNT) ? \
3569 + ((skb)->priority * dpa_num_cpus + smp_processor_id()) : \
3570 + ((CONFIG_FMAN_PFC_COS_COUNT - 1) * \
3571 + dpa_num_cpus + smp_processor_id()));
3572 +
3573 +#else
3574 +#define dpa_get_queue_mapping(skb) \
3575 + raw_smp_processor_id()
3576 +#endif
3577 +#else
3578 +/* Use the queue selected by XPS */
3579 +#define dpa_get_queue_mapping(skb) \
3580 + skb_get_queue_mapping(skb)
3581 +#endif
3582 +
3583 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
3584 +struct ptp_priv_s {
3585 + struct device_node *node;
3586 + struct platform_device *of_dev;
3587 + struct ptp_clock *clock;
3588 + struct mac_device *mac_dev;
3589 +};
3590 +extern struct ptp_priv_s ptp_priv;
3591 +#endif
3592 +
3593 +static inline void _dpa_bp_free_pf(void *addr)
3594 +{
3595 + put_page(virt_to_head_page(addr));
3596 +}
3597 +
3598 +/* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue
3599 + * manifests itself at high traffic rates when frames cross 4K memory
3600 + * boundaries or when they are not aligned to 16 bytes; For the moment, we
3601 + * use a SW workaround to avoid frames larger than 4K or that exceed 4K
3602 + * alignments and to realign the frames to 16 bytes.
3603 + */
3604 +
3605 +#ifndef CONFIG_PPC
3606 +extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */
3607 +#define NONREC_MARK 0x01
3608 +#define HAS_DMA_ISSUE(start, size) \
3609 + (((uintptr_t)(start) + (size)) > \
3610 + (((uintptr_t)(start) + 0x1000) & ~0xFFF))
3611 +#endif /* !CONFIG_PPC */
3612 +
3613 +#endif /* __DPA_H */
3614 --- /dev/null
3615 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
3616 @@ -0,0 +1,205 @@
3617 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3618 + *
3619 + * Redistribution and use in source and binary forms, with or without
3620 + * modification, are permitted provided that the following conditions are met:
3621 + * * Redistributions of source code must retain the above copyright
3622 + * notice, this list of conditions and the following disclaimer.
3623 + * * Redistributions in binary form must reproduce the above copyright
3624 + * notice, this list of conditions and the following disclaimer in the
3625 + * documentation and/or other materials provided with the distribution.
3626 + * * Neither the name of Freescale Semiconductor nor the
3627 + * names of its contributors may be used to endorse or promote products
3628 + * derived from this software without specific prior written permission.
3629 + *
3630 + *
3631 + * ALTERNATIVELY, this software may be distributed under the terms of the
3632 + * GNU General Public License ("GPL") as published by the Free Software
3633 + * Foundation, either version 2 of that License or (at your option) any
3634 + * later version.
3635 + *
3636 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3637 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3638 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3639 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3640 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3641 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3642 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3643 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3644 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3645 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3646 + */
3647 +
3648 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3649 +#define pr_fmt(fmt) \
3650 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
3651 + KBUILD_BASENAME".c", __LINE__, __func__
3652 +#else
3653 +#define pr_fmt(fmt) \
3654 + KBUILD_MODNAME ": " fmt
3655 +#endif
3656 +
3657 +#include <linux/init.h>
3658 +#include <linux/module.h>
3659 +#include <linux/io.h>
3660 +#include <linux/of_platform.h>
3661 +#include <linux/of_net.h>
3662 +#include <linux/etherdevice.h>
3663 +#include <linux/kthread.h>
3664 +#include <linux/percpu.h>
3665 +#include <linux/highmem.h>
3666 +#include <linux/sort.h>
3667 +#include <linux/fsl_qman.h>
3668 +#include "dpaa_eth.h"
3669 +#include "dpaa_eth_common.h"
3670 +#include "dpaa_eth_base.h"
3671 +
3672 +#define DPA_DESCRIPTION "FSL DPAA Advanced drivers:"
3673 +
3674 +MODULE_LICENSE("Dual BSD/GPL");
3675 +
3676 +uint8_t advanced_debug = -1;
3677 +module_param(advanced_debug, byte, S_IRUGO);
3678 +MODULE_PARM_DESC(advanced_debug, "Module/Driver verbosity level");
3679 +EXPORT_SYMBOL(advanced_debug);
3680 +
3681 +static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
3682 +{
3683 + return ((struct dpa_bp *)dpa_bp0)->size -
3684 + ((struct dpa_bp *)dpa_bp1)->size;
3685 +}
3686 +
3687 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3688 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
3689 +{
3690 + int i, lenp, na, ns, err;
3691 + struct device *dev;
3692 + struct device_node *dev_node;
3693 + const __be32 *bpool_cfg;
3694 + struct dpa_bp *dpa_bp;
3695 + u32 bpid;
3696 +
3697 + dev = &_of_dev->dev;
3698 +
3699 + *count = of_count_phandle_with_args(dev->of_node,
3700 + "fsl,bman-buffer-pools", NULL);
3701 + if (*count < 1) {
3702 + dev_err(dev, "missing fsl,bman-buffer-pools device tree entry\n");
3703 + return ERR_PTR(-EINVAL);
3704 + }
3705 +
3706 + dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL);
3707 + if (dpa_bp == NULL) {
3708 + dev_err(dev, "devm_kzalloc() failed\n");
3709 + return ERR_PTR(-ENOMEM);
3710 + }
3711 +
3712 + dev_node = of_find_node_by_path("/");
3713 + if (unlikely(dev_node == NULL)) {
3714 + dev_err(dev, "of_find_node_by_path(/) failed\n");
3715 + return ERR_PTR(-EINVAL);
3716 + }
3717 +
3718 + na = of_n_addr_cells(dev_node);
3719 + ns = of_n_size_cells(dev_node);
3720 +
3721 + for (i = 0; i < *count; i++) {
3722 + of_node_put(dev_node);
3723 +
3724 + dev_node = of_parse_phandle(dev->of_node,
3725 + "fsl,bman-buffer-pools", i);
3726 + if (dev_node == NULL) {
3727 + dev_err(dev, "of_find_node_by_phandle() failed\n");
3728 + return ERR_PTR(-EFAULT);
3729 + }
3730 +
3731 + if (unlikely(!of_device_is_compatible(dev_node, "fsl,bpool"))) {
3732 + dev_err(dev,
3733 + "!of_device_is_compatible(%s, fsl,bpool)\n",
3734 + dev_node->full_name);
3735 + dpa_bp = ERR_PTR(-EINVAL);
3736 + goto _return_of_node_put;
3737 + }
3738 +
3739 + err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
3740 + if (err) {
3741 + dev_err(dev, "Cannot find buffer pool ID in the device tree\n");
3742 + dpa_bp = ERR_PTR(-EINVAL);
3743 + goto _return_of_node_put;
3744 + }
3745 + dpa_bp[i].bpid = (uint8_t)bpid;
3746 +
3747 + bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
3748 + &lenp);
3749 + if (bpool_cfg && (lenp == (2 * ns + na) * sizeof(*bpool_cfg))) {
3750 + const uint32_t *seed_pool;
3751 +
3752 + dpa_bp[i].config_count =
3753 + (int)of_read_number(bpool_cfg, ns);
3754 + dpa_bp[i].size =
3755 + (size_t)of_read_number(bpool_cfg + ns, ns);
3756 + dpa_bp[i].paddr =
3757 + of_read_number(bpool_cfg + 2 * ns, na);
3758 +
3759 + seed_pool = of_get_property(dev_node,
3760 + "fsl,bpool-ethernet-seeds", &lenp);
3761 + dpa_bp[i].seed_pool = !!seed_pool;
3762 +
3763 + } else {
3764 + dev_err(dev,
3765 + "Missing/invalid fsl,bpool-ethernet-cfg device tree entry for node %s\n",
3766 + dev_node->full_name);
3767 + dpa_bp = ERR_PTR(-EINVAL);
3768 + goto _return_of_node_put;
3769 + }
3770 + }
3771 +
3772 + sort(dpa_bp, *count, sizeof(*dpa_bp), dpa_bp_cmp, NULL);
3773 +
3774 + return dpa_bp;
3775 +
3776 +_return_of_node_put:
3777 + if (dev_node)
3778 + of_node_put(dev_node);
3779 +
3780 + return dpa_bp;
3781 +}
3782 +EXPORT_SYMBOL(dpa_bp_probe);
3783 +
3784 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3785 + size_t count)
3786 +{
3787 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3788 + int i;
3789 +
3790 + priv->dpa_bp = dpa_bp;
3791 + priv->bp_count = count;
3792 +
3793 + for (i = 0; i < count; i++) {
3794 + int err;
3795 + err = dpa_bp_alloc(&dpa_bp[i]);
3796 + if (err < 0) {
3797 + dpa_bp_free(priv);
3798 + priv->dpa_bp = NULL;
3799 + return err;
3800 + }
3801 + }
3802 +
3803 + return 0;
3804 +}
3805 +EXPORT_SYMBOL(dpa_bp_create);
3806 +
3807 +static int __init __cold dpa_advanced_load(void)
3808 +{
3809 + pr_info(DPA_DESCRIPTION "\n");
3810 +
3811 + return 0;
3812 +}
3813 +module_init(dpa_advanced_load);
3814 +
3815 +static void __exit __cold dpa_advanced_unload(void)
3816 +{
3817 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
3818 + KBUILD_BASENAME".c", __func__);
3819 +
3820 +}
3821 +module_exit(dpa_advanced_unload);
3822 --- /dev/null
3823 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
3824 @@ -0,0 +1,49 @@
3825 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3826 + *
3827 + * Redistribution and use in source and binary forms, with or without
3828 + * modification, are permitted provided that the following conditions are met:
3829 + * * Redistributions of source code must retain the above copyright
3830 + * notice, this list of conditions and the following disclaimer.
3831 + * * Redistributions in binary form must reproduce the above copyright
3832 + * notice, this list of conditions and the following disclaimer in the
3833 + * documentation and/or other materials provided with the distribution.
3834 + * * Neither the name of Freescale Semiconductor nor the
3835 + * names of its contributors may be used to endorse or promote products
3836 + * derived from this software without specific prior written permission.
3837 + *
3838 + *
3839 + * ALTERNATIVELY, this software may be distributed under the terms of the
3840 + * GNU General Public License ("GPL") as published by the Free Software
3841 + * Foundation, either version 2 of that License or (at your option) any
3842 + * later version.
3843 + *
3844 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3845 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3846 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3847 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3848 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3849 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3850 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3851 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3852 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3853 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3854 + */
3855 +
3856 +#ifndef __DPAA_ETH_BASE_H
3857 +#define __DPAA_ETH_BASE_H
3858 +
3859 +#include <linux/etherdevice.h> /* struct net_device */
3860 +#include <linux/fsl_bman.h> /* struct bm_buffer */
3861 +#include <linux/of_platform.h> /* struct platform_device */
3862 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
3863 +
3864 +extern uint8_t advanced_debug;
3865 +extern const struct dpa_fq_cbs_t shared_fq_cbs;
3866 +extern int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
3867 +
3868 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3869 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count);
3870 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3871 + size_t count);
3872 +
3873 +#endif /* __DPAA_ETH_BASE_H */
3874 --- /dev/null
3875 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
3876 @@ -0,0 +1,1992 @@
3877 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
3878 + *
3879 + * Redistribution and use in source and binary forms, with or without
3880 + * modification, are permitted provided that the following conditions are met:
3881 + * * Redistributions of source code must retain the above copyright
3882 + * notice, this list of conditions and the following disclaimer.
3883 + * * Redistributions in binary form must reproduce the above copyright
3884 + * notice, this list of conditions and the following disclaimer in the
3885 + * documentation and/or other materials provided with the distribution.
3886 + * * Neither the name of Freescale Semiconductor nor the
3887 + * names of its contributors may be used to endorse or promote products
3888 + * derived from this software without specific prior written permission.
3889 + *
3890 + *
3891 + * ALTERNATIVELY, this software may be distributed under the terms of the
3892 + * GNU General Public License ("GPL") as published by the Free Software
3893 + * Foundation, either version 2 of that License or (at your option) any
3894 + * later version.
3895 + *
3896 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3897 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3898 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3899 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3900 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3901 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3902 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3903 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3904 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3905 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3906 + */
3907 +
3908 +#include <linux/init.h>
3909 +#include "dpaa_eth_ceetm.h"
3910 +
3911 +#define DPA_CEETM_DESCRIPTION "FSL DPAA CEETM qdisc"
3912 +
3913 +const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1] = {
3914 + [TCA_CEETM_COPT] = { .len = sizeof(struct tc_ceetm_copt) },
3915 + [TCA_CEETM_QOPS] = { .len = sizeof(struct tc_ceetm_qopt) },
3916 +};
3917 +
3918 +struct Qdisc_ops ceetm_qdisc_ops;
3919 +
3920 +/* Obtain the DCP and the SP ids from the FMan port */
3921 +static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id,
3922 + unsigned int *sp_id)
3923 +{
3924 + uint32_t channel;
3925 + t_LnxWrpFmPortDev *port_dev;
3926 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
3927 + struct mac_device *mac_dev = dpa_priv->mac_dev;
3928 +
3929 + port_dev = (t_LnxWrpFmPortDev *)mac_dev->port_dev[TX];
3930 + channel = port_dev->txCh;
3931 +
3932 + *sp_id = channel & CHANNEL_SP_MASK;
3933 + pr_debug(KBUILD_BASENAME " : FM sub-portal ID %d\n", *sp_id);
3934 +
3935 + if (channel < DCP0_MAX_CHANNEL) {
3936 + *dcp_id = qm_dc_portal_fman0;
3937 + pr_debug(KBUILD_BASENAME " : DCP ID 0\n");
3938 + } else {
3939 + *dcp_id = qm_dc_portal_fman1;
3940 + pr_debug(KBUILD_BASENAME " : DCP ID 1\n");
3941 + }
3942 +}
3943 +
3944 +/* Enqueue Rejection Notification callback */
3945 +static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq,
3946 + const struct qm_mr_entry *msg)
3947 +{
3948 + struct net_device *net_dev;
3949 + struct ceetm_class *cls;
3950 + struct ceetm_class_stats *cstats = NULL;
3951 + const struct dpa_priv_s *dpa_priv;
3952 + struct dpa_percpu_priv_s *dpa_percpu_priv;
3953 + struct sk_buff *skb;
3954 + struct qm_fd fd = msg->ern.fd;
3955 +
3956 + net_dev = ((struct ceetm_fq *)fq)->net_dev;
3957 + dpa_priv = netdev_priv(net_dev);
3958 + dpa_percpu_priv = raw_cpu_ptr(dpa_priv->percpu_priv);
3959 +
3960 + /* Increment DPA counters */
3961 + dpa_percpu_priv->stats.tx_dropped++;
3962 + dpa_percpu_priv->stats.tx_fifo_errors++;
3963 +
3964 + /* Increment CEETM counters */
3965 + cls = ((struct ceetm_fq *)fq)->ceetm_cls;
3966 + switch (cls->type) {
3967 + case CEETM_PRIO:
3968 + cstats = this_cpu_ptr(cls->prio.cstats);
3969 + break;
3970 + case CEETM_WBFS:
3971 + cstats = this_cpu_ptr(cls->wbfs.cstats);
3972 + break;
3973 + }
3974 +
3975 + if (cstats)
3976 + cstats->ern_drop_count++;
3977 +
3978 + if (fd.bpid != 0xff) {
3979 + dpa_fd_release(net_dev, &fd);
3980 + return;
3981 + }
3982 +
3983 + skb = _dpa_cleanup_tx_fd(dpa_priv, &fd);
3984 + dev_kfree_skb_any(skb);
3985 +}
3986 +
3987 +/* Congestion State Change Notification callback */
3988 +static void ceetm_cscn(struct qm_ceetm_ccg *ccg, void *cb_ctx, int congested)
3989 +{
3990 + struct ceetm_fq *ceetm_fq = (struct ceetm_fq *)cb_ctx;
3991 + struct dpa_priv_s *dpa_priv = netdev_priv(ceetm_fq->net_dev);
3992 + struct ceetm_class *cls = ceetm_fq->ceetm_cls;
3993 + struct ceetm_class_stats *cstats = NULL;
3994 +
3995 + switch (cls->type) {
3996 + case CEETM_PRIO:
3997 + cstats = this_cpu_ptr(cls->prio.cstats);
3998 + break;
3999 + case CEETM_WBFS:
4000 + cstats = this_cpu_ptr(cls->wbfs.cstats);
4001 + break;
4002 + }
4003 +
4004 + if (congested) {
4005 + dpa_priv->cgr_data.congestion_start_jiffies = jiffies;
4006 + netif_tx_stop_all_queues(dpa_priv->net_dev);
4007 + dpa_priv->cgr_data.cgr_congested_count++;
4008 + if (cstats)
4009 + cstats->congested_count++;
4010 + } else {
4011 + dpa_priv->cgr_data.congested_jiffies +=
4012 + (jiffies - dpa_priv->cgr_data.congestion_start_jiffies);
4013 + netif_tx_wake_all_queues(dpa_priv->net_dev);
4014 + }
4015 +}
4016 +
4017 +/* Allocate a ceetm fq */
4018 +static int ceetm_alloc_fq(struct ceetm_fq **fq, struct net_device *dev,
4019 + struct ceetm_class *cls)
4020 +{
4021 + *fq = kzalloc(sizeof(**fq), GFP_KERNEL);
4022 + if (!*fq)
4023 + return -ENOMEM;
4024 +
4025 + (*fq)->net_dev = dev;
4026 + (*fq)->ceetm_cls = cls;
4027 + return 0;
4028 +}
4029 +
4030 +/* Configure a ceetm Class Congestion Group */
4031 +static int ceetm_config_ccg(struct qm_ceetm_ccg **ccg,
4032 + struct qm_ceetm_channel *channel, unsigned int id,
4033 + struct ceetm_fq *fq, struct dpa_priv_s *dpa_priv)
4034 +{
4035 + int err;
4036 + u32 cs_th;
4037 + u16 ccg_mask;
4038 + struct qm_ceetm_ccg_params ccg_params;
4039 +
4040 + err = qman_ceetm_ccg_claim(ccg, channel, id, ceetm_cscn, fq);
4041 + if (err)
4042 + return err;
4043 +
4044 + /* Configure the count mode (frames/bytes), enable congestion state
4045 + * notifications, configure the congestion entry and exit thresholds,
4046 + * enable tail-drop, configure the tail-drop mode, and set the
4047 + * overhead accounting limit
4048 + */
4049 + ccg_mask = QM_CCGR_WE_MODE |
4050 + QM_CCGR_WE_CSCN_EN |
4051 + QM_CCGR_WE_CS_THRES_IN | QM_CCGR_WE_CS_THRES_OUT |
4052 + QM_CCGR_WE_TD_EN | QM_CCGR_WE_TD_MODE |
4053 + QM_CCGR_WE_OAL;
4054 +
4055 + ccg_params.mode = 0; /* count bytes */
4056 + ccg_params.cscn_en = 1; /* generate notifications */
4057 + ccg_params.td_en = 1; /* enable tail-drop */
4058 + ccg_params.td_mode = 0; /* tail-drop on congestion state */
4059 + ccg_params.oal = (signed char)(min(sizeof(struct sk_buff) +
4060 + dpa_priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
4061 +
4062 + /* Set the congestion state thresholds according to the link speed */
4063 + if (dpa_priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
4064 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
4065 + else
4066 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
4067 +
4068 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_in, cs_th, 1);
4069 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_out,
4070 + cs_th * CEETM_CCGR_RATIO, 1);
4071 +
4072 + err = qman_ceetm_ccg_set(*ccg, ccg_mask, &ccg_params);
4073 + if (err)
4074 + return err;
4075 +
4076 + return 0;
4077 +}
4078 +
4079 +/* Configure a ceetm Logical Frame Queue */
4080 +static int ceetm_config_lfq(struct qm_ceetm_cq *cq, struct ceetm_fq *fq,
4081 + struct qm_ceetm_lfq **lfq)
4082 +{
4083 + int err;
4084 + u64 context_a;
4085 + u32 context_b;
4086 +
4087 + err = qman_ceetm_lfq_claim(lfq, cq);
4088 + if (err)
4089 + return err;
4090 +
4091 + /* Get the former contexts in order to preserve context B */
4092 + err = qman_ceetm_lfq_get_context(*lfq, &context_a, &context_b);
4093 + if (err)
4094 + return err;
4095 +
4096 + context_a = CEETM_CONTEXT_A;
4097 + err = qman_ceetm_lfq_set_context(*lfq, context_a, context_b);
4098 + if (err)
4099 + return err;
4100 +
4101 + (*lfq)->ern = ceetm_ern;
4102 +
4103 + err = qman_ceetm_create_fq(*lfq, &fq->fq);
4104 + if (err)
4105 + return err;
4106 +
4107 + return 0;
4108 +}
4109 +
4110 +/* Configure a prio ceetm class */
4111 +static int ceetm_config_prio_cls(struct ceetm_class *cls,
4112 + struct net_device *dev,
4113 + struct qm_ceetm_channel *channel,
4114 + unsigned int id)
4115 +{
4116 + int err;
4117 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4118 +
4119 + err = ceetm_alloc_fq(&cls->prio.fq, dev, cls);
4120 + if (err)
4121 + return err;
4122 +
4123 + /* Claim and configure the CCG */
4124 + err = ceetm_config_ccg(&cls->prio.ccg, channel, id, cls->prio.fq,
4125 + dpa_priv);
4126 + if (err)
4127 + return err;
4128 +
4129 + /* Claim and configure the CQ */
4130 + err = qman_ceetm_cq_claim(&cls->prio.cq, channel, id, cls->prio.ccg);
4131 + if (err)
4132 + return err;
4133 +
4134 + if (cls->shaped) {
4135 + err = qman_ceetm_channel_set_cq_cr_eligibility(channel, id, 1);
4136 + if (err)
4137 + return err;
4138 +
4139 + err = qman_ceetm_channel_set_cq_er_eligibility(channel, id, 1);
4140 + if (err)
4141 + return err;
4142 + }
4143 +
4144 + /* Claim and configure a LFQ */
4145 + err = ceetm_config_lfq(cls->prio.cq, cls->prio.fq, &cls->prio.lfq);
4146 + if (err)
4147 + return err;
4148 +
4149 + return 0;
4150 +}
4151 +
4152 +/* Configure a wbfs ceetm class */
4153 +static int ceetm_config_wbfs_cls(struct ceetm_class *cls,
4154 + struct net_device *dev,
4155 + struct qm_ceetm_channel *channel,
4156 + unsigned int id, int type)
4157 +{
4158 + int err;
4159 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4160 +
4161 + err = ceetm_alloc_fq(&cls->wbfs.fq, dev, cls);
4162 + if (err)
4163 + return err;
4164 +
4165 + /* Claim and configure the CCG */
4166 + err = ceetm_config_ccg(&cls->wbfs.ccg, channel, id, cls->wbfs.fq,
4167 + dpa_priv);
4168 + if (err)
4169 + return err;
4170 +
4171 + /* Claim and configure the CQ */
4172 + if (type == WBFS_GRP_B)
4173 + err = qman_ceetm_cq_claim_B(&cls->wbfs.cq, channel, id,
4174 + cls->wbfs.ccg);
4175 + else
4176 + err = qman_ceetm_cq_claim_A(&cls->wbfs.cq, channel, id,
4177 + cls->wbfs.ccg);
4178 + if (err)
4179 + return err;
4180 +
4181 + /* Configure the CQ weight: real number multiplied by 100 to get rid
4182 + * of the fraction
4183 + */
4184 + err = qman_ceetm_set_queue_weight_in_ratio(cls->wbfs.cq,
4185 + cls->wbfs.weight * 100);
4186 + if (err)
4187 + return err;
4188 +
4189 + /* Claim and configure a LFQ */
4190 + err = ceetm_config_lfq(cls->wbfs.cq, cls->wbfs.fq, &cls->wbfs.lfq);
4191 + if (err)
4192 + return err;
4193 +
4194 + return 0;
4195 +}
4196 +
4197 +/* Find class in qdisc hash table using given handle */
4198 +static inline struct ceetm_class *ceetm_find(u32 handle, struct Qdisc *sch)
4199 +{
4200 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4201 + struct Qdisc_class_common *clc;
4202 +
4203 + pr_debug(KBUILD_BASENAME " : %s : find class %X in qdisc %X\n",
4204 + __func__, handle, sch->handle);
4205 +
4206 + clc = qdisc_class_find(&priv->clhash, handle);
4207 + return clc ? container_of(clc, struct ceetm_class, common) : NULL;
4208 +}
4209 +
4210 +/* Insert a class in the qdisc's class hash */
4211 +static void ceetm_link_class(struct Qdisc *sch,
4212 + struct Qdisc_class_hash *clhash,
4213 + struct Qdisc_class_common *common)
4214 +{
4215 + sch_tree_lock(sch);
4216 + qdisc_class_hash_insert(clhash, common);
4217 + sch_tree_unlock(sch);
4218 + qdisc_class_hash_grow(sch, clhash);
4219 +}
4220 +
4221 +/* Destroy a ceetm class */
4222 +static void ceetm_cls_destroy(struct Qdisc *sch, struct ceetm_class *cl)
4223 +{
4224 + if (!cl)
4225 + return;
4226 +
4227 + pr_debug(KBUILD_BASENAME " : %s : destroy class %X from under %X\n",
4228 + __func__, cl->common.classid, sch->handle);
4229 +
4230 + switch (cl->type) {
4231 + case CEETM_ROOT:
4232 + if (cl->root.child) {
4233 + qdisc_destroy(cl->root.child);
4234 + cl->root.child = NULL;
4235 + }
4236 +
4237 + if (cl->root.ch && qman_ceetm_channel_release(cl->root.ch))
4238 + pr_err(KBUILD_BASENAME
4239 + " : %s : error releasing the channel %d\n",
4240 + __func__, cl->root.ch->idx);
4241 +
4242 + break;
4243 +
4244 + case CEETM_PRIO:
4245 + if (cl->prio.child) {
4246 + qdisc_destroy(cl->prio.child);
4247 + cl->prio.child = NULL;
4248 + }
4249 +
4250 + if (cl->prio.lfq && qman_ceetm_lfq_release(cl->prio.lfq))
4251 + pr_err(KBUILD_BASENAME
4252 + " : %s : error releasing the LFQ %d\n",
4253 + __func__, cl->prio.lfq->idx);
4254 +
4255 + if (cl->prio.cq && qman_ceetm_cq_release(cl->prio.cq))
4256 + pr_err(KBUILD_BASENAME
4257 + " : %s : error releasing the CQ %d\n",
4258 + __func__, cl->prio.cq->idx);
4259 +
4260 + if (cl->prio.ccg && qman_ceetm_ccg_release(cl->prio.ccg))
4261 + pr_err(KBUILD_BASENAME
4262 + " : %s : error releasing the CCG %d\n",
4263 + __func__, cl->prio.ccg->idx);
4264 +
4265 + kfree(cl->prio.fq);
4266 +
4267 + if (cl->prio.cstats)
4268 + free_percpu(cl->prio.cstats);
4269 +
4270 + break;
4271 +
4272 + case CEETM_WBFS:
4273 + if (cl->wbfs.lfq && qman_ceetm_lfq_release(cl->wbfs.lfq))
4274 + pr_err(KBUILD_BASENAME
4275 + " : %s : error releasing the LFQ %d\n",
4276 + __func__, cl->wbfs.lfq->idx);
4277 +
4278 + if (cl->wbfs.cq && qman_ceetm_cq_release(cl->wbfs.cq))
4279 + pr_err(KBUILD_BASENAME
4280 + " : %s : error releasing the CQ %d\n",
4281 + __func__, cl->wbfs.cq->idx);
4282 +
4283 + if (cl->wbfs.ccg && qman_ceetm_ccg_release(cl->wbfs.ccg))
4284 + pr_err(KBUILD_BASENAME
4285 + " : %s : error releasing the CCG %d\n",
4286 + __func__, cl->wbfs.ccg->idx);
4287 +
4288 + kfree(cl->wbfs.fq);
4289 +
4290 + if (cl->wbfs.cstats)
4291 + free_percpu(cl->wbfs.cstats);
4292 + }
4293 +
4294 + tcf_destroy_chain(&cl->filter_list);
4295 + kfree(cl);
4296 +}
4297 +
4298 +/* Destroy a ceetm qdisc */
4299 +static void ceetm_destroy(struct Qdisc *sch)
4300 +{
4301 + unsigned int ntx, i;
4302 + struct hlist_node *next;
4303 + struct ceetm_class *cl;
4304 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4305 + struct net_device *dev = qdisc_dev(sch);
4306 +
4307 + pr_debug(KBUILD_BASENAME " : %s : destroy qdisc %X\n",
4308 + __func__, sch->handle);
4309 +
4310 + /* All filters need to be removed before destroying the classes */
4311 + tcf_destroy_chain(&priv->filter_list);
4312 +
4313 + for (i = 0; i < priv->clhash.hashsize; i++) {
4314 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode)
4315 + tcf_destroy_chain(&cl->filter_list);
4316 + }
4317 +
4318 + for (i = 0; i < priv->clhash.hashsize; i++) {
4319 + hlist_for_each_entry_safe(cl, next, &priv->clhash.hash[i],
4320 + common.hnode)
4321 + ceetm_cls_destroy(sch, cl);
4322 + }
4323 +
4324 + qdisc_class_hash_destroy(&priv->clhash);
4325 +
4326 + switch (priv->type) {
4327 + case CEETM_ROOT:
4328 + dpa_disable_ceetm(dev);
4329 +
4330 + if (priv->root.lni && qman_ceetm_lni_release(priv->root.lni))
4331 + pr_err(KBUILD_BASENAME
4332 + " : %s : error releasing the LNI %d\n",
4333 + __func__, priv->root.lni->idx);
4334 +
4335 + if (priv->root.sp && qman_ceetm_sp_release(priv->root.sp))
4336 + pr_err(KBUILD_BASENAME
4337 + " : %s : error releasing the SP %d\n",
4338 + __func__, priv->root.sp->idx);
4339 +
4340 + if (priv->root.qstats)
4341 + free_percpu(priv->root.qstats);
4342 +
4343 + if (!priv->root.qdiscs)
4344 + break;
4345 +
4346 + /* Remove the pfifo qdiscs */
4347 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++)
4348 + if (priv->root.qdiscs[ntx])
4349 + qdisc_destroy(priv->root.qdiscs[ntx]);
4350 +
4351 + kfree(priv->root.qdiscs);
4352 + break;
4353 +
4354 + case CEETM_PRIO:
4355 + if (priv->prio.parent)
4356 + priv->prio.parent->root.child = NULL;
4357 + break;
4358 +
4359 + case CEETM_WBFS:
4360 + if (priv->wbfs.parent)
4361 + priv->wbfs.parent->prio.child = NULL;
4362 + break;
4363 + }
4364 +}
4365 +
4366 +static int ceetm_dump(struct Qdisc *sch, struct sk_buff *skb)
4367 +{
4368 + struct Qdisc *qdisc;
4369 + unsigned int ntx, i;
4370 + struct nlattr *nest;
4371 + struct tc_ceetm_qopt qopt;
4372 + struct ceetm_qdisc_stats *qstats;
4373 + struct net_device *dev = qdisc_dev(sch);
4374 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4375 +
4376 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4377 +
4378 + sch_tree_lock(sch);
4379 + memset(&qopt, 0, sizeof(qopt));
4380 + qopt.type = priv->type;
4381 + qopt.shaped = priv->shaped;
4382 +
4383 + switch (priv->type) {
4384 + case CEETM_ROOT:
4385 + /* Gather statistics from the underlying pfifo qdiscs */
4386 + sch->q.qlen = 0;
4387 + memset(&sch->bstats, 0, sizeof(sch->bstats));
4388 + memset(&sch->qstats, 0, sizeof(sch->qstats));
4389 +
4390 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
4391 + qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping;
4392 + sch->q.qlen += qdisc->q.qlen;
4393 + sch->bstats.bytes += qdisc->bstats.bytes;
4394 + sch->bstats.packets += qdisc->bstats.packets;
4395 + sch->qstats.qlen += qdisc->qstats.qlen;
4396 + sch->qstats.backlog += qdisc->qstats.backlog;
4397 + sch->qstats.drops += qdisc->qstats.drops;
4398 + sch->qstats.requeues += qdisc->qstats.requeues;
4399 + sch->qstats.overlimits += qdisc->qstats.overlimits;
4400 + }
4401 +
4402 + for_each_online_cpu(i) {
4403 + qstats = per_cpu_ptr(priv->root.qstats, i);
4404 + sch->qstats.drops += qstats->drops;
4405 + }
4406 +
4407 + qopt.rate = priv->root.rate;
4408 + qopt.ceil = priv->root.ceil;
4409 + qopt.overhead = priv->root.overhead;
4410 + break;
4411 +
4412 + case CEETM_PRIO:
4413 + qopt.qcount = priv->prio.qcount;
4414 + break;
4415 +
4416 + case CEETM_WBFS:
4417 + qopt.qcount = priv->wbfs.qcount;
4418 + qopt.cr = priv->wbfs.cr;
4419 + qopt.er = priv->wbfs.er;
4420 + break;
4421 +
4422 + default:
4423 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
4424 + sch_tree_unlock(sch);
4425 + return -EINVAL;
4426 + }
4427 +
4428 + nest = nla_nest_start(skb, TCA_OPTIONS);
4429 + if (!nest)
4430 + goto nla_put_failure;
4431 + if (nla_put(skb, TCA_CEETM_QOPS, sizeof(qopt), &qopt))
4432 + goto nla_put_failure;
4433 + nla_nest_end(skb, nest);
4434 +
4435 + sch_tree_unlock(sch);
4436 + return skb->len;
4437 +
4438 +nla_put_failure:
4439 + sch_tree_unlock(sch);
4440 + nla_nest_cancel(skb, nest);
4441 + return -EMSGSIZE;
4442 +}
4443 +
4444 +/* Configure a root ceetm qdisc */
4445 +static int ceetm_init_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
4446 + struct tc_ceetm_qopt *qopt)
4447 +{
4448 + struct netdev_queue *dev_queue;
4449 + struct Qdisc *qdisc;
4450 + enum qm_dc_portal dcp_id;
4451 + unsigned int i, sp_id, parent_id;
4452 + int err;
4453 + u64 bps;
4454 + struct qm_ceetm_sp *sp;
4455 + struct qm_ceetm_lni *lni;
4456 + struct net_device *dev = qdisc_dev(sch);
4457 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4458 + struct mac_device *mac_dev = dpa_priv->mac_dev;
4459 +
4460 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4461 +
4462 + /* Validate inputs */
4463 + if (sch->parent != TC_H_ROOT) {
4464 + pr_err("CEETM: a root ceetm qdisc can not be attached to a class\n");
4465 + tcf_destroy_chain(&priv->filter_list);
4466 + qdisc_class_hash_destroy(&priv->clhash);
4467 + return -EINVAL;
4468 + }
4469 +
4470 + if (!mac_dev) {
4471 + pr_err("CEETM: the interface is lacking a mac\n");
4472 + err = -EINVAL;
4473 + goto err_init_root;
4474 + }
4475 +
4476 + /* pre-allocate underlying pfifo qdiscs */
4477 + priv->root.qdiscs = kcalloc(dev->num_tx_queues,
4478 + sizeof(priv->root.qdiscs[0]),
4479 + GFP_KERNEL);
4480 + if (!priv->root.qdiscs) {
4481 + err = -ENOMEM;
4482 + goto err_init_root;
4483 + }
4484 +
4485 + for (i = 0; i < dev->num_tx_queues; i++) {
4486 + dev_queue = netdev_get_tx_queue(dev, i);
4487 + parent_id = TC_H_MAKE(TC_H_MAJ(sch->handle),
4488 + TC_H_MIN(i + PFIFO_MIN_OFFSET));
4489 +
4490 + qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,
4491 + parent_id);
4492 + if (!qdisc) {
4493 + err = -ENOMEM;
4494 + goto err_init_root;
4495 + }
4496 +
4497 + priv->root.qdiscs[i] = qdisc;
4498 + qdisc->flags |= TCQ_F_ONETXQUEUE;
4499 + }
4500 +
4501 + sch->flags |= TCQ_F_MQROOT;
4502 +
4503 + priv->root.qstats = alloc_percpu(struct ceetm_qdisc_stats);
4504 + if (!priv->root.qstats) {
4505 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4506 + __func__);
4507 + err = -ENOMEM;
4508 + goto err_init_root;
4509 + }
4510 +
4511 + priv->shaped = qopt->shaped;
4512 + priv->root.rate = qopt->rate;
4513 + priv->root.ceil = qopt->ceil;
4514 + priv->root.overhead = qopt->overhead;
4515 +
4516 + /* Claim the SP */
4517 + get_dcp_and_sp(dev, &dcp_id, &sp_id);
4518 + err = qman_ceetm_sp_claim(&sp, dcp_id, sp_id);
4519 + if (err) {
4520 + pr_err(KBUILD_BASENAME " : %s : failed to claim the SP\n",
4521 + __func__);
4522 + goto err_init_root;
4523 + }
4524 +
4525 + priv->root.sp = sp;
4526 +
4527 + /* Claim the LNI - will use the same id as the SP id since SPs 0-7
4528 + * are connected to the TX FMan ports
4529 + */
4530 + err = qman_ceetm_lni_claim(&lni, dcp_id, sp_id);
4531 + if (err) {
4532 + pr_err(KBUILD_BASENAME " : %s : failed to claim the LNI\n",
4533 + __func__);
4534 + goto err_init_root;
4535 + }
4536 +
4537 + priv->root.lni = lni;
4538 +
4539 + err = qman_ceetm_sp_set_lni(sp, lni);
4540 + if (err) {
4541 + pr_err(KBUILD_BASENAME " : %s : failed to link the SP and LNI\n",
4542 + __func__);
4543 + goto err_init_root;
4544 + }
4545 +
4546 + lni->sp = sp;
4547 +
4548 + /* Configure the LNI shaper */
4549 + if (priv->shaped) {
4550 + err = qman_ceetm_lni_enable_shaper(lni, 1, priv->root.overhead);
4551 + if (err) {
4552 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4553 + __func__);
4554 + goto err_init_root;
4555 + }
4556 +
4557 + bps = priv->root.rate << 3; /* Bps -> bps */
4558 + err = qman_ceetm_lni_set_commit_rate_bps(lni, bps, dev->mtu);
4559 + if (err) {
4560 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4561 + __func__);
4562 + goto err_init_root;
4563 + }
4564 +
4565 + bps = priv->root.ceil << 3; /* Bps -> bps */
4566 + err = qman_ceetm_lni_set_excess_rate_bps(lni, bps, dev->mtu);
4567 + if (err) {
4568 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4569 + __func__);
4570 + goto err_init_root;
4571 + }
4572 + }
4573 +
4574 + /* TODO default configuration */
4575 +
4576 + dpa_enable_ceetm(dev);
4577 + return 0;
4578 +
4579 +err_init_root:
4580 + ceetm_destroy(sch);
4581 + return err;
4582 +}
4583 +
4584 +/* Configure a prio ceetm qdisc */
4585 +static int ceetm_init_prio(struct Qdisc *sch, struct ceetm_qdisc *priv,
4586 + struct tc_ceetm_qopt *qopt)
4587 +{
4588 + int err;
4589 + unsigned int i;
4590 + struct ceetm_class *parent_cl, *child_cl;
4591 + struct Qdisc *parent_qdisc;
4592 + struct net_device *dev = qdisc_dev(sch);
4593 +
4594 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4595 +
4596 + if (sch->parent == TC_H_ROOT) {
4597 + pr_err("CEETM: a prio ceetm qdisc can not be root\n");
4598 + err = -EINVAL;
4599 + goto err_init_prio;
4600 + }
4601 +
4602 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4603 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4604 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4605 + err = -EINVAL;
4606 + goto err_init_prio;
4607 + }
4608 +
4609 + /* Obtain the parent root ceetm_class */
4610 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4611 +
4612 + if (!parent_cl || parent_cl->type != CEETM_ROOT) {
4613 + pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n");
4614 + err = -EINVAL;
4615 + goto err_init_prio;
4616 + }
4617 +
4618 + priv->prio.parent = parent_cl;
4619 + parent_cl->root.child = sch;
4620 +
4621 + priv->shaped = parent_cl->shaped;
4622 + priv->prio.qcount = qopt->qcount;
4623 +
4624 + /* Create and configure qcount child classes */
4625 + for (i = 0; i < priv->prio.qcount; i++) {
4626 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4627 + if (!child_cl) {
4628 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4629 + __func__);
4630 + err = -ENOMEM;
4631 + goto err_init_prio;
4632 + }
4633 +
4634 + child_cl->prio.cstats = alloc_percpu(struct ceetm_class_stats);
4635 + if (!child_cl->prio.cstats) {
4636 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4637 + __func__);
4638 + err = -ENOMEM;
4639 + goto err_init_prio_cls;
4640 + }
4641 +
4642 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4643 + child_cl->refcnt = 1;
4644 + child_cl->parent = sch;
4645 + child_cl->type = CEETM_PRIO;
4646 + child_cl->shaped = priv->shaped;
4647 + child_cl->prio.child = NULL;
4648 +
4649 + /* All shaped CQs have CR and ER enabled by default */
4650 + child_cl->prio.cr = child_cl->shaped;
4651 + child_cl->prio.er = child_cl->shaped;
4652 + child_cl->prio.fq = NULL;
4653 + child_cl->prio.cq = NULL;
4654 +
4655 + /* Configure the corresponding hardware CQ */
4656 + err = ceetm_config_prio_cls(child_cl, dev,
4657 + parent_cl->root.ch, i);
4658 + if (err) {
4659 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
4660 + __func__, child_cl->common.classid);
4661 + goto err_init_prio_cls;
4662 + }
4663 +
4664 + /* Add class handle in Qdisc */
4665 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
4666 + pr_debug(KBUILD_BASENAME " : %s : added ceetm prio class %X associated with CQ %d and CCG %d\n",
4667 + __func__, child_cl->common.classid,
4668 + child_cl->prio.cq->idx, child_cl->prio.ccg->idx);
4669 + }
4670 +
4671 + return 0;
4672 +
4673 +err_init_prio_cls:
4674 + ceetm_cls_destroy(sch, child_cl);
4675 +err_init_prio:
4676 + ceetm_destroy(sch);
4677 + return err;
4678 +}
4679 +
4680 +/* Configure a wbfs ceetm qdisc */
4681 +static int ceetm_init_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
4682 + struct tc_ceetm_qopt *qopt)
4683 +{
4684 + int err, group_b, small_group;
4685 + unsigned int i, id, prio_a, prio_b;
4686 + struct ceetm_class *parent_cl, *child_cl, *root_cl;
4687 + struct Qdisc *parent_qdisc;
4688 + struct ceetm_qdisc *parent_priv;
4689 + struct qm_ceetm_channel *channel;
4690 + struct net_device *dev = qdisc_dev(sch);
4691 +
4692 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4693 +
4694 + /* Validate inputs */
4695 + if (sch->parent == TC_H_ROOT) {
4696 + pr_err("CEETM: a wbfs ceetm qdiscs can not be root\n");
4697 + err = -EINVAL;
4698 + goto err_init_wbfs;
4699 + }
4700 +
4701 + /* Obtain the parent prio ceetm qdisc */
4702 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4703 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4704 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4705 + err = -EINVAL;
4706 + goto err_init_wbfs;
4707 + }
4708 +
4709 + /* Obtain the parent prio ceetm class */
4710 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4711 + parent_priv = qdisc_priv(parent_qdisc);
4712 +
4713 + if (!parent_cl || parent_cl->type != CEETM_PRIO) {
4714 + pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n");
4715 + err = -EINVAL;
4716 + goto err_init_wbfs;
4717 + }
4718 +
4719 + if (!qopt->qcount || !qopt->qweight[0]) {
4720 + pr_err("CEETM: qcount and qweight are mandatory for a wbfs ceetm qdisc\n");
4721 + err = -EINVAL;
4722 + goto err_init_wbfs;
4723 + }
4724 +
4725 + priv->shaped = parent_cl->shaped;
4726 +
4727 + if (!priv->shaped && (qopt->cr || qopt->er)) {
4728 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
4729 + err = -EINVAL;
4730 + goto err_init_wbfs;
4731 + }
4732 +
4733 + if (priv->shaped && !(qopt->cr || qopt->er)) {
4734 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
4735 + err = -EINVAL;
4736 + goto err_init_wbfs;
4737 + }
4738 +
4739 + /* Obtain the parent root ceetm class */
4740 + root_cl = parent_priv->prio.parent;
4741 + if ((root_cl->root.wbfs_grp_a && root_cl->root.wbfs_grp_b) ||
4742 + root_cl->root.wbfs_grp_large) {
4743 + pr_err("CEETM: no more wbfs classes are available\n");
4744 + err = -EINVAL;
4745 + goto err_init_wbfs;
4746 + }
4747 +
4748 + if ((root_cl->root.wbfs_grp_a || root_cl->root.wbfs_grp_b) &&
4749 + qopt->qcount == CEETM_MAX_WBFS_QCOUNT) {
4750 + pr_err("CEETM: only %d wbfs classes are available\n",
4751 + CEETM_MIN_WBFS_QCOUNT);
4752 + err = -EINVAL;
4753 + goto err_init_wbfs;
4754 + }
4755 +
4756 + priv->wbfs.parent = parent_cl;
4757 + parent_cl->prio.child = sch;
4758 +
4759 + priv->wbfs.qcount = qopt->qcount;
4760 + priv->wbfs.cr = qopt->cr;
4761 + priv->wbfs.er = qopt->er;
4762 +
4763 + channel = root_cl->root.ch;
4764 +
4765 + /* Configure the hardware wbfs channel groups */
4766 + if (priv->wbfs.qcount == CEETM_MAX_WBFS_QCOUNT) {
4767 + /* Configure the large group A */
4768 + priv->wbfs.group_type = WBFS_GRP_LARGE;
4769 + small_group = false;
4770 + group_b = false;
4771 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4772 + prio_b = prio_a;
4773 +
4774 + } else if (root_cl->root.wbfs_grp_a) {
4775 + /* Configure the group B */
4776 + priv->wbfs.group_type = WBFS_GRP_B;
4777 +
4778 + err = qman_ceetm_channel_get_group(channel, &small_group,
4779 + &prio_a, &prio_b);
4780 + if (err) {
4781 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4782 + __func__);
4783 + goto err_init_wbfs;
4784 + }
4785 +
4786 + small_group = true;
4787 + group_b = true;
4788 + prio_b = TC_H_MIN(parent_cl->common.classid) - 1;
4789 + /* If group A isn't configured, configure it as group B */
4790 + prio_a = prio_a ? : prio_b;
4791 +
4792 + } else {
4793 + /* Configure the small group A */
4794 + priv->wbfs.group_type = WBFS_GRP_A;
4795 +
4796 + err = qman_ceetm_channel_get_group(channel, &small_group,
4797 + &prio_a, &prio_b);
4798 + if (err) {
4799 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4800 + __func__);
4801 + goto err_init_wbfs;
4802 + }
4803 +
4804 + small_group = true;
4805 + group_b = false;
4806 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4807 + /* If group B isn't configured, configure it as group A */
4808 + prio_b = prio_b ? : prio_a;
4809 + }
4810 +
4811 + err = qman_ceetm_channel_set_group(channel, small_group, prio_a,
4812 + prio_b);
4813 + if (err)
4814 + goto err_init_wbfs;
4815 +
4816 + if (priv->shaped) {
4817 + err = qman_ceetm_channel_set_group_cr_eligibility(channel,
4818 + group_b,
4819 + priv->wbfs.cr);
4820 + if (err) {
4821 + pr_err(KBUILD_BASENAME " : %s : failed to set group CR eligibility\n",
4822 + __func__);
4823 + goto err_init_wbfs;
4824 + }
4825 +
4826 + err = qman_ceetm_channel_set_group_er_eligibility(channel,
4827 + group_b,
4828 + priv->wbfs.er);
4829 + if (err) {
4830 + pr_err(KBUILD_BASENAME " : %s : failed to set group ER eligibility\n",
4831 + __func__);
4832 + goto err_init_wbfs;
4833 + }
4834 + }
4835 +
4836 + /* Create qcount child classes */
4837 + for (i = 0; i < priv->wbfs.qcount; i++) {
4838 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4839 + if (!child_cl) {
4840 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4841 + __func__);
4842 + err = -ENOMEM;
4843 + goto err_init_wbfs;
4844 + }
4845 +
4846 + child_cl->wbfs.cstats = alloc_percpu(struct ceetm_class_stats);
4847 + if (!child_cl->wbfs.cstats) {
4848 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4849 + __func__);
4850 + err = -ENOMEM;
4851 + goto err_init_wbfs_cls;
4852 + }
4853 +
4854 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4855 + child_cl->refcnt = 1;
4856 + child_cl->parent = sch;
4857 + child_cl->type = CEETM_WBFS;
4858 + child_cl->shaped = priv->shaped;
4859 + child_cl->wbfs.fq = NULL;
4860 + child_cl->wbfs.cq = NULL;
4861 + child_cl->wbfs.weight = qopt->qweight[i];
4862 +
4863 + if (priv->wbfs.group_type == WBFS_GRP_B)
4864 + id = WBFS_GRP_B_OFFSET + i;
4865 + else
4866 + id = WBFS_GRP_A_OFFSET + i;
4867 +
4868 + err = ceetm_config_wbfs_cls(child_cl, dev, channel, id,
4869 + priv->wbfs.group_type);
4870 + if (err) {
4871 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
4872 + __func__, child_cl->common.classid);
4873 + goto err_init_wbfs_cls;
4874 + }
4875 +
4876 + /* Add class handle in Qdisc */
4877 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
4878 + pr_debug(KBUILD_BASENAME " : %s : added ceetm wbfs class %X associated with CQ %d and CCG %d\n",
4879 + __func__, child_cl->common.classid,
4880 + child_cl->wbfs.cq->idx, child_cl->wbfs.ccg->idx);
4881 + }
4882 +
4883 + /* Signal the root class that a group has been configured */
4884 + switch (priv->wbfs.group_type) {
4885 + case WBFS_GRP_LARGE:
4886 + root_cl->root.wbfs_grp_large = true;
4887 + break;
4888 + case WBFS_GRP_A:
4889 + root_cl->root.wbfs_grp_a = true;
4890 + break;
4891 + case WBFS_GRP_B:
4892 + root_cl->root.wbfs_grp_b = true;
4893 + break;
4894 + }
4895 +
4896 + return 0;
4897 +
4898 +err_init_wbfs_cls:
4899 + ceetm_cls_destroy(sch, child_cl);
4900 +err_init_wbfs:
4901 + ceetm_destroy(sch);
4902 + return err;
4903 +}
4904 +
4905 +/* Configure a generic ceetm qdisc */
4906 +static int ceetm_init(struct Qdisc *sch, struct nlattr *opt)
4907 +{
4908 + struct tc_ceetm_qopt *qopt;
4909 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
4910 + int ret;
4911 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4912 + struct net_device *dev = qdisc_dev(sch);
4913 +
4914 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4915 +
4916 + if (!netif_is_multiqueue(dev))
4917 + return -EOPNOTSUPP;
4918 +
4919 + if (!opt) {
4920 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4921 + return -EINVAL;
4922 + }
4923 +
4924 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
4925 + if (ret < 0) {
4926 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4927 + return ret;
4928 + }
4929 +
4930 + if (!tb[TCA_CEETM_QOPS]) {
4931 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4932 + return -EINVAL;
4933 + }
4934 +
4935 + if (TC_H_MIN(sch->handle)) {
4936 + pr_err("CEETM: a qdisc should not have a minor\n");
4937 + return -EINVAL;
4938 + }
4939 +
4940 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
4941 +
4942 + /* Initialize the class hash list. Each qdisc has its own class hash */
4943 + ret = qdisc_class_hash_init(&priv->clhash);
4944 + if (ret < 0) {
4945 + pr_err(KBUILD_BASENAME " : %s : qdisc_class_hash_init failed\n",
4946 + __func__);
4947 + return ret;
4948 + }
4949 +
4950 + priv->type = qopt->type;
4951 +
4952 + switch (priv->type) {
4953 + case CEETM_ROOT:
4954 + ret = ceetm_init_root(sch, priv, qopt);
4955 + break;
4956 + case CEETM_PRIO:
4957 + ret = ceetm_init_prio(sch, priv, qopt);
4958 + break;
4959 + case CEETM_WBFS:
4960 + ret = ceetm_init_wbfs(sch, priv, qopt);
4961 + break;
4962 + default:
4963 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
4964 + ceetm_destroy(sch);
4965 + ret = -EINVAL;
4966 + }
4967 +
4968 + return ret;
4969 +}
4970 +
4971 +/* Edit a root ceetm qdisc */
4972 +static int ceetm_change_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
4973 + struct net_device *dev,
4974 + struct tc_ceetm_qopt *qopt)
4975 +{
4976 + int err = 0;
4977 + u64 bps;
4978 +
4979 + if (priv->shaped != (bool)qopt->shaped) {
4980 + pr_err("CEETM: qdisc %X is %s\n", sch->handle,
4981 + priv->shaped ? "shaped" : "unshaped");
4982 + return -EINVAL;
4983 + }
4984 +
4985 + /* Nothing to modify for unshaped qdiscs */
4986 + if (!priv->shaped)
4987 + return 0;
4988 +
4989 + /* Configure the LNI shaper */
4990 + if (priv->root.overhead != qopt->overhead) {
4991 + err = qman_ceetm_lni_enable_shaper(priv->root.lni, 1,
4992 + qopt->overhead);
4993 + if (err)
4994 + goto change_err;
4995 + priv->root.overhead = qopt->overhead;
4996 + }
4997 +
4998 + if (priv->root.rate != qopt->rate) {
4999 + bps = qopt->rate << 3; /* Bps -> bps */
5000 + err = qman_ceetm_lni_set_commit_rate_bps(priv->root.lni, bps,
5001 + dev->mtu);
5002 + if (err)
5003 + goto change_err;
5004 + priv->root.rate = qopt->rate;
5005 + }
5006 +
5007 + if (priv->root.ceil != qopt->ceil) {
5008 + bps = qopt->ceil << 3; /* Bps -> bps */
5009 + err = qman_ceetm_lni_set_excess_rate_bps(priv->root.lni, bps,
5010 + dev->mtu);
5011 + if (err)
5012 + goto change_err;
5013 + priv->root.ceil = qopt->ceil;
5014 + }
5015 +
5016 + return 0;
5017 +
5018 +change_err:
5019 + pr_err(KBUILD_BASENAME " : %s : failed to configure the root ceetm qdisc %X\n",
5020 + __func__, sch->handle);
5021 + return err;
5022 +}
5023 +
5024 +/* Edit a wbfs ceetm qdisc */
5025 +static int ceetm_change_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
5026 + struct tc_ceetm_qopt *qopt)
5027 +{
5028 + int err;
5029 + bool group_b;
5030 + struct qm_ceetm_channel *channel;
5031 + struct ceetm_class *prio_class, *root_class;
5032 + struct ceetm_qdisc *prio_qdisc;
5033 +
5034 + if (qopt->qcount) {
5035 + pr_err("CEETM: the qcount can not be modified\n");
5036 + return -EINVAL;
5037 + }
5038 +
5039 + if (qopt->qweight[0]) {
5040 + pr_err("CEETM: the qweight can be modified through the wbfs classes\n");
5041 + return -EINVAL;
5042 + }
5043 +
5044 + if (!priv->shaped && (qopt->cr || qopt->er)) {
5045 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
5046 + return -EINVAL;
5047 + }
5048 +
5049 + if (priv->shaped && !(qopt->cr || qopt->er)) {
5050 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
5051 + return -EINVAL;
5052 + }
5053 +
5054 + /* Nothing to modify for unshaped qdiscs */
5055 + if (!priv->shaped)
5056 + return 0;
5057 +
5058 + prio_class = priv->wbfs.parent;
5059 + prio_qdisc = qdisc_priv(prio_class->parent);
5060 + root_class = prio_qdisc->prio.parent;
5061 + channel = root_class->root.ch;
5062 + group_b = priv->wbfs.group_type == WBFS_GRP_B;
5063 +
5064 + if (qopt->cr != priv->wbfs.cr) {
5065 + err = qman_ceetm_channel_set_group_cr_eligibility(channel,
5066 + group_b,
5067 + qopt->cr);
5068 + if (err)
5069 + goto change_err;
5070 + priv->wbfs.cr = qopt->cr;
5071 + }
5072 +
5073 + if (qopt->er != priv->wbfs.er) {
5074 + err = qman_ceetm_channel_set_group_er_eligibility(channel,
5075 + group_b,
5076 + qopt->er);
5077 + if (err)
5078 + goto change_err;
5079 + priv->wbfs.er = qopt->er;
5080 + }
5081 +
5082 + return 0;
5083 +
5084 +change_err:
5085 + pr_err(KBUILD_BASENAME " : %s : failed to configure the wbfs ceetm qdisc %X\n",
5086 + __func__, sch->handle);
5087 + return err;
5088 +}
5089 +
5090 +/* Edit a ceetm qdisc */
5091 +static int ceetm_change(struct Qdisc *sch, struct nlattr *opt)
5092 +{
5093 + struct tc_ceetm_qopt *qopt;
5094 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
5095 + int ret;
5096 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5097 + struct net_device *dev = qdisc_dev(sch);
5098 +
5099 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5100 +
5101 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
5102 + if (ret < 0) {
5103 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5104 + return ret;
5105 + }
5106 +
5107 + if (!tb[TCA_CEETM_QOPS]) {
5108 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5109 + return -EINVAL;
5110 + }
5111 +
5112 + if (TC_H_MIN(sch->handle)) {
5113 + pr_err("CEETM: a qdisc should not have a minor\n");
5114 + return -EINVAL;
5115 + }
5116 +
5117 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
5118 +
5119 + if (priv->type != qopt->type) {
5120 + pr_err("CEETM: qdisc %X is not of the provided type\n",
5121 + sch->handle);
5122 + return -EINVAL;
5123 + }
5124 +
5125 + switch (priv->type) {
5126 + case CEETM_ROOT:
5127 + ret = ceetm_change_root(sch, priv, dev, qopt);
5128 + break;
5129 + case CEETM_PRIO:
5130 + pr_err("CEETM: prio qdiscs can not be modified\n");
5131 + ret = -EINVAL;
5132 + break;
5133 + case CEETM_WBFS:
5134 + ret = ceetm_change_wbfs(sch, priv, qopt);
5135 + break;
5136 + default:
5137 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
5138 + ret = -EINVAL;
5139 + }
5140 +
5141 + return ret;
5142 +}
5143 +
5144 +/* Attach the underlying pfifo qdiscs */
5145 +static void ceetm_attach(struct Qdisc *sch)
5146 +{
5147 + struct net_device *dev = qdisc_dev(sch);
5148 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5149 + struct Qdisc *qdisc, *old_qdisc;
5150 + unsigned int i;
5151 +
5152 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5153 +
5154 + for (i = 0; i < dev->num_tx_queues; i++) {
5155 + qdisc = priv->root.qdiscs[i];
5156 + old_qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc);
5157 + if (old_qdisc)
5158 + qdisc_destroy(old_qdisc);
5159 + }
5160 +}
5161 +
5162 +static unsigned long ceetm_cls_get(struct Qdisc *sch, u32 classid)
5163 +{
5164 + struct ceetm_class *cl;
5165 +
5166 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5167 + __func__, classid, sch->handle);
5168 + cl = ceetm_find(classid, sch);
5169 +
5170 + if (cl)
5171 + cl->refcnt++; /* Will decrement in put() */
5172 + return (unsigned long)cl;
5173 +}
5174 +
5175 +static void ceetm_cls_put(struct Qdisc *sch, unsigned long arg)
5176 +{
5177 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5178 +
5179 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5180 + __func__, cl->common.classid, sch->handle);
5181 + cl->refcnt--;
5182 +
5183 + if (cl->refcnt == 0)
5184 + ceetm_cls_destroy(sch, cl);
5185 +}
5186 +
5187 +static int ceetm_cls_change_root(struct ceetm_class *cl,
5188 + struct tc_ceetm_copt *copt,
5189 + struct net_device *dev)
5190 +{
5191 + int err;
5192 + u64 bps;
5193 +
5194 + if ((bool)copt->shaped != cl->shaped) {
5195 + pr_err("CEETM: class %X is %s\n", cl->common.classid,
5196 + cl->shaped ? "shaped" : "unshaped");
5197 + return -EINVAL;
5198 + }
5199 +
5200 + if (cl->shaped && cl->root.rate != copt->rate) {
5201 + bps = copt->rate << 3; /* Bps -> bps */
5202 + err = qman_ceetm_channel_set_commit_rate_bps(cl->root.ch, bps,
5203 + dev->mtu);
5204 + if (err)
5205 + goto change_cls_err;
5206 + cl->root.rate = copt->rate;
5207 + }
5208 +
5209 + if (cl->shaped && cl->root.ceil != copt->ceil) {
5210 + bps = copt->ceil << 3; /* Bps -> bps */
5211 + err = qman_ceetm_channel_set_excess_rate_bps(cl->root.ch, bps,
5212 + dev->mtu);
5213 + if (err)
5214 + goto change_cls_err;
5215 + cl->root.ceil = copt->ceil;
5216 + }
5217 +
5218 + if (!cl->shaped && cl->root.tbl != copt->tbl) {
5219 + err = qman_ceetm_channel_set_weight(cl->root.ch, copt->tbl);
5220 + if (err)
5221 + goto change_cls_err;
5222 + cl->root.tbl = copt->tbl;
5223 + }
5224 +
5225 + return 0;
5226 +
5227 +change_cls_err:
5228 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm root class %X\n",
5229 + __func__, cl->common.classid);
5230 + return err;
5231 +}
5232 +
5233 +static int ceetm_cls_change_prio(struct ceetm_class *cl,
5234 + struct tc_ceetm_copt *copt)
5235 +{
5236 + int err;
5237 +
5238 + if (!cl->shaped && (copt->cr || copt->er)) {
5239 + pr_err("CEETM: only shaped classes can have CR and ER enabled\n");
5240 + return -EINVAL;
5241 + }
5242 +
5243 + if (cl->prio.cr != (bool)copt->cr) {
5244 + err = qman_ceetm_channel_set_cq_cr_eligibility(
5245 + cl->prio.cq->parent,
5246 + cl->prio.cq->idx,
5247 + copt->cr);
5248 + if (err)
5249 + goto change_cls_err;
5250 + cl->prio.cr = copt->cr;
5251 + }
5252 +
5253 + if (cl->prio.er != (bool)copt->er) {
5254 + err = qman_ceetm_channel_set_cq_er_eligibility(
5255 + cl->prio.cq->parent,
5256 + cl->prio.cq->idx,
5257 + copt->er);
5258 + if (err)
5259 + goto change_cls_err;
5260 + cl->prio.er = copt->er;
5261 + }
5262 +
5263 + return 0;
5264 +
5265 +change_cls_err:
5266 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
5267 + __func__, cl->common.classid);
5268 + return err;
5269 +}
5270 +
5271 +static int ceetm_cls_change_wbfs(struct ceetm_class *cl,
5272 + struct tc_ceetm_copt *copt)
5273 +{
5274 + int err;
5275 +
5276 + if (copt->weight != cl->wbfs.weight) {
5277 + /* Configure the CQ weight: real number multiplied by 100 to
5278 + * get rid of the fraction
5279 + */
5280 + err = qman_ceetm_set_queue_weight_in_ratio(cl->wbfs.cq,
5281 + copt->weight * 100);
5282 +
5283 + if (err) {
5284 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
5285 + __func__, cl->common.classid);
5286 + return err;
5287 + }
5288 +
5289 + cl->wbfs.weight = copt->weight;
5290 + }
5291 +
5292 + return 0;
5293 +}
5294 +
5295 +/* Add a ceetm root class or configure a ceetm root/prio/wbfs class */
5296 +static int ceetm_cls_change(struct Qdisc *sch, u32 classid, u32 parentid,
5297 + struct nlattr **tca, unsigned long *arg)
5298 +{
5299 + int err;
5300 + u64 bps;
5301 + struct ceetm_qdisc *priv;
5302 + struct ceetm_class *cl = (struct ceetm_class *)*arg;
5303 + struct nlattr *opt = tca[TCA_OPTIONS];
5304 + struct nlattr *tb[__TCA_CEETM_MAX];
5305 + struct tc_ceetm_copt *copt;
5306 + struct qm_ceetm_channel *channel;
5307 + struct net_device *dev = qdisc_dev(sch);
5308 +
5309 + pr_debug(KBUILD_BASENAME " : %s : classid %X under qdisc %X\n",
5310 + __func__, classid, sch->handle);
5311 +
5312 + if (strcmp(sch->ops->id, ceetm_qdisc_ops.id)) {
5313 + pr_err("CEETM: a ceetm class can not be attached to other qdisc/class types\n");
5314 + return -EINVAL;
5315 + }
5316 +
5317 + priv = qdisc_priv(sch);
5318 +
5319 + if (!opt) {
5320 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5321 + return -EINVAL;
5322 + }
5323 +
5324 + if (!cl && sch->handle != parentid) {
5325 + pr_err("CEETM: classes can be attached to the root ceetm qdisc only\n");
5326 + return -EINVAL;
5327 + }
5328 +
5329 + if (!cl && priv->type != CEETM_ROOT) {
5330 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5331 + return -EINVAL;
5332 + }
5333 +
5334 + err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy);
5335 + if (err < 0) {
5336 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5337 + return -EINVAL;
5338 + }
5339 +
5340 + if (!tb[TCA_CEETM_COPT]) {
5341 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5342 + return -EINVAL;
5343 + }
5344 +
5345 + if (TC_H_MIN(classid) >= PFIFO_MIN_OFFSET) {
5346 + pr_err("CEETM: only minors 0x01 to 0x20 can be used for ceetm root classes\n");
5347 + return -EINVAL;
5348 + }
5349 +
5350 + copt = nla_data(tb[TCA_CEETM_COPT]);
5351 +
5352 + /* Configure an existing ceetm class */
5353 + if (cl) {
5354 + if (copt->type != cl->type) {
5355 + pr_err("CEETM: class %X is not of the provided type\n",
5356 + cl->common.classid);
5357 + return -EINVAL;
5358 + }
5359 +
5360 + switch (copt->type) {
5361 + case CEETM_ROOT:
5362 + return ceetm_cls_change_root(cl, copt, dev);
5363 +
5364 + case CEETM_PRIO:
5365 + return ceetm_cls_change_prio(cl, copt);
5366 +
5367 + case CEETM_WBFS:
5368 + return ceetm_cls_change_wbfs(cl, copt);
5369 +
5370 + default:
5371 + pr_err(KBUILD_BASENAME " : %s : invalid class\n",
5372 + __func__);
5373 + return -EINVAL;
5374 + }
5375 + }
5376 +
5377 + /* Add a new root ceetm class */
5378 + if (copt->type != CEETM_ROOT) {
5379 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5380 + return -EINVAL;
5381 + }
5382 +
5383 + if (copt->shaped && !priv->shaped) {
5384 + pr_err("CEETM: can not add a shaped ceetm root class under an unshaped ceetm root qdisc\n");
5385 + return -EINVAL;
5386 + }
5387 +
5388 + cl = kzalloc(sizeof(*cl), GFP_KERNEL);
5389 + if (!cl)
5390 + return -ENOMEM;
5391 +
5392 + cl->type = copt->type;
5393 + cl->shaped = copt->shaped;
5394 + cl->root.rate = copt->rate;
5395 + cl->root.ceil = copt->ceil;
5396 + cl->root.tbl = copt->tbl;
5397 +
5398 + cl->common.classid = classid;
5399 + cl->refcnt = 1;
5400 + cl->parent = sch;
5401 + cl->root.child = NULL;
5402 + cl->root.wbfs_grp_a = false;
5403 + cl->root.wbfs_grp_b = false;
5404 + cl->root.wbfs_grp_large = false;
5405 +
5406 + /* Claim a CEETM channel */
5407 + err = qman_ceetm_channel_claim(&channel, priv->root.lni);
5408 + if (err) {
5409 + pr_err(KBUILD_BASENAME " : %s : failed to claim a channel\n",
5410 + __func__);
5411 + goto claim_err;
5412 + }
5413 +
5414 + cl->root.ch = channel;
5415 +
5416 + if (cl->shaped) {
5417 + /* Configure the channel shaper */
5418 + err = qman_ceetm_channel_enable_shaper(channel, 1);
5419 + if (err)
5420 + goto channel_err;
5421 +
5422 + bps = cl->root.rate << 3; /* Bps -> bps */
5423 + err = qman_ceetm_channel_set_commit_rate_bps(channel, bps,
5424 + dev->mtu);
5425 + if (err)
5426 + goto channel_err;
5427 +
5428 + bps = cl->root.ceil << 3; /* Bps -> bps */
5429 + err = qman_ceetm_channel_set_excess_rate_bps(channel, bps,
5430 + dev->mtu);
5431 + if (err)
5432 + goto channel_err;
5433 +
5434 + } else {
5435 + /* Configure the uFQ algorithm */
5436 + err = qman_ceetm_channel_set_weight(channel, cl->root.tbl);
5437 + if (err)
5438 + goto channel_err;
5439 + }
5440 +
5441 + /* Add class handle in Qdisc */
5442 + ceetm_link_class(sch, &priv->clhash, &cl->common);
5443 +
5444 + pr_debug(KBUILD_BASENAME " : %s : configured class %X associated with channel %d\n",
5445 + __func__, classid, channel->idx);
5446 + *arg = (unsigned long)cl;
5447 + return 0;
5448 +
5449 +channel_err:
5450 + pr_err(KBUILD_BASENAME " : %s : failed to configure the channel %d\n",
5451 + __func__, channel->idx);
5452 + if (qman_ceetm_channel_release(channel))
5453 + pr_err(KBUILD_BASENAME " : %s : failed to release the channel %d\n",
5454 + __func__, channel->idx);
5455 +claim_err:
5456 + kfree(cl);
5457 + return err;
5458 +}
5459 +
5460 +static void ceetm_cls_walk(struct Qdisc *sch, struct qdisc_walker *arg)
5461 +{
5462 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5463 + struct ceetm_class *cl;
5464 + unsigned int i;
5465 +
5466 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5467 +
5468 + if (arg->stop)
5469 + return;
5470 +
5471 + for (i = 0; i < priv->clhash.hashsize; i++) {
5472 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) {
5473 + if (arg->count < arg->skip) {
5474 + arg->count++;
5475 + continue;
5476 + }
5477 + if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
5478 + arg->stop = 1;
5479 + return;
5480 + }
5481 + arg->count++;
5482 + }
5483 + }
5484 +}
5485 +
5486 +static int ceetm_cls_dump(struct Qdisc *sch, unsigned long arg,
5487 + struct sk_buff *skb, struct tcmsg *tcm)
5488 +{
5489 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5490 + struct nlattr *nest;
5491 + struct tc_ceetm_copt copt;
5492 +
5493 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5494 + __func__, cl->common.classid, sch->handle);
5495 +
5496 + sch_tree_lock(sch);
5497 +
5498 + tcm->tcm_parent = ((struct Qdisc *)cl->parent)->handle;
5499 + tcm->tcm_handle = cl->common.classid;
5500 +
5501 + memset(&copt, 0, sizeof(copt));
5502 +
5503 + copt.shaped = cl->shaped;
5504 + copt.type = cl->type;
5505 +
5506 + switch (cl->type) {
5507 + case CEETM_ROOT:
5508 + if (cl->root.child)
5509 + tcm->tcm_info = cl->root.child->handle;
5510 +
5511 + copt.rate = cl->root.rate;
5512 + copt.ceil = cl->root.ceil;
5513 + copt.tbl = cl->root.tbl;
5514 + break;
5515 +
5516 + case CEETM_PRIO:
5517 + if (cl->prio.child)
5518 + tcm->tcm_info = cl->prio.child->handle;
5519 +
5520 + copt.cr = cl->prio.cr;
5521 + copt.er = cl->prio.er;
5522 + break;
5523 +
5524 + case CEETM_WBFS:
5525 + copt.weight = cl->wbfs.weight;
5526 + break;
5527 + }
5528 +
5529 + nest = nla_nest_start(skb, TCA_OPTIONS);
5530 + if (!nest)
5531 + goto nla_put_failure;
5532 + if (nla_put(skb, TCA_CEETM_COPT, sizeof(copt), &copt))
5533 + goto nla_put_failure;
5534 + nla_nest_end(skb, nest);
5535 + sch_tree_unlock(sch);
5536 + return skb->len;
5537 +
5538 +nla_put_failure:
5539 + sch_tree_unlock(sch);
5540 + nla_nest_cancel(skb, nest);
5541 + return -EMSGSIZE;
5542 +}
5543 +
5544 +static int ceetm_cls_delete(struct Qdisc *sch, unsigned long arg)
5545 +{
5546 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5547 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5548 +
5549 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5550 + __func__, cl->common.classid, sch->handle);
5551 +
5552 + sch_tree_lock(sch);
5553 + qdisc_class_hash_remove(&priv->clhash, &cl->common);
5554 + cl->refcnt--;
5555 +
5556 + /* The refcnt should be at least 1 since we have incremented it in
5557 + * get(). Will decrement again in put() where we will call destroy()
5558 + * to actually free the memory if it reaches 0.
5559 + */
5560 + WARN_ON(cl->refcnt == 0);
5561 +
5562 + sch_tree_unlock(sch);
5563 + return 0;
5564 +}
5565 +
5566 +/* Get the class' child qdisc, if any */
5567 +static struct Qdisc *ceetm_cls_leaf(struct Qdisc *sch, unsigned long arg)
5568 +{
5569 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5570 +
5571 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5572 + __func__, cl->common.classid, sch->handle);
5573 +
5574 + switch (cl->type) {
5575 + case CEETM_ROOT:
5576 + return cl->root.child;
5577 +
5578 + case CEETM_PRIO:
5579 + return cl->prio.child;
5580 + }
5581 +
5582 + return NULL;
5583 +}
5584 +
5585 +static int ceetm_cls_graft(struct Qdisc *sch, unsigned long arg,
5586 + struct Qdisc *new, struct Qdisc **old)
5587 +{
5588 + if (new && strcmp(new->ops->id, ceetm_qdisc_ops.id)) {
5589 + pr_err("CEETM: only ceetm qdiscs can be attached to ceetm classes\n");
5590 + return -EOPNOTSUPP;
5591 + }
5592 +
5593 + return 0;
5594 +}
5595 +
5596 +static int ceetm_cls_dump_stats(struct Qdisc *sch, unsigned long arg,
5597 + struct gnet_dump *d)
5598 +{
5599 + unsigned int i;
5600 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5601 + struct gnet_stats_basic_packed tmp_bstats;
5602 + struct ceetm_class_stats *cstats = NULL;
5603 + struct qm_ceetm_cq *cq = NULL;
5604 + struct tc_ceetm_xstats xstats;
5605 +
5606 + memset(&xstats, 0, sizeof(xstats));
5607 + memset(&tmp_bstats, 0, sizeof(tmp_bstats));
5608 +
5609 + switch (cl->type) {
5610 + case CEETM_ROOT:
5611 + return 0;
5612 + case CEETM_PRIO:
5613 + cq = cl->prio.cq;
5614 + break;
5615 + case CEETM_WBFS:
5616 + cq = cl->wbfs.cq;
5617 + break;
5618 + }
5619 +
5620 + for_each_online_cpu(i) {
5621 + switch (cl->type) {
5622 + case CEETM_PRIO:
5623 + cstats = per_cpu_ptr(cl->prio.cstats, i);
5624 + break;
5625 + case CEETM_WBFS:
5626 + cstats = per_cpu_ptr(cl->wbfs.cstats, i);
5627 + break;
5628 + }
5629 +
5630 + if (cstats) {
5631 + xstats.ern_drop_count += cstats->ern_drop_count;
5632 + xstats.congested_count += cstats->congested_count;
5633 + tmp_bstats.bytes += cstats->bstats.bytes;
5634 + tmp_bstats.packets += cstats->bstats.packets;
5635 + }
5636 + }
5637 +
5638 + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
5639 + d, NULL, &tmp_bstats) < 0)
5640 + return -1;
5641 +
5642 + if (cq && qman_ceetm_cq_get_dequeue_statistics(cq, 0,
5643 + &xstats.frame_count,
5644 + &xstats.byte_count))
5645 + return -1;
5646 +
5647 + return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
5648 +}
5649 +
5650 +static struct tcf_proto **ceetm_tcf_chain(struct Qdisc *sch, unsigned long arg)
5651 +{
5652 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5653 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5654 + struct tcf_proto **fl = cl ? &cl->filter_list : &priv->filter_list;
5655 +
5656 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5657 + cl ? cl->common.classid : 0, sch->handle);
5658 + return fl;
5659 +}
5660 +
5661 +static unsigned long ceetm_tcf_bind(struct Qdisc *sch, unsigned long parent,
5662 + u32 classid)
5663 +{
5664 + struct ceetm_class *cl = ceetm_find(classid, sch);
5665 +
5666 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5667 + cl ? cl->common.classid : 0, sch->handle);
5668 + return (unsigned long)cl;
5669 +}
5670 +
5671 +static void ceetm_tcf_unbind(struct Qdisc *sch, unsigned long arg)
5672 +{
5673 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5674 +
5675 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5676 + cl ? cl->common.classid : 0, sch->handle);
5677 +}
5678 +
5679 +const struct Qdisc_class_ops ceetm_cls_ops = {
5680 + .graft = ceetm_cls_graft,
5681 + .leaf = ceetm_cls_leaf,
5682 + .get = ceetm_cls_get,
5683 + .put = ceetm_cls_put,
5684 + .change = ceetm_cls_change,
5685 + .delete = ceetm_cls_delete,
5686 + .walk = ceetm_cls_walk,
5687 + .tcf_chain = ceetm_tcf_chain,
5688 + .bind_tcf = ceetm_tcf_bind,
5689 + .unbind_tcf = ceetm_tcf_unbind,
5690 + .dump = ceetm_cls_dump,
5691 + .dump_stats = ceetm_cls_dump_stats,
5692 +};
5693 +
5694 +struct Qdisc_ops ceetm_qdisc_ops __read_mostly = {
5695 + .id = "ceetm",
5696 + .priv_size = sizeof(struct ceetm_qdisc),
5697 + .cl_ops = &ceetm_cls_ops,
5698 + .init = ceetm_init,
5699 + .destroy = ceetm_destroy,
5700 + .change = ceetm_change,
5701 + .dump = ceetm_dump,
5702 + .attach = ceetm_attach,
5703 + .owner = THIS_MODULE,
5704 +};
5705 +
5706 +/* Run the filters and classifiers attached to the qdisc on the provided skb */
5707 +static struct ceetm_class *ceetm_classify(struct sk_buff *skb,
5708 + struct Qdisc *sch, int *qerr,
5709 + bool *act_drop)
5710 +{
5711 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5712 + struct ceetm_class *cl = NULL, *wbfs_cl;
5713 + struct tcf_result res;
5714 + struct tcf_proto *tcf;
5715 + int result;
5716 +
5717 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
5718 + tcf = priv->filter_list;
5719 + while (tcf && (result = tc_classify(skb, tcf, &res, false)) >= 0) {
5720 +#ifdef CONFIG_NET_CLS_ACT
5721 + switch (result) {
5722 + case TC_ACT_QUEUED:
5723 + case TC_ACT_STOLEN:
5724 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
5725 + case TC_ACT_SHOT:
5726 + /* No valid class found due to action */
5727 + *act_drop = true;
5728 + return NULL;
5729 + }
5730 +#endif
5731 + cl = (void *)res.class;
5732 + if (!cl) {
5733 + if (res.classid == sch->handle) {
5734 + /* The filter leads to the qdisc */
5735 + /* TODO default qdisc */
5736 + return NULL;
5737 + }
5738 +
5739 + cl = ceetm_find(res.classid, sch);
5740 + if (!cl)
5741 + /* The filter leads to an invalid class */
5742 + break;
5743 + }
5744 +
5745 + /* The class might have its own filters attached */
5746 + tcf = cl->filter_list;
5747 + }
5748 +
5749 + if (!cl) {
5750 + /* No valid class found */
5751 + /* TODO default qdisc */
5752 + return NULL;
5753 + }
5754 +
5755 + switch (cl->type) {
5756 + case CEETM_ROOT:
5757 + if (cl->root.child) {
5758 + /* Run the prio qdisc classifiers */
5759 + return ceetm_classify(skb, cl->root.child, qerr,
5760 + act_drop);
5761 + } else {
5762 + /* The root class does not have a child prio qdisc */
5763 + /* TODO default qdisc */
5764 + return NULL;
5765 + }
5766 + case CEETM_PRIO:
5767 + if (cl->prio.child) {
5768 + /* If filters lead to a wbfs class, return it.
5769 + * Otherwise, return the prio class
5770 + */
5771 + wbfs_cl = ceetm_classify(skb, cl->prio.child, qerr,
5772 + act_drop);
5773 + /* A NULL result might indicate either an erroneous
5774 + * filter, or no filters at all. We will assume the
5775 + * latter
5776 + */
5777 + return wbfs_cl ? : cl;
5778 + }
5779 + }
5780 +
5781 + /* For wbfs and childless prio classes, return the class directly */
5782 + return cl;
5783 +}
5784 +
5785 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev)
5786 +{
5787 + int ret;
5788 + bool act_drop = false;
5789 + struct Qdisc *sch = net_dev->qdisc;
5790 + struct ceetm_class *cl;
5791 + struct dpa_priv_s *priv_dpa;
5792 + struct qman_fq *egress_fq, *conf_fq;
5793 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5794 + struct ceetm_qdisc_stats *qstats = this_cpu_ptr(priv->root.qstats);
5795 + struct ceetm_class_stats *cstats;
5796 + const int queue_mapping = dpa_get_queue_mapping(skb);
5797 + spinlock_t *root_lock = qdisc_lock(sch);
5798 +
5799 + spin_lock(root_lock);
5800 + cl = ceetm_classify(skb, sch, &ret, &act_drop);
5801 + spin_unlock(root_lock);
5802 +
5803 +#ifdef CONFIG_NET_CLS_ACT
5804 + if (act_drop) {
5805 + if (ret & __NET_XMIT_BYPASS)
5806 + qstats->drops++;
5807 + goto drop;
5808 + }
5809 +#endif
5810 + /* TODO default class */
5811 + if (unlikely(!cl)) {
5812 + qstats->drops++;
5813 + goto drop;
5814 + }
5815 +
5816 + priv_dpa = netdev_priv(net_dev);
5817 + conf_fq = priv_dpa->conf_fqs[queue_mapping];
5818 +
5819 + /* Choose the proper tx fq and update the basic stats (bytes and
5820 + * packets sent by the class)
5821 + */
5822 + switch (cl->type) {
5823 + case CEETM_PRIO:
5824 + egress_fq = &cl->prio.fq->fq;
5825 + cstats = this_cpu_ptr(cl->prio.cstats);
5826 + break;
5827 + case CEETM_WBFS:
5828 + egress_fq = &cl->wbfs.fq->fq;
5829 + cstats = this_cpu_ptr(cl->wbfs.cstats);
5830 + break;
5831 + default:
5832 + qstats->drops++;
5833 + goto drop;
5834 + }
5835 +
5836 + bstats_update(&cstats->bstats, skb);
5837 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
5838 +
5839 +drop:
5840 + dev_kfree_skb_any(skb);
5841 + return NET_XMIT_SUCCESS;
5842 +}
5843 +
5844 +static int __init ceetm_register(void)
5845 +{
5846 + int _errno = 0;
5847 +
5848 + pr_info(KBUILD_MODNAME ": " DPA_CEETM_DESCRIPTION "\n");
5849 +
5850 + _errno = register_qdisc(&ceetm_qdisc_ops);
5851 + if (unlikely(_errno))
5852 + pr_err(KBUILD_MODNAME
5853 + ": %s:%hu:%s(): register_qdisc() = %d\n",
5854 + KBUILD_BASENAME ".c", __LINE__, __func__, _errno);
5855 +
5856 + return _errno;
5857 +}
5858 +
5859 +static void __exit ceetm_unregister(void)
5860 +{
5861 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
5862 + KBUILD_BASENAME ".c", __func__);
5863 +
5864 + unregister_qdisc(&ceetm_qdisc_ops);
5865 +}
5866 +
5867 +module_init(ceetm_register);
5868 +module_exit(ceetm_unregister);
5869 --- /dev/null
5870 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
5871 @@ -0,0 +1,237 @@
5872 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
5873 + *
5874 + * Redistribution and use in source and binary forms, with or without
5875 + * modification, are permitted provided that the following conditions are met:
5876 + * * Redistributions of source code must retain the above copyright
5877 + * notice, this list of conditions and the following disclaimer.
5878 + * * Redistributions in binary form must reproduce the above copyright
5879 + * notice, this list of conditions and the following disclaimer in the
5880 + * documentation and/or other materials provided with the distribution.
5881 + * * Neither the name of Freescale Semiconductor nor the
5882 + * names of its contributors may be used to endorse or promote products
5883 + * derived from this software without specific prior written permission.
5884 + *
5885 + *
5886 + * ALTERNATIVELY, this software may be distributed under the terms of the
5887 + * GNU General Public License ("GPL") as published by the Free Software
5888 + * Foundation, either version 2 of that License or (at your option) any
5889 + * later version.
5890 + *
5891 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
5892 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5893 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5894 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
5895 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5896 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5897 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5898 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5899 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5900 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5901 + */
5902 +
5903 +#ifndef __DPAA_ETH_CEETM_H
5904 +#define __DPAA_ETH_CEETM_H
5905 +
5906 +#include <net/pkt_sched.h>
5907 +#include <net/pkt_cls.h>
5908 +#include <net/netlink.h>
5909 +#include <lnxwrp_fm.h>
5910 +
5911 +#include "mac.h"
5912 +#include "dpaa_eth_common.h"
5913 +
5914 +/* Mask to determine the sub-portal id from a channel number */
5915 +#define CHANNEL_SP_MASK 0x1f
5916 +/* The number of the last channel that services DCP0, connected to FMan 0.
5917 + * Value validated for B4 and T series platforms.
5918 + */
5919 +#define DCP0_MAX_CHANNEL 0x80f
5920 +/* A2V=1 - field A2 is valid
5921 + * A0V=1 - field A0 is valid - enables frame confirmation
5922 + * OVOM=1 - override operation mode bits with values from A2
5923 + * EBD=1 - external buffers are deallocated at the end of the FMan flow
5924 + * NL=0 - the BMI releases all the internal buffers
5925 + */
5926 +#define CEETM_CONTEXT_A 0x1a00000080000000
5927 +/* The ratio between the superior and inferior congestion state thresholds. The
5928 + * lower threshold is set to 7/8 of the superior one (as the default for WQ
5929 + * scheduling).
5930 + */
5931 +#define CEETM_CCGR_RATIO 0.875
5932 +/* For functional purposes, there are num_tx_queues pfifo qdiscs through which
5933 + * frames reach the driver. Their handles start from 1:21. Handles 1:1 to 1:20
5934 + * are reserved for the maximum 32 CEETM channels (majors and minors are in
5935 + * hex).
5936 + */
5937 +#define PFIFO_MIN_OFFSET 0x21
5938 +
5939 +/* A maximum of 8 CQs can be linked to a CQ channel or to a WBFS scheduler. */
5940 +#define CEETM_MAX_PRIO_QCOUNT 8
5941 +#define CEETM_MAX_WBFS_QCOUNT 8
5942 +#define CEETM_MIN_WBFS_QCOUNT 4
5943 +
5944 +/* The id offsets of the CQs belonging to WBFS groups (ids 8-11/15 for group A
5945 + * and/or 12-15 for group B).
5946 + */
5947 +#define WBFS_GRP_A_OFFSET 8
5948 +#define WBFS_GRP_B_OFFSET 12
5949 +
5950 +#define WBFS_GRP_A 1
5951 +#define WBFS_GRP_B 2
5952 +#define WBFS_GRP_LARGE 3
5953 +
5954 +enum {
5955 + TCA_CEETM_UNSPEC,
5956 + TCA_CEETM_COPT,
5957 + TCA_CEETM_QOPS,
5958 + __TCA_CEETM_MAX,
5959 +};
5960 +
5961 +/* CEETM configuration types */
5962 +enum {
5963 + CEETM_ROOT = 1,
5964 + CEETM_PRIO,
5965 + CEETM_WBFS
5966 +};
5967 +
5968 +#define TCA_CEETM_MAX (__TCA_CEETM_MAX - 1)
5969 +extern const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1];
5970 +
5971 +struct ceetm_class;
5972 +struct ceetm_qdisc_stats;
5973 +struct ceetm_class_stats;
5974 +
5975 +struct ceetm_fq {
5976 + struct qman_fq fq;
5977 + struct net_device *net_dev;
5978 + struct ceetm_class *ceetm_cls;
5979 +};
5980 +
5981 +struct root_q {
5982 + struct Qdisc **qdiscs;
5983 + __u16 overhead;
5984 + __u32 rate;
5985 + __u32 ceil;
5986 + struct qm_ceetm_sp *sp;
5987 + struct qm_ceetm_lni *lni;
5988 + struct ceetm_qdisc_stats __percpu *qstats;
5989 +};
5990 +
5991 +struct prio_q {
5992 + __u16 qcount;
5993 + struct ceetm_class *parent;
5994 +};
5995 +
5996 +struct wbfs_q {
5997 + __u16 qcount;
5998 + int group_type;
5999 + struct ceetm_class *parent;
6000 + __u16 cr;
6001 + __u16 er;
6002 +};
6003 +
6004 +struct ceetm_qdisc {
6005 + int type; /* LNI/CHNL/WBFS */
6006 + bool shaped;
6007 + union {
6008 + struct root_q root;
6009 + struct prio_q prio;
6010 + struct wbfs_q wbfs;
6011 + };
6012 + struct Qdisc_class_hash clhash;
6013 + struct tcf_proto *filter_list; /* qdisc attached filters */
6014 +};
6015 +
6016 +/* CEETM Qdisc configuration parameters */
6017 +struct tc_ceetm_qopt {
6018 + __u32 type;
6019 + __u16 shaped;
6020 + __u16 qcount;
6021 + __u16 overhead;
6022 + __u32 rate;
6023 + __u32 ceil;
6024 + __u16 cr;
6025 + __u16 er;
6026 + __u8 qweight[CEETM_MAX_WBFS_QCOUNT];
6027 +};
6028 +
6029 +struct root_c {
6030 + unsigned int rate;
6031 + unsigned int ceil;
6032 + unsigned int tbl;
6033 + bool wbfs_grp_a;
6034 + bool wbfs_grp_b;
6035 + bool wbfs_grp_large;
6036 + struct Qdisc *child;
6037 + struct qm_ceetm_channel *ch;
6038 +};
6039 +
6040 +struct prio_c {
6041 + bool cr;
6042 + bool er;
6043 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6044 + struct qm_ceetm_lfq *lfq;
6045 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6046 + struct qm_ceetm_ccg *ccg;
6047 + /* only one wbfs can be linked to one priority CQ */
6048 + struct Qdisc *child;
6049 + struct ceetm_class_stats __percpu *cstats;
6050 +};
6051 +
6052 +struct wbfs_c {
6053 + __u8 weight; /* The weight of the class between 1 and 248 */
6054 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6055 + struct qm_ceetm_lfq *lfq;
6056 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6057 + struct qm_ceetm_ccg *ccg;
6058 + struct ceetm_class_stats __percpu *cstats;
6059 +};
6060 +
6061 +struct ceetm_class {
6062 + struct Qdisc_class_common common;
6063 + int refcnt; /* usage count of this class */
6064 + struct tcf_proto *filter_list; /* class attached filters */
6065 + struct Qdisc *parent;
6066 + bool shaped;
6067 + int type; /* ROOT/PRIO/WBFS */
6068 + union {
6069 + struct root_c root;
6070 + struct prio_c prio;
6071 + struct wbfs_c wbfs;
6072 + };
6073 +};
6074 +
6075 +/* CEETM Class configuration parameters */
6076 +struct tc_ceetm_copt {
6077 + __u32 type;
6078 + __u16 shaped;
6079 + __u32 rate;
6080 + __u32 ceil;
6081 + __u16 tbl;
6082 + __u16 cr;
6083 + __u16 er;
6084 + __u8 weight;
6085 +};
6086 +
6087 +/* CEETM stats */
6088 +struct ceetm_qdisc_stats {
6089 + __u32 drops;
6090 +};
6091 +
6092 +struct ceetm_class_stats {
6093 + /* Software counters */
6094 + struct gnet_stats_basic_packed bstats;
6095 + __u32 ern_drop_count;
6096 + __u32 congested_count;
6097 +};
6098 +
6099 +struct tc_ceetm_xstats {
6100 + __u32 ern_drop_count;
6101 + __u32 congested_count;
6102 + /* Hardware counters */
6103 + __u64 frame_count;
6104 + __u64 byte_count;
6105 +};
6106 +
6107 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev);
6108 +#endif
6109 --- /dev/null
6110 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
6111 @@ -0,0 +1,1820 @@
6112 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
6113 + *
6114 + * Redistribution and use in source and binary forms, with or without
6115 + * modification, are permitted provided that the following conditions are met:
6116 + * * Redistributions of source code must retain the above copyright
6117 + * notice, this list of conditions and the following disclaimer.
6118 + * * Redistributions in binary form must reproduce the above copyright
6119 + * notice, this list of conditions and the following disclaimer in the
6120 + * documentation and/or other materials provided with the distribution.
6121 + * * Neither the name of Freescale Semiconductor nor the
6122 + * names of its contributors may be used to endorse or promote products
6123 + * derived from this software without specific prior written permission.
6124 + *
6125 + *
6126 + * ALTERNATIVELY, this software may be distributed under the terms of the
6127 + * GNU General Public License ("GPL") as published by the Free Software
6128 + * Foundation, either version 2 of that License or (at your option) any
6129 + * later version.
6130 + *
6131 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
6132 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6133 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6134 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
6135 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6136 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6137 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6138 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6139 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6140 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6141 + */
6142 +
6143 +#include <linux/init.h>
6144 +#include <linux/module.h>
6145 +#include <linux/of_platform.h>
6146 +#include <linux/of_net.h>
6147 +#include <linux/etherdevice.h>
6148 +#include <linux/kthread.h>
6149 +#include <linux/percpu.h>
6150 +#include <linux/highmem.h>
6151 +#include <linux/sort.h>
6152 +#include <linux/fsl_qman.h>
6153 +#include <linux/ip.h>
6154 +#include <linux/ipv6.h>
6155 +#include <linux/if_vlan.h> /* vlan_eth_hdr */
6156 +#include "dpaa_eth.h"
6157 +#include "dpaa_eth_common.h"
6158 +#ifdef CONFIG_FSL_DPAA_1588
6159 +#include "dpaa_1588.h"
6160 +#endif
6161 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6162 +#include "dpaa_debugfs.h"
6163 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6164 +#include "mac.h"
6165 +
6166 +/* Size in bytes of the FQ taildrop threshold */
6167 +#define DPA_FQ_TD 0x200000
6168 +
6169 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6170 +struct ptp_priv_s ptp_priv;
6171 +#endif
6172 +
6173 +static struct dpa_bp *dpa_bp_array[64];
6174 +
6175 +int dpa_max_frm;
6176 +EXPORT_SYMBOL(dpa_max_frm);
6177 +
6178 +int dpa_rx_extra_headroom;
6179 +EXPORT_SYMBOL(dpa_rx_extra_headroom);
6180 +
6181 +int dpa_num_cpus = NR_CPUS;
6182 +
6183 +static const struct fqid_cell tx_confirm_fqids[] = {
6184 + {0, DPAA_ETH_TX_QUEUES}
6185 +};
6186 +
6187 +static struct fqid_cell default_fqids[][3] = {
6188 + [RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} },
6189 + [TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} }
6190 +};
6191 +
6192 +static const char fsl_qman_frame_queues[][25] = {
6193 + [RX] = "fsl,qman-frame-queues-rx",
6194 + [TX] = "fsl,qman-frame-queues-tx"
6195 +};
6196 +#ifdef CONFIG_FSL_DPAA_HOOKS
6197 +/* A set of callbacks for hooking into the fastpath at different points. */
6198 +struct dpaa_eth_hooks_s dpaa_eth_hooks;
6199 +EXPORT_SYMBOL(dpaa_eth_hooks);
6200 +/* This function should only be called on the probe paths, since it makes no
6201 + * effort to guarantee consistency of the destination hooks structure.
6202 + */
6203 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks)
6204 +{
6205 + if (hooks)
6206 + dpaa_eth_hooks = *hooks;
6207 + else
6208 + pr_err("NULL pointer to hooks!\n");
6209 +}
6210 +EXPORT_SYMBOL(fsl_dpaa_eth_set_hooks);
6211 +#endif
6212 +
6213 +int dpa_netdev_init(struct net_device *net_dev,
6214 + const uint8_t *mac_addr,
6215 + uint16_t tx_timeout)
6216 +{
6217 + int err;
6218 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6219 + struct device *dev = net_dev->dev.parent;
6220 +
6221 + net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
6222 +
6223 + net_dev->features |= net_dev->hw_features;
6224 + net_dev->vlan_features = net_dev->features;
6225 +
6226 + memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
6227 + memcpy(net_dev->dev_addr, mac_addr, net_dev->addr_len);
6228 +
6229 + net_dev->ethtool_ops = &dpa_ethtool_ops;
6230 +
6231 + net_dev->needed_headroom = priv->tx_headroom;
6232 + net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
6233 +
6234 + err = register_netdev(net_dev);
6235 + if (err < 0) {
6236 + dev_err(dev, "register_netdev() = %d\n", err);
6237 + return err;
6238 + }
6239 +
6240 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6241 + /* create debugfs entry for this net_device */
6242 + err = dpa_netdev_debugfs_create(net_dev);
6243 + if (err) {
6244 + unregister_netdev(net_dev);
6245 + return err;
6246 + }
6247 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6248 +
6249 + return 0;
6250 +}
6251 +EXPORT_SYMBOL(dpa_netdev_init);
6252 +
6253 +int __cold dpa_start(struct net_device *net_dev)
6254 +{
6255 + int err, i;
6256 + struct dpa_priv_s *priv;
6257 + struct mac_device *mac_dev;
6258 +
6259 + priv = netdev_priv(net_dev);
6260 + mac_dev = priv->mac_dev;
6261 +
6262 + err = mac_dev->init_phy(net_dev, priv->mac_dev);
6263 + if (err < 0) {
6264 + if (netif_msg_ifup(priv))
6265 + netdev_err(net_dev, "init_phy() = %d\n", err);
6266 + return err;
6267 + }
6268 +
6269 + for_each_port_device(i, mac_dev->port_dev) {
6270 + err = fm_port_enable(mac_dev->port_dev[i]);
6271 + if (err)
6272 + goto mac_start_failed;
6273 + }
6274 +
6275 + err = priv->mac_dev->start(mac_dev);
6276 + if (err < 0) {
6277 + if (netif_msg_ifup(priv))
6278 + netdev_err(net_dev, "mac_dev->start() = %d\n", err);
6279 + goto mac_start_failed;
6280 + }
6281 +
6282 + netif_tx_start_all_queues(net_dev);
6283 +
6284 + return 0;
6285 +
6286 +mac_start_failed:
6287 + for_each_port_device(i, mac_dev->port_dev)
6288 + fm_port_disable(mac_dev->port_dev[i]);
6289 +
6290 + return err;
6291 +}
6292 +EXPORT_SYMBOL(dpa_start);
6293 +
6294 +int __cold dpa_stop(struct net_device *net_dev)
6295 +{
6296 + int _errno, i, err;
6297 + struct dpa_priv_s *priv;
6298 + struct mac_device *mac_dev;
6299 +
6300 + priv = netdev_priv(net_dev);
6301 + mac_dev = priv->mac_dev;
6302 +
6303 + netif_tx_stop_all_queues(net_dev);
6304 + /* Allow the Fman (Tx) port to process in-flight frames before we
6305 + * try switching it off.
6306 + */
6307 + usleep_range(5000, 10000);
6308 +
6309 + _errno = mac_dev->stop(mac_dev);
6310 + if (unlikely(_errno < 0))
6311 + if (netif_msg_ifdown(priv))
6312 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
6313 + _errno);
6314 +
6315 + for_each_port_device(i, mac_dev->port_dev) {
6316 + err = fm_port_disable(mac_dev->port_dev[i]);
6317 + _errno = err ? err : _errno;
6318 + }
6319 +
6320 + if (mac_dev->phy_dev)
6321 + phy_disconnect(mac_dev->phy_dev);
6322 + mac_dev->phy_dev = NULL;
6323 +
6324 + return _errno;
6325 +}
6326 +EXPORT_SYMBOL(dpa_stop);
6327 +
6328 +void __cold dpa_timeout(struct net_device *net_dev)
6329 +{
6330 + const struct dpa_priv_s *priv;
6331 + struct dpa_percpu_priv_s *percpu_priv;
6332 +
6333 + priv = netdev_priv(net_dev);
6334 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
6335 +
6336 + if (netif_msg_timer(priv))
6337 + netdev_crit(net_dev, "Transmit timeout!\n");
6338 +
6339 + percpu_priv->stats.tx_errors++;
6340 +}
6341 +EXPORT_SYMBOL(dpa_timeout);
6342 +
6343 +/* net_device */
6344 +
6345 +/**
6346 + * @param net_dev the device for which statistics are calculated
6347 + * @param stats the function fills this structure with the device's statistics
6348 + * @return the address of the structure containing the statistics
6349 + *
6350 + * Calculates the statistics for the given device by adding the statistics
6351 + * collected by each CPU.
6352 + */
6353 +void __cold
6354 +dpa_get_stats64(struct net_device *net_dev,
6355 + struct rtnl_link_stats64 *stats)
6356 +{
6357 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6358 + u64 *cpustats;
6359 + u64 *netstats = (u64 *)stats;
6360 + int i, j;
6361 + struct dpa_percpu_priv_s *percpu_priv;
6362 + int numstats = sizeof(struct rtnl_link_stats64) / sizeof(u64);
6363 +
6364 + for_each_possible_cpu(i) {
6365 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
6366 +
6367 + cpustats = (u64 *)&percpu_priv->stats;
6368 +
6369 + for (j = 0; j < numstats; j++)
6370 + netstats[j] += cpustats[j];
6371 + }
6372 +}
6373 +EXPORT_SYMBOL(dpa_get_stats64);
6374 +
6375 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu)
6376 +{
6377 + int max_mtu = dpa_get_max_mtu();
6378 +
6379 +#ifndef CONFIG_PPC
6380 + /* Due to the A010022 FMan errata, we can not use contig frames larger
6381 + * than 4K, nor S/G frames. We need to prevent the user from setting a
6382 + * large MTU.
6383 + */
6384 + if (unlikely(dpaa_errata_a010022))
6385 + max_mtu = DPA_BP_RAW_SIZE;
6386 +#endif
6387 +
6388 + /* Make sure we don't exceed the Ethernet controller's MAXFRM */
6389 + if (new_mtu < 68 || new_mtu > max_mtu) {
6390 + netdev_err(net_dev, "Invalid L3 mtu %d (must be between %d and %d).\n",
6391 + new_mtu, 68, max_mtu);
6392 + return -EINVAL;
6393 + }
6394 + net_dev->mtu = new_mtu;
6395 +
6396 + return 0;
6397 +}
6398 +EXPORT_SYMBOL(dpa_change_mtu);
6399 +
6400 +/* .ndo_init callback */
6401 +int dpa_ndo_init(struct net_device *net_dev)
6402 +{
6403 + /* If fsl_fm_max_frm is set to a higher value than the all-common 1500,
6404 + * we choose conservatively and let the user explicitly set a higher
6405 + * MTU via ifconfig. Otherwise, the user may end up with different MTUs
6406 + * in the same LAN.
6407 + * If on the other hand fsl_fm_max_frm has been chosen below 1500,
6408 + * start with the maximum allowed.
6409 + */
6410 + int init_mtu = min(dpa_get_max_mtu(), ETH_DATA_LEN);
6411 +
6412 + pr_debug("Setting initial MTU on net device: %d\n", init_mtu);
6413 + net_dev->mtu = init_mtu;
6414 +
6415 + return 0;
6416 +}
6417 +EXPORT_SYMBOL(dpa_ndo_init);
6418 +
6419 +int dpa_set_features(struct net_device *dev, netdev_features_t features)
6420 +{
6421 + /* Not much to do here for now */
6422 + dev->features = features;
6423 + return 0;
6424 +}
6425 +EXPORT_SYMBOL(dpa_set_features);
6426 +
6427 +netdev_features_t dpa_fix_features(struct net_device *dev,
6428 + netdev_features_t features)
6429 +{
6430 + netdev_features_t unsupported_features = 0;
6431 +
6432 + /* In theory we should never be requested to enable features that
6433 + * we didn't set in netdev->features and netdev->hw_features at probe
6434 + * time, but double check just to be on the safe side.
6435 + * We don't support enabling Rx csum through ethtool yet
6436 + */
6437 + unsupported_features |= NETIF_F_RXCSUM;
6438 +
6439 + features &= ~unsupported_features;
6440 +
6441 + return features;
6442 +}
6443 +EXPORT_SYMBOL(dpa_fix_features);
6444 +
6445 +#ifdef CONFIG_FSL_DPAA_TS
6446 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx,
6447 + const void *data)
6448 +{
6449 + u64 *ts, ns;
6450 +
6451 + ts = fm_port_get_buffer_time_stamp(priv->mac_dev->port_dev[rx_tx],
6452 + data);
6453 +
6454 + if (!ts || *ts == 0)
6455 + return 0;
6456 +
6457 + be64_to_cpus(ts);
6458 +
6459 + /* multiple DPA_PTP_NOMINAL_FREQ_PERIOD_NS for case of non power of 2 */
6460 + ns = *ts << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT;
6461 +
6462 + return ns;
6463 +}
6464 +
6465 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
6466 + struct skb_shared_hwtstamps *shhwtstamps, const void *data)
6467 +{
6468 + u64 ns;
6469 +
6470 + ns = dpa_get_timestamp_ns(priv, rx_tx, data);
6471 +
6472 + if (ns == 0)
6473 + return -EINVAL;
6474 +
6475 + memset(shhwtstamps, 0, sizeof(*shhwtstamps));
6476 + shhwtstamps->hwtstamp = ns_to_ktime(ns);
6477 +
6478 + return 0;
6479 +}
6480 +
6481 +static void dpa_ts_tx_enable(struct net_device *dev)
6482 +{
6483 + struct dpa_priv_s *priv = netdev_priv(dev);
6484 + struct mac_device *mac_dev = priv->mac_dev;
6485 +
6486 + if (mac_dev->fm_rtc_enable)
6487 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6488 + if (mac_dev->ptp_enable)
6489 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6490 +
6491 + priv->ts_tx_en = true;
6492 +}
6493 +
6494 +static void dpa_ts_tx_disable(struct net_device *dev)
6495 +{
6496 + struct dpa_priv_s *priv = netdev_priv(dev);
6497 +
6498 +#if 0
6499 +/* the RTC might be needed by the Rx Ts, cannot disable here
6500 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6501 + */
6502 + struct mac_device *mac_dev = priv->mac_dev;
6503 +
6504 + if (mac_dev->fm_rtc_disable)
6505 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6506 +
6507 + if (mac_dev->ptp_disable)
6508 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6509 +#endif
6510 +
6511 + priv->ts_tx_en = false;
6512 +}
6513 +
6514 +static void dpa_ts_rx_enable(struct net_device *dev)
6515 +{
6516 + struct dpa_priv_s *priv = netdev_priv(dev);
6517 + struct mac_device *mac_dev = priv->mac_dev;
6518 +
6519 + if (mac_dev->fm_rtc_enable)
6520 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6521 + if (mac_dev->ptp_enable)
6522 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6523 +
6524 + priv->ts_rx_en = true;
6525 +}
6526 +
6527 +static void dpa_ts_rx_disable(struct net_device *dev)
6528 +{
6529 + struct dpa_priv_s *priv = netdev_priv(dev);
6530 +
6531 +#if 0
6532 +/* the RTC might be needed by the Tx Ts, cannot disable here
6533 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6534 + */
6535 + struct mac_device *mac_dev = priv->mac_dev;
6536 +
6537 + if (mac_dev->fm_rtc_disable)
6538 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6539 +
6540 + if (mac_dev->ptp_disable)
6541 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6542 +#endif
6543 +
6544 + priv->ts_rx_en = false;
6545 +}
6546 +
6547 +static int dpa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6548 +{
6549 + struct hwtstamp_config config;
6550 +
6551 + if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
6552 + return -EFAULT;
6553 +
6554 + switch (config.tx_type) {
6555 + case HWTSTAMP_TX_OFF:
6556 + dpa_ts_tx_disable(dev);
6557 + break;
6558 + case HWTSTAMP_TX_ON:
6559 + dpa_ts_tx_enable(dev);
6560 + break;
6561 + default:
6562 + return -ERANGE;
6563 + }
6564 +
6565 + if (config.rx_filter == HWTSTAMP_FILTER_NONE)
6566 + dpa_ts_rx_disable(dev);
6567 + else {
6568 + dpa_ts_rx_enable(dev);
6569 + /* TS is set for all frame types, not only those requested */
6570 + config.rx_filter = HWTSTAMP_FILTER_ALL;
6571 + }
6572 +
6573 + return copy_to_user(rq->ifr_data, &config, sizeof(config)) ?
6574 + -EFAULT : 0;
6575 +}
6576 +#endif /* CONFIG_FSL_DPAA_TS */
6577 +
6578 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6579 +{
6580 +#ifdef CONFIG_FSL_DPAA_1588
6581 + struct dpa_priv_s *priv = netdev_priv(dev);
6582 +#endif
6583 + int ret = 0;
6584 +
6585 + /* at least one timestamping feature must be enabled */
6586 +#ifdef CONFIG_FSL_DPAA_TS
6587 + if (!netif_running(dev))
6588 +#endif
6589 + return -EINVAL;
6590 +
6591 +#ifdef CONFIG_FSL_DPAA_TS
6592 + if (cmd == SIOCSHWTSTAMP)
6593 + return dpa_ts_ioctl(dev, rq, cmd);
6594 +#endif /* CONFIG_FSL_DPAA_TS */
6595 +
6596 +#ifdef CONFIG_FSL_DPAA_1588
6597 + if ((cmd >= PTP_ENBL_TXTS_IOCTL) && (cmd <= PTP_CLEANUP_TS)) {
6598 + if (priv->tsu && priv->tsu->valid)
6599 + ret = dpa_ioctl_1588(dev, rq, cmd);
6600 + else
6601 + ret = -ENODEV;
6602 + }
6603 +#endif
6604 +
6605 + return ret;
6606 +}
6607 +EXPORT_SYMBOL(dpa_ioctl);
6608 +
6609 +int __cold dpa_remove(struct platform_device *of_dev)
6610 +{
6611 + int err;
6612 + struct device *dev;
6613 + struct net_device *net_dev;
6614 + struct dpa_priv_s *priv;
6615 +
6616 + dev = &of_dev->dev;
6617 + net_dev = dev_get_drvdata(dev);
6618 +
6619 + priv = netdev_priv(net_dev);
6620 +
6621 + dpaa_eth_sysfs_remove(dev);
6622 +
6623 + dev_set_drvdata(dev, NULL);
6624 + unregister_netdev(net_dev);
6625 +
6626 + err = dpa_fq_free(dev, &priv->dpa_fq_list);
6627 +
6628 + qman_delete_cgr_safe(&priv->ingress_cgr);
6629 + qman_release_cgrid(priv->ingress_cgr.cgrid);
6630 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
6631 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
6632 +
6633 + dpa_private_napi_del(net_dev);
6634 +
6635 + dpa_bp_free(priv);
6636 +
6637 + if (priv->buf_layout)
6638 + devm_kfree(dev, priv->buf_layout);
6639 +
6640 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6641 + /* remove debugfs entry for this net_device */
6642 + dpa_netdev_debugfs_remove(net_dev);
6643 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6644 +
6645 +#ifdef CONFIG_FSL_DPAA_1588
6646 + if (priv->tsu && priv->tsu->valid)
6647 + dpa_ptp_cleanup(priv);
6648 +#endif
6649 +
6650 + free_netdev(net_dev);
6651 +
6652 + return err;
6653 +}
6654 +EXPORT_SYMBOL(dpa_remove);
6655 +
6656 +struct mac_device * __cold __must_check
6657 +__attribute__((nonnull))
6658 +dpa_mac_probe(struct platform_device *_of_dev)
6659 +{
6660 + struct device *dpa_dev, *dev;
6661 + struct device_node *mac_node;
6662 + struct platform_device *of_dev;
6663 + struct mac_device *mac_dev;
6664 +#ifdef CONFIG_FSL_DPAA_1588
6665 + int lenp;
6666 + const phandle *phandle_prop;
6667 + struct net_device *net_dev = NULL;
6668 + struct dpa_priv_s *priv = NULL;
6669 + struct device_node *timer_node;
6670 +#endif
6671 + dpa_dev = &_of_dev->dev;
6672 +
6673 + mac_node = of_parse_phandle(_of_dev->dev.of_node, "fsl,fman-mac", 0);
6674 + if (unlikely(mac_node == NULL)) {
6675 + dev_err(dpa_dev, "Cannot find MAC device device tree node\n");
6676 + return ERR_PTR(-EFAULT);
6677 + }
6678 +
6679 + of_dev = of_find_device_by_node(mac_node);
6680 + if (unlikely(of_dev == NULL)) {
6681 + dev_err(dpa_dev, "of_find_device_by_node(%s) failed\n",
6682 + mac_node->full_name);
6683 + of_node_put(mac_node);
6684 + return ERR_PTR(-EINVAL);
6685 + }
6686 + of_node_put(mac_node);
6687 +
6688 + dev = &of_dev->dev;
6689 +
6690 + mac_dev = dev_get_drvdata(dev);
6691 + if (unlikely(mac_dev == NULL)) {
6692 + dev_err(dpa_dev, "dev_get_drvdata(%s) failed\n",
6693 + dev_name(dev));
6694 + return ERR_PTR(-EINVAL);
6695 + }
6696 +
6697 +#ifdef CONFIG_FSL_DPAA_1588
6698 + phandle_prop = of_get_property(mac_node, "ptp-timer", &lenp);
6699 + if (phandle_prop && ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6700 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6701 + (mac_dev->speed == SPEED_1000)))) {
6702 + timer_node = of_find_node_by_phandle(*phandle_prop);
6703 + if (timer_node)
6704 + net_dev = dev_get_drvdata(dpa_dev);
6705 + if (timer_node && net_dev) {
6706 + priv = netdev_priv(net_dev);
6707 + if (!dpa_ptp_init(priv))
6708 + dev_info(dev, "%s: ptp 1588 is initialized.\n",
6709 + mac_node->full_name);
6710 + }
6711 + }
6712 +#endif
6713 +
6714 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6715 + if ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6716 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6717 + (mac_dev->speed == SPEED_1000))) {
6718 + ptp_priv.node = of_parse_phandle(mac_node, "ptp-timer", 0);
6719 + if (ptp_priv.node) {
6720 + ptp_priv.of_dev = of_find_device_by_node(ptp_priv.node);
6721 + if (unlikely(ptp_priv.of_dev == NULL)) {
6722 + dev_err(dpa_dev,
6723 + "Cannot find device represented by timer_node\n");
6724 + of_node_put(ptp_priv.node);
6725 + return ERR_PTR(-EINVAL);
6726 + }
6727 + ptp_priv.mac_dev = mac_dev;
6728 + }
6729 + }
6730 +#endif
6731 + return mac_dev;
6732 +}
6733 +EXPORT_SYMBOL(dpa_mac_probe);
6734 +
6735 +int dpa_set_mac_address(struct net_device *net_dev, void *addr)
6736 +{
6737 + const struct dpa_priv_s *priv;
6738 + int _errno;
6739 + struct mac_device *mac_dev;
6740 +
6741 + priv = netdev_priv(net_dev);
6742 +
6743 + _errno = eth_mac_addr(net_dev, addr);
6744 + if (_errno < 0) {
6745 + if (netif_msg_drv(priv))
6746 + netdev_err(net_dev,
6747 + "eth_mac_addr() = %d\n",
6748 + _errno);
6749 + return _errno;
6750 + }
6751 +
6752 + mac_dev = priv->mac_dev;
6753 +
6754 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
6755 + net_dev->dev_addr);
6756 + if (_errno < 0) {
6757 + if (netif_msg_drv(priv))
6758 + netdev_err(net_dev,
6759 + "mac_dev->change_addr() = %d\n",
6760 + _errno);
6761 + return _errno;
6762 + }
6763 +
6764 + return 0;
6765 +}
6766 +EXPORT_SYMBOL(dpa_set_mac_address);
6767 +
6768 +void dpa_set_rx_mode(struct net_device *net_dev)
6769 +{
6770 + int _errno;
6771 + const struct dpa_priv_s *priv;
6772 +
6773 + priv = netdev_priv(net_dev);
6774 +
6775 + if (!!(net_dev->flags & IFF_PROMISC) != priv->mac_dev->promisc) {
6776 + priv->mac_dev->promisc = !priv->mac_dev->promisc;
6777 + _errno = priv->mac_dev->set_promisc(
6778 + priv->mac_dev->get_mac_handle(priv->mac_dev),
6779 + priv->mac_dev->promisc);
6780 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6781 + netdev_err(net_dev,
6782 + "mac_dev->set_promisc() = %d\n",
6783 + _errno);
6784 + }
6785 +
6786 + _errno = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
6787 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6788 + netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno);
6789 +}
6790 +EXPORT_SYMBOL(dpa_set_rx_mode);
6791 +
6792 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
6793 + struct dpa_buffer_layout_s *layout)
6794 +{
6795 + struct fm_port_params params;
6796 +
6797 + /* Rx */
6798 + layout[RX].priv_data_size = (uint16_t)DPA_RX_PRIV_DATA_SIZE;
6799 + layout[RX].parse_results = true;
6800 + layout[RX].hash_results = true;
6801 +#ifdef CONFIG_FSL_DPAA_TS
6802 + layout[RX].time_stamp = true;
6803 +#endif
6804 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[RX], &params);
6805 + layout[RX].manip_extra_space = params.manip_extra_space;
6806 + /* a value of zero for data alignment means "don't care", so align to
6807 + * a non-zero value to prevent FMD from using its own default
6808 + */
6809 + layout[RX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6810 +
6811 + /* Tx */
6812 + layout[TX].priv_data_size = DPA_TX_PRIV_DATA_SIZE;
6813 + layout[TX].parse_results = true;
6814 + layout[TX].hash_results = true;
6815 +#ifdef CONFIG_FSL_DPAA_TS
6816 + layout[TX].time_stamp = true;
6817 +#endif
6818 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[TX], &params);
6819 + layout[TX].manip_extra_space = params.manip_extra_space;
6820 + layout[TX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6821 +}
6822 +EXPORT_SYMBOL(dpa_set_buffers_layout);
6823 +
6824 +int __attribute__((nonnull))
6825 +dpa_bp_alloc(struct dpa_bp *dpa_bp)
6826 +{
6827 + int err;
6828 + struct bman_pool_params bp_params;
6829 + struct platform_device *pdev;
6830 +
6831 + if (dpa_bp->size == 0 || dpa_bp->config_count == 0) {
6832 + pr_err("Buffer pool is not properly initialized! Missing size or initial number of buffers");
6833 + return -EINVAL;
6834 + }
6835 +
6836 + memset(&bp_params, 0, sizeof(struct bman_pool_params));
6837 +#ifdef CONFIG_FMAN_PFC
6838 + bp_params.flags = BMAN_POOL_FLAG_THRESH;
6839 + bp_params.thresholds[0] = bp_params.thresholds[2] =
6840 + CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD;
6841 + bp_params.thresholds[1] = bp_params.thresholds[3] =
6842 + CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
6843 +#endif
6844 +
6845 + /* If the pool is already specified, we only create one per bpid */
6846 + if (dpa_bpid2pool_use(dpa_bp->bpid))
6847 + return 0;
6848 +
6849 + if (dpa_bp->bpid == 0)
6850 + bp_params.flags |= BMAN_POOL_FLAG_DYNAMIC_BPID;
6851 + else
6852 + bp_params.bpid = dpa_bp->bpid;
6853 +
6854 + dpa_bp->pool = bman_new_pool(&bp_params);
6855 + if (unlikely(dpa_bp->pool == NULL)) {
6856 + pr_err("bman_new_pool() failed\n");
6857 + return -ENODEV;
6858 + }
6859 +
6860 + dpa_bp->bpid = (uint8_t)bman_get_params(dpa_bp->pool)->bpid;
6861 +
6862 + pdev = platform_device_register_simple("dpaa_eth_bpool",
6863 + dpa_bp->bpid, NULL, 0);
6864 + if (IS_ERR(pdev)) {
6865 + pr_err("platform_device_register_simple() failed\n");
6866 + err = PTR_ERR(pdev);
6867 + goto pdev_register_failed;
6868 + }
6869 + {
6870 + struct dma_map_ops *ops = get_dma_ops(&pdev->dev);
6871 + ops->dma_supported = NULL;
6872 + }
6873 + err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40));
6874 + if (err) {
6875 + pr_err("dma_coerce_mask_and_coherent() failed\n");
6876 + goto pdev_mask_failed;
6877 + }
6878 +#ifdef CONFIG_FMAN_ARM
6879 + /* force coherency */
6880 + pdev->dev.archdata.dma_coherent = true;
6881 + arch_setup_dma_ops(&pdev->dev, 0, 0, NULL, true);
6882 +#endif
6883 +
6884 + dpa_bp->dev = &pdev->dev;
6885 +
6886 + if (dpa_bp->seed_cb) {
6887 + err = dpa_bp->seed_cb(dpa_bp);
6888 + if (err)
6889 + goto pool_seed_failed;
6890 + }
6891 +
6892 + dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp);
6893 +
6894 + return 0;
6895 +
6896 +pool_seed_failed:
6897 +pdev_mask_failed:
6898 + platform_device_unregister(pdev);
6899 +pdev_register_failed:
6900 + bman_free_pool(dpa_bp->pool);
6901 +
6902 + return err;
6903 +}
6904 +EXPORT_SYMBOL(dpa_bp_alloc);
6905 +
6906 +void dpa_bp_drain(struct dpa_bp *bp)
6907 +{
6908 + int ret, num = 8;
6909 +
6910 + do {
6911 + struct bm_buffer bmb[8];
6912 + int i;
6913 +
6914 + ret = bman_acquire(bp->pool, bmb, num, 0);
6915 + if (ret < 0) {
6916 + if (num == 8) {
6917 + /* we have less than 8 buffers left;
6918 + * drain them one by one
6919 + */
6920 + num = 1;
6921 + ret = 1;
6922 + continue;
6923 + } else {
6924 + /* Pool is fully drained */
6925 + break;
6926 + }
6927 + }
6928 +
6929 + for (i = 0; i < num; i++) {
6930 + dma_addr_t addr = bm_buf_addr(&bmb[i]);
6931 +
6932 + dma_unmap_single(bp->dev, addr, bp->size,
6933 + DMA_BIDIRECTIONAL);
6934 +
6935 + bp->free_buf_cb(phys_to_virt(addr));
6936 + }
6937 + } while (ret > 0);
6938 +}
6939 +EXPORT_SYMBOL(dpa_bp_drain);
6940 +
6941 +static void __cold __attribute__((nonnull))
6942 +_dpa_bp_free(struct dpa_bp *dpa_bp)
6943 +{
6944 + struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid);
6945 +
6946 + /* the mapping between bpid and dpa_bp is done very late in the
6947 + * allocation procedure; if something failed before the mapping, the bp
6948 + * was not configured, therefore we don't need the below instructions
6949 + */
6950 + if (!bp)
6951 + return;
6952 +
6953 + if (!atomic_dec_and_test(&bp->refs))
6954 + return;
6955 +
6956 + if (bp->free_buf_cb)
6957 + dpa_bp_drain(bp);
6958 +
6959 + dpa_bp_array[bp->bpid] = NULL;
6960 + bman_free_pool(bp->pool);
6961 +
6962 + if (bp->dev)
6963 + platform_device_unregister(to_platform_device(bp->dev));
6964 +}
6965 +
6966 +void __cold __attribute__((nonnull))
6967 +dpa_bp_free(struct dpa_priv_s *priv)
6968 +{
6969 + int i;
6970 +
6971 + if (priv->dpa_bp)
6972 + for (i = 0; i < priv->bp_count; i++)
6973 + _dpa_bp_free(&priv->dpa_bp[i]);
6974 +}
6975 +EXPORT_SYMBOL(dpa_bp_free);
6976 +
6977 +struct dpa_bp *dpa_bpid2pool(int bpid)
6978 +{
6979 + return dpa_bp_array[bpid];
6980 +}
6981 +EXPORT_SYMBOL(dpa_bpid2pool);
6982 +
6983 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp)
6984 +{
6985 + dpa_bp_array[bpid] = dpa_bp;
6986 + atomic_set(&dpa_bp->refs, 1);
6987 +}
6988 +
6989 +bool dpa_bpid2pool_use(int bpid)
6990 +{
6991 + if (dpa_bpid2pool(bpid)) {
6992 + atomic_inc(&dpa_bp_array[bpid]->refs);
6993 + return true;
6994 + }
6995 +
6996 + return false;
6997 +}
6998 +
6999 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
7000 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
7001 + void *accel_priv, select_queue_fallback_t fallback)
7002 +{
7003 + return dpa_get_queue_mapping(skb);
7004 +}
7005 +EXPORT_SYMBOL(dpa_select_queue);
7006 +#endif
7007 +
7008 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
7009 + u32 fq_start,
7010 + u32 fq_count,
7011 + struct list_head *list,
7012 + enum dpa_fq_type fq_type)
7013 +{
7014 + int i;
7015 + struct dpa_fq *dpa_fq;
7016 +
7017 + dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fq_count, GFP_KERNEL);
7018 + if (dpa_fq == NULL)
7019 + return NULL;
7020 +
7021 + for (i = 0; i < fq_count; i++) {
7022 + dpa_fq[i].fq_type = fq_type;
7023 + if (fq_type == FQ_TYPE_RX_PCD_HI_PRIO)
7024 + dpa_fq[i].fqid = fq_start ?
7025 + DPAA_ETH_FQ_DELTA + fq_start + i : 0;
7026 + else
7027 + dpa_fq[i].fqid = fq_start ? fq_start + i : 0;
7028 +
7029 + list_add_tail(&dpa_fq[i].list, list);
7030 + }
7031 +
7032 +#ifdef CONFIG_FMAN_PFC
7033 + if (fq_type == FQ_TYPE_TX)
7034 + for (i = 0; i < fq_count; i++)
7035 + dpa_fq[i].wq = i / dpa_num_cpus;
7036 + else
7037 +#endif
7038 + for (i = 0; i < fq_count; i++)
7039 + _dpa_assign_wq(dpa_fq + i);
7040 +
7041 + return dpa_fq;
7042 +}
7043 +EXPORT_SYMBOL(dpa_fq_alloc);
7044 +
7045 +/* Probing of FQs for MACful ports */
7046 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
7047 + struct fm_port_fqs *port_fqs,
7048 + bool alloc_tx_conf_fqs,
7049 + enum port_type ptype)
7050 +{
7051 + struct fqid_cell *fqids = NULL;
7052 + const void *fqids_off = NULL;
7053 + struct dpa_fq *dpa_fq = NULL;
7054 + struct device_node *np = dev->of_node;
7055 + int num_ranges;
7056 + int i, lenp;
7057 +
7058 + if (ptype == TX && alloc_tx_conf_fqs) {
7059 + if (!dpa_fq_alloc(dev, tx_confirm_fqids->start,
7060 + tx_confirm_fqids->count, list,
7061 + FQ_TYPE_TX_CONF_MQ))
7062 + goto fq_alloc_failed;
7063 + }
7064 +
7065 + fqids_off = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
7066 + if (fqids_off == NULL) {
7067 + /* No dts definition, so use the defaults. */
7068 + fqids = default_fqids[ptype];
7069 + num_ranges = 3;
7070 + } else {
7071 + num_ranges = lenp / sizeof(*fqids);
7072 +
7073 + fqids = devm_kzalloc(dev, sizeof(*fqids) * num_ranges,
7074 + GFP_KERNEL);
7075 + if (fqids == NULL)
7076 + goto fqids_alloc_failed;
7077 +
7078 + /* convert to CPU endianess */
7079 + for (i = 0; i < num_ranges; i++) {
7080 + fqids[i].start = be32_to_cpup(fqids_off +
7081 + i * sizeof(*fqids));
7082 + fqids[i].count = be32_to_cpup(fqids_off +
7083 + i * sizeof(*fqids) + sizeof(__be32));
7084 + }
7085 + }
7086 +
7087 + for (i = 0; i < num_ranges; i++) {
7088 + switch (i) {
7089 + case 0:
7090 + /* The first queue is the error queue */
7091 + if (fqids[i].count != 1)
7092 + goto invalid_error_queue;
7093 +
7094 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7095 + fqids[i].count, list,
7096 + ptype == RX ?
7097 + FQ_TYPE_RX_ERROR :
7098 + FQ_TYPE_TX_ERROR);
7099 + if (dpa_fq == NULL)
7100 + goto fq_alloc_failed;
7101 +
7102 + if (ptype == RX)
7103 + port_fqs->rx_errq = &dpa_fq[0];
7104 + else
7105 + port_fqs->tx_errq = &dpa_fq[0];
7106 + break;
7107 + case 1:
7108 + /* the second queue is the default queue */
7109 + if (fqids[i].count != 1)
7110 + goto invalid_default_queue;
7111 +
7112 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7113 + fqids[i].count, list,
7114 + ptype == RX ?
7115 + FQ_TYPE_RX_DEFAULT :
7116 + FQ_TYPE_TX_CONFIRM);
7117 + if (dpa_fq == NULL)
7118 + goto fq_alloc_failed;
7119 +
7120 + if (ptype == RX)
7121 + port_fqs->rx_defq = &dpa_fq[0];
7122 + else
7123 + port_fqs->tx_defq = &dpa_fq[0];
7124 + break;
7125 + default:
7126 + /* all subsequent queues are either RX* PCD or Tx */
7127 + if (ptype == RX) {
7128 + if (!dpa_fq_alloc(dev, fqids[i].start,
7129 + fqids[i].count, list,
7130 + FQ_TYPE_RX_PCD) ||
7131 + !dpa_fq_alloc(dev, fqids[i].start,
7132 + fqids[i].count, list,
7133 + FQ_TYPE_RX_PCD_HI_PRIO))
7134 + goto fq_alloc_failed;
7135 + } else {
7136 + if (!dpa_fq_alloc(dev, fqids[i].start,
7137 + fqids[i].count, list,
7138 + FQ_TYPE_TX))
7139 + goto fq_alloc_failed;
7140 + }
7141 + break;
7142 + }
7143 + }
7144 +
7145 + return 0;
7146 +
7147 +fq_alloc_failed:
7148 +fqids_alloc_failed:
7149 + dev_err(dev, "Cannot allocate memory for frame queues\n");
7150 + return -ENOMEM;
7151 +
7152 +invalid_default_queue:
7153 +invalid_error_queue:
7154 + dev_err(dev, "Too many default or error queues\n");
7155 + return -EINVAL;
7156 +}
7157 +EXPORT_SYMBOL(dpa_fq_probe_mac);
7158 +
7159 +static u32 rx_pool_channel;
7160 +static DEFINE_SPINLOCK(rx_pool_channel_init);
7161 +
7162 +int dpa_get_channel(void)
7163 +{
7164 + spin_lock(&rx_pool_channel_init);
7165 + if (!rx_pool_channel) {
7166 + u32 pool;
7167 + int ret = qman_alloc_pool(&pool);
7168 + if (!ret)
7169 + rx_pool_channel = pool;
7170 + }
7171 + spin_unlock(&rx_pool_channel_init);
7172 + if (!rx_pool_channel)
7173 + return -ENOMEM;
7174 + return rx_pool_channel;
7175 +}
7176 +EXPORT_SYMBOL(dpa_get_channel);
7177 +
7178 +void dpa_release_channel(void)
7179 +{
7180 + qman_release_pool(rx_pool_channel);
7181 +}
7182 +EXPORT_SYMBOL(dpa_release_channel);
7183 +
7184 +void dpaa_eth_add_channel(u16 channel)
7185 +{
7186 + const cpumask_t *cpus = qman_affine_cpus();
7187 + u32 pool = QM_SDQCR_CHANNELS_POOL_CONV(channel);
7188 + int cpu;
7189 + struct qman_portal *portal;
7190 +
7191 + for_each_cpu(cpu, cpus) {
7192 + portal = (struct qman_portal *)qman_get_affine_portal(cpu);
7193 + qman_p_static_dequeue_add(portal, pool);
7194 + }
7195 +}
7196 +EXPORT_SYMBOL(dpaa_eth_add_channel);
7197 +
7198 +/**
7199 + * Congestion group state change notification callback.
7200 + * Stops the device's egress queues while they are congested and
7201 + * wakes them upon exiting congested state.
7202 + * Also updates some CGR-related stats.
7203 + */
7204 +static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr,
7205 +
7206 + int congested)
7207 +{
7208 + struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr,
7209 + struct dpa_priv_s, cgr_data.cgr);
7210 +
7211 + if (congested) {
7212 + priv->cgr_data.congestion_start_jiffies = jiffies;
7213 + netif_tx_stop_all_queues(priv->net_dev);
7214 + priv->cgr_data.cgr_congested_count++;
7215 + } else {
7216 + priv->cgr_data.congested_jiffies +=
7217 + (jiffies - priv->cgr_data.congestion_start_jiffies);
7218 + netif_tx_wake_all_queues(priv->net_dev);
7219 + }
7220 +}
7221 +
7222 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv)
7223 +{
7224 + struct qm_mcc_initcgr initcgr;
7225 + u32 cs_th;
7226 + int err;
7227 +
7228 + err = qman_alloc_cgrid(&priv->cgr_data.cgr.cgrid);
7229 + if (err < 0) {
7230 + pr_err("Error %d allocating CGR ID\n", err);
7231 + goto out_error;
7232 + }
7233 + priv->cgr_data.cgr.cb = dpaa_eth_cgscn;
7234 +
7235 + /* Enable Congestion State Change Notifications and CS taildrop */
7236 + initcgr.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES;
7237 + initcgr.cgr.cscn_en = QM_CGR_EN;
7238 +
7239 + /* Set different thresholds based on the MAC speed.
7240 + * TODO: this may turn suboptimal if the MAC is reconfigured at a speed
7241 + * lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link.
7242 + * In such cases, we ought to reconfigure the threshold, too.
7243 + */
7244 + if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
7245 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
7246 + else
7247 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
7248 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
7249 +
7250 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
7251 + initcgr.cgr.cstd_en = QM_CGR_EN;
7252 +
7253 + err = qman_create_cgr(&priv->cgr_data.cgr, QMAN_CGR_FLAG_USE_INIT,
7254 + &initcgr);
7255 + if (err < 0) {
7256 + pr_err("Error %d creating CGR with ID %d\n", err,
7257 + priv->cgr_data.cgr.cgrid);
7258 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
7259 + goto out_error;
7260 + }
7261 + pr_debug("Created CGR %d for netdev with hwaddr %pM on QMan channel %d\n",
7262 + priv->cgr_data.cgr.cgrid, priv->mac_dev->addr,
7263 + priv->cgr_data.cgr.chan);
7264 +
7265 +out_error:
7266 + return err;
7267 +}
7268 +EXPORT_SYMBOL(dpaa_eth_cgr_init);
7269 +
7270 +static inline void dpa_setup_ingress(const struct dpa_priv_s *priv,
7271 + struct dpa_fq *fq,
7272 + const struct qman_fq *template)
7273 +{
7274 + fq->fq_base = *template;
7275 + fq->net_dev = priv->net_dev;
7276 +
7277 + fq->flags = QMAN_FQ_FLAG_NO_ENQUEUE;
7278 + fq->channel = priv->channel;
7279 +}
7280 +
7281 +static inline void dpa_setup_egress(const struct dpa_priv_s *priv,
7282 + struct dpa_fq *fq,
7283 + struct fm_port *port,
7284 + const struct qman_fq *template)
7285 +{
7286 + fq->fq_base = *template;
7287 + fq->net_dev = priv->net_dev;
7288 +
7289 + if (port) {
7290 + fq->flags = QMAN_FQ_FLAG_TO_DCPORTAL;
7291 + fq->channel = (uint16_t)fm_get_tx_port_channel(port);
7292 + } else {
7293 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
7294 + }
7295 +}
7296 +
7297 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
7298 + struct fm_port *tx_port)
7299 +{
7300 + struct dpa_fq *fq;
7301 + uint16_t portals[NR_CPUS];
7302 + int cpu, portal_cnt = 0, num_portals = 0;
7303 + uint32_t pcd_fqid, pcd_fqid_hi_prio;
7304 + const cpumask_t *affine_cpus = qman_affine_cpus();
7305 + int egress_cnt = 0, conf_cnt = 0;
7306 +
7307 + /* Prepare for PCD FQs init */
7308 + for_each_cpu(cpu, affine_cpus)
7309 + portals[num_portals++] = qman_affine_channel(cpu);
7310 + if (num_portals == 0)
7311 + dev_err(priv->net_dev->dev.parent,
7312 + "No Qman software (affine) channels found");
7313 +
7314 + pcd_fqid = (priv->mac_dev) ?
7315 + DPAA_ETH_PCD_FQ_BASE(priv->mac_dev->res->start) : 0;
7316 + pcd_fqid_hi_prio = (priv->mac_dev) ?
7317 + DPAA_ETH_PCD_FQ_HI_PRIO_BASE(priv->mac_dev->res->start) : 0;
7318 +
7319 + /* Initialize each FQ in the list */
7320 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7321 + switch (fq->fq_type) {
7322 + case FQ_TYPE_RX_DEFAULT:
7323 + BUG_ON(!priv->mac_dev);
7324 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7325 + break;
7326 + case FQ_TYPE_RX_ERROR:
7327 + BUG_ON(!priv->mac_dev);
7328 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_errq);
7329 + break;
7330 + case FQ_TYPE_RX_PCD:
7331 + /* For MACless we can't have dynamic Rx queues */
7332 + BUG_ON(!priv->mac_dev && !fq->fqid);
7333 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7334 + if (!fq->fqid)
7335 + fq->fqid = pcd_fqid++;
7336 + fq->channel = portals[portal_cnt];
7337 + portal_cnt = (portal_cnt + 1) % num_portals;
7338 + break;
7339 + case FQ_TYPE_RX_PCD_HI_PRIO:
7340 + /* For MACless we can't have dynamic Hi Pri Rx queues */
7341 + BUG_ON(!priv->mac_dev && !fq->fqid);
7342 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7343 + if (!fq->fqid)
7344 + fq->fqid = pcd_fqid_hi_prio++;
7345 + fq->channel = portals[portal_cnt];
7346 + portal_cnt = (portal_cnt + 1) % num_portals;
7347 + break;
7348 + case FQ_TYPE_TX:
7349 + dpa_setup_egress(priv, fq, tx_port,
7350 + &fq_cbs->egress_ern);
7351 + /* If we have more Tx queues than the number of cores,
7352 + * just ignore the extra ones.
7353 + */
7354 + if (egress_cnt < DPAA_ETH_TX_QUEUES)
7355 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7356 + break;
7357 + case FQ_TYPE_TX_CONFIRM:
7358 + BUG_ON(!priv->mac_dev);
7359 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7360 + break;
7361 + case FQ_TYPE_TX_CONF_MQ:
7362 + BUG_ON(!priv->mac_dev);
7363 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7364 + priv->conf_fqs[conf_cnt++] = &fq->fq_base;
7365 + break;
7366 + case FQ_TYPE_TX_ERROR:
7367 + BUG_ON(!priv->mac_dev);
7368 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_errq);
7369 + break;
7370 + default:
7371 + dev_warn(priv->net_dev->dev.parent,
7372 + "Unknown FQ type detected!\n");
7373 + break;
7374 + }
7375 + }
7376 +
7377 + /* The number of Tx queues may be smaller than the number of cores, if
7378 + * the Tx queue range is specified in the device tree instead of being
7379 + * dynamically allocated.
7380 + * Make sure all CPUs receive a corresponding Tx queue.
7381 + */
7382 + while (egress_cnt < DPAA_ETH_TX_QUEUES) {
7383 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7384 + if (fq->fq_type != FQ_TYPE_TX)
7385 + continue;
7386 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7387 + if (egress_cnt == DPAA_ETH_TX_QUEUES)
7388 + break;
7389 + }
7390 + }
7391 +}
7392 +EXPORT_SYMBOL(dpa_fq_setup);
7393 +
7394 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
7395 +{
7396 + int _errno;
7397 + const struct dpa_priv_s *priv;
7398 + struct device *dev;
7399 + struct qman_fq *fq;
7400 + struct qm_mcc_initfq initfq;
7401 + struct qman_fq *confq;
7402 + int queue_id;
7403 +
7404 + priv = netdev_priv(dpa_fq->net_dev);
7405 + dev = dpa_fq->net_dev->dev.parent;
7406 +
7407 + if (dpa_fq->fqid == 0)
7408 + dpa_fq->flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
7409 +
7410 + dpa_fq->init = !(dpa_fq->flags & QMAN_FQ_FLAG_NO_MODIFY);
7411 +
7412 + _errno = qman_create_fq(dpa_fq->fqid, dpa_fq->flags, &dpa_fq->fq_base);
7413 + if (_errno) {
7414 + dev_err(dev, "qman_create_fq() failed\n");
7415 + return _errno;
7416 + }
7417 + fq = &dpa_fq->fq_base;
7418 +
7419 + if (dpa_fq->init) {
7420 + memset(&initfq, 0, sizeof(initfq));
7421 +
7422 + initfq.we_mask = QM_INITFQ_WE_FQCTRL;
7423 + /* FIXME: why would we want to keep an empty FQ in cache? */
7424 + initfq.fqd.fq_ctrl = QM_FQCTRL_PREFERINCACHE;
7425 +
7426 + /* Try to reduce the number of portal interrupts for
7427 + * Tx Confirmation FQs.
7428 + */
7429 + if (dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM)
7430 + initfq.fqd.fq_ctrl |= QM_FQCTRL_HOLDACTIVE;
7431 +
7432 + /* FQ placement */
7433 + initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
7434 +
7435 + initfq.fqd.dest.channel = dpa_fq->channel;
7436 + initfq.fqd.dest.wq = dpa_fq->wq;
7437 +
7438 + /* Put all egress queues in a congestion group of their own.
7439 + * Sensu stricto, the Tx confirmation queues are Rx FQs,
7440 + * rather than Tx - but they nonetheless account for the
7441 + * memory footprint on behalf of egress traffic. We therefore
7442 + * place them in the netdev's CGR, along with the Tx FQs.
7443 + */
7444 + if (dpa_fq->fq_type == FQ_TYPE_TX ||
7445 + dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM ||
7446 + dpa_fq->fq_type == FQ_TYPE_TX_CONF_MQ) {
7447 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7448 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7449 + initfq.fqd.cgid = (uint8_t)priv->cgr_data.cgr.cgrid;
7450 + /* Set a fixed overhead accounting, in an attempt to
7451 + * reduce the impact of fixed-size skb shells and the
7452 + * driver's needed headroom on system memory. This is
7453 + * especially the case when the egress traffic is
7454 + * composed of small datagrams.
7455 + * Unfortunately, QMan's OAL value is capped to an
7456 + * insufficient value, but even that is better than
7457 + * no overhead accounting at all.
7458 + */
7459 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7460 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7461 + initfq.fqd.oac_init.oal =
7462 + (signed char)(min(sizeof(struct sk_buff) +
7463 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7464 + }
7465 +
7466 + if (td_enable) {
7467 + initfq.we_mask |= QM_INITFQ_WE_TDTHRESH;
7468 + qm_fqd_taildrop_set(&initfq.fqd.td,
7469 + DPA_FQ_TD, 1);
7470 + initfq.fqd.fq_ctrl = QM_FQCTRL_TDE;
7471 + }
7472 +
7473 + /* Configure the Tx confirmation queue, now that we know
7474 + * which Tx queue it pairs with.
7475 + */
7476 + if (dpa_fq->fq_type == FQ_TYPE_TX) {
7477 + queue_id = _dpa_tx_fq_to_id(priv, &dpa_fq->fq_base);
7478 + if (queue_id >= 0) {
7479 + confq = priv->conf_fqs[queue_id];
7480 + if (confq) {
7481 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7482 + /* ContextA: OVOM=1 (use contextA2 bits instead of ICAD)
7483 + * A2V=1 (contextA A2 field is valid)
7484 + * A0V=1 (contextA A0 field is valid)
7485 + * B0V=1 (contextB field is valid)
7486 + * ContextA A2: EBD=1 (deallocate buffers inside FMan)
7487 + * ContextB B0(ASPID): 0 (absolute Virtual Storage ID)
7488 + */
7489 + initfq.fqd.context_a.hi = 0x1e000000;
7490 + initfq.fqd.context_a.lo = 0x80000000;
7491 + }
7492 + }
7493 + }
7494 +
7495 + /* Put all *private* ingress queues in our "ingress CGR". */
7496 + if (priv->use_ingress_cgr &&
7497 + (dpa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
7498 + dpa_fq->fq_type == FQ_TYPE_RX_ERROR ||
7499 + dpa_fq->fq_type == FQ_TYPE_RX_PCD ||
7500 + dpa_fq->fq_type == FQ_TYPE_RX_PCD_HI_PRIO)) {
7501 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7502 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7503 + initfq.fqd.cgid = (uint8_t)priv->ingress_cgr.cgrid;
7504 + /* Set a fixed overhead accounting, just like for the
7505 + * egress CGR.
7506 + */
7507 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7508 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7509 + initfq.fqd.oac_init.oal =
7510 + (signed char)(min(sizeof(struct sk_buff) +
7511 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7512 + }
7513 +
7514 + /* Initialization common to all ingress queues */
7515 + if (dpa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) {
7516 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7517 + initfq.fqd.fq_ctrl |=
7518 + QM_FQCTRL_CTXASTASHING | QM_FQCTRL_AVOIDBLOCK;
7519 + initfq.fqd.context_a.stashing.exclusive =
7520 + QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX |
7521 + QM_STASHING_EXCL_ANNOTATION;
7522 + initfq.fqd.context_a.stashing.data_cl = 2;
7523 + initfq.fqd.context_a.stashing.annotation_cl = 1;
7524 + initfq.fqd.context_a.stashing.context_cl =
7525 + DIV_ROUND_UP(sizeof(struct qman_fq), 64);
7526 + }
7527 +
7528 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
7529 + if (_errno < 0) {
7530 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno)) {
7531 + dpa_fq->init = 0;
7532 + } else {
7533 + dev_err(dev, "qman_init_fq(%u) = %d\n",
7534 + qman_fq_fqid(fq), _errno);
7535 + qman_destroy_fq(fq, 0);
7536 + }
7537 + return _errno;
7538 + }
7539 + }
7540 +
7541 + dpa_fq->fqid = qman_fq_fqid(fq);
7542 +
7543 + return 0;
7544 +}
7545 +EXPORT_SYMBOL(dpa_fq_init);
7546 +
7547 +int __cold __attribute__((nonnull))
7548 +_dpa_fq_free(struct device *dev, struct qman_fq *fq)
7549 +{
7550 + int _errno, __errno;
7551 + struct dpa_fq *dpa_fq;
7552 + const struct dpa_priv_s *priv;
7553 +
7554 + _errno = 0;
7555 +
7556 + dpa_fq = container_of(fq, struct dpa_fq, fq_base);
7557 + priv = netdev_priv(dpa_fq->net_dev);
7558 +
7559 + if (dpa_fq->init) {
7560 + _errno = qman_retire_fq(fq, NULL);
7561 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
7562 + dev_err(dev, "qman_retire_fq(%u) = %d\n",
7563 + qman_fq_fqid(fq), _errno);
7564 +
7565 + __errno = qman_oos_fq(fq);
7566 + if (unlikely(__errno < 0) && netif_msg_drv(priv)) {
7567 + dev_err(dev, "qman_oos_fq(%u) = %d\n",
7568 + qman_fq_fqid(fq), __errno);
7569 + if (_errno >= 0)
7570 + _errno = __errno;
7571 + }
7572 + }
7573 +
7574 + qman_destroy_fq(fq, 0);
7575 + list_del(&dpa_fq->list);
7576 +
7577 + return _errno;
7578 +}
7579 +EXPORT_SYMBOL(_dpa_fq_free);
7580 +
7581 +int __cold __attribute__((nonnull))
7582 +dpa_fq_free(struct device *dev, struct list_head *list)
7583 +{
7584 + int _errno, __errno;
7585 + struct dpa_fq *dpa_fq, *tmp;
7586 +
7587 + _errno = 0;
7588 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7589 + __errno = _dpa_fq_free(dev, (struct qman_fq *)dpa_fq);
7590 + if (unlikely(__errno < 0) && _errno >= 0)
7591 + _errno = __errno;
7592 + }
7593 +
7594 + return _errno;
7595 +}
7596 +EXPORT_SYMBOL(dpa_fq_free);
7597 +
7598 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable)
7599 +{
7600 + int _errno, __errno;
7601 + struct dpa_fq *dpa_fq, *tmp;
7602 + static bool print_msg __read_mostly;
7603 +
7604 + _errno = 0;
7605 + print_msg = true;
7606 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7607 + __errno = dpa_fq_init(dpa_fq, td_enable);
7608 + if (unlikely(__errno < 0) && _errno >= 0) {
7609 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, __errno)) {
7610 + if (print_msg) {
7611 + dev_warn(dev,
7612 + "Skip RX PCD High Priority FQs initialization\n");
7613 + print_msg = false;
7614 + }
7615 + if (_dpa_fq_free(dev, (struct qman_fq *)dpa_fq))
7616 + dev_warn(dev,
7617 + "Error freeing frame queues\n");
7618 + } else {
7619 + _errno = __errno;
7620 + break;
7621 + }
7622 + }
7623 + }
7624 +
7625 + return _errno;
7626 +}
7627 +EXPORT_SYMBOL(dpa_fqs_init);
7628 +static void
7629 +dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq,
7630 + struct dpa_fq *defq, struct dpa_buffer_layout_s *buf_layout)
7631 +{
7632 + struct fm_port_params tx_port_param;
7633 + bool frag_enabled = false;
7634 +
7635 + memset(&tx_port_param, 0, sizeof(tx_port_param));
7636 + dpaa_eth_init_port(tx, port, tx_port_param, errq->fqid, defq->fqid,
7637 + buf_layout, frag_enabled);
7638 +}
7639 +
7640 +static void
7641 +dpaa_eth_init_rx_port(struct fm_port *port, struct dpa_bp *bp, size_t count,
7642 + struct dpa_fq *errq, struct dpa_fq *defq,
7643 + struct dpa_buffer_layout_s *buf_layout)
7644 +{
7645 + struct fm_port_params rx_port_param;
7646 + int i;
7647 + bool frag_enabled = false;
7648 +
7649 + memset(&rx_port_param, 0, sizeof(rx_port_param));
7650 + count = min(ARRAY_SIZE(rx_port_param.pool_param), count);
7651 + rx_port_param.num_pools = (uint8_t)count;
7652 + for (i = 0; i < count; i++) {
7653 + if (i >= rx_port_param.num_pools)
7654 + break;
7655 + rx_port_param.pool_param[i].id = bp[i].bpid;
7656 + rx_port_param.pool_param[i].size = (uint16_t)bp[i].size;
7657 + }
7658 +
7659 + dpaa_eth_init_port(rx, port, rx_port_param, errq->fqid, defq->fqid,
7660 + buf_layout, frag_enabled);
7661 +}
7662 +
7663 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
7664 +/* Defined as weak, to be implemented by fman pcd tester. */
7665 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *)
7666 +__attribute__((weak));
7667 +
7668 +int dpa_free_pcd_fqids(struct device *, uint32_t) __attribute__((weak));
7669 +#else
7670 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *);
7671 +
7672 +int dpa_free_pcd_fqids(struct device *, uint32_t);
7673 +
7674 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
7675 +
7676 +
7677 +int dpa_alloc_pcd_fqids(struct device *dev, uint32_t num,
7678 + uint8_t alignment, uint32_t *base_fqid)
7679 +{
7680 + dev_crit(dev, "callback not implemented!\n");
7681 +
7682 + return 0;
7683 +}
7684 +
7685 +int dpa_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
7686 +{
7687 +
7688 + dev_crit(dev, "callback not implemented!\n");
7689 +
7690 + return 0;
7691 +}
7692 +
7693 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
7694 + struct dpa_bp *bp, size_t count,
7695 + struct fm_port_fqs *port_fqs,
7696 + struct dpa_buffer_layout_s *buf_layout,
7697 + struct device *dev)
7698 +{
7699 + struct fm_port_pcd_param rx_port_pcd_param;
7700 + struct fm_port *rxport = mac_dev->port_dev[RX];
7701 + struct fm_port *txport = mac_dev->port_dev[TX];
7702 +
7703 + dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
7704 + port_fqs->tx_defq, &buf_layout[TX]);
7705 + dpaa_eth_init_rx_port(rxport, bp, count, port_fqs->rx_errq,
7706 + port_fqs->rx_defq, &buf_layout[RX]);
7707 +
7708 + rx_port_pcd_param.cba = dpa_alloc_pcd_fqids;
7709 + rx_port_pcd_param.cbf = dpa_free_pcd_fqids;
7710 + rx_port_pcd_param.dev = dev;
7711 + fm_port_pcd_bind(rxport, &rx_port_pcd_param);
7712 +}
7713 +EXPORT_SYMBOL(dpaa_eth_init_ports);
7714 +
7715 +void dpa_release_sgt(struct qm_sg_entry *sgt)
7716 +{
7717 + struct dpa_bp *dpa_bp;
7718 + struct bm_buffer bmb[DPA_BUFF_RELEASE_MAX];
7719 + uint8_t i = 0, j;
7720 +
7721 + memset(bmb, 0, DPA_BUFF_RELEASE_MAX * sizeof(struct bm_buffer));
7722 +
7723 + do {
7724 + dpa_bp = dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i]));
7725 + DPA_BUG_ON(!dpa_bp);
7726 +
7727 + j = 0;
7728 + do {
7729 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
7730 + bm_buffer_set64(&bmb[j], qm_sg_addr(&sgt[i]));
7731 +
7732 + j++; i++;
7733 + } while (j < ARRAY_SIZE(bmb) &&
7734 + !qm_sg_entry_get_final(&sgt[i-1]) &&
7735 + qm_sg_entry_get_bpid(&sgt[i-1]) ==
7736 + qm_sg_entry_get_bpid(&sgt[i]));
7737 +
7738 + while (bman_release(dpa_bp->pool, bmb, j, 0))
7739 + cpu_relax();
7740 + } while (!qm_sg_entry_get_final(&sgt[i-1]));
7741 +}
7742 +EXPORT_SYMBOL(dpa_release_sgt);
7743 +
7744 +void __attribute__((nonnull))
7745 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd)
7746 +{
7747 + struct qm_sg_entry *sgt;
7748 + struct dpa_bp *dpa_bp;
7749 + struct bm_buffer bmb;
7750 + dma_addr_t addr;
7751 + void *vaddr;
7752 +
7753 + bmb.opaque = 0;
7754 + bm_buffer_set64(&bmb, qm_fd_addr(fd));
7755 +
7756 + dpa_bp = dpa_bpid2pool(fd->bpid);
7757 + DPA_BUG_ON(!dpa_bp);
7758 +
7759 + if (fd->format == qm_fd_sg) {
7760 + vaddr = phys_to_virt(qm_fd_addr(fd));
7761 + sgt = vaddr + dpa_fd_offset(fd);
7762 +
7763 + dma_unmap_single(dpa_bp->dev, qm_fd_addr(fd), dpa_bp->size,
7764 + DMA_BIDIRECTIONAL);
7765 +
7766 + dpa_release_sgt(sgt);
7767 + addr = dma_map_single(dpa_bp->dev, vaddr, dpa_bp->size,
7768 + DMA_BIDIRECTIONAL);
7769 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
7770 + dev_err(dpa_bp->dev, "DMA mapping failed");
7771 + return;
7772 + }
7773 + bm_buffer_set64(&bmb, addr);
7774 + }
7775 +
7776 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
7777 + cpu_relax();
7778 +}
7779 +EXPORT_SYMBOL(dpa_fd_release);
7780 +
7781 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
7782 + const struct qm_mr_entry *msg)
7783 +{
7784 + switch (msg->ern.rc & QM_MR_RC_MASK) {
7785 + case QM_MR_RC_CGR_TAILDROP:
7786 + percpu_priv->ern_cnt.cg_tdrop++;
7787 + break;
7788 + case QM_MR_RC_WRED:
7789 + percpu_priv->ern_cnt.wred++;
7790 + break;
7791 + case QM_MR_RC_ERROR:
7792 + percpu_priv->ern_cnt.err_cond++;
7793 + break;
7794 + case QM_MR_RC_ORPWINDOW_EARLY:
7795 + percpu_priv->ern_cnt.early_window++;
7796 + break;
7797 + case QM_MR_RC_ORPWINDOW_LATE:
7798 + percpu_priv->ern_cnt.late_window++;
7799 + break;
7800 + case QM_MR_RC_FQ_TAILDROP:
7801 + percpu_priv->ern_cnt.fq_tdrop++;
7802 + break;
7803 + case QM_MR_RC_ORPWINDOW_RETIRED:
7804 + percpu_priv->ern_cnt.fq_retired++;
7805 + break;
7806 + case QM_MR_RC_ORP_ZERO:
7807 + percpu_priv->ern_cnt.orp_zero++;
7808 + break;
7809 + }
7810 +}
7811 +EXPORT_SYMBOL(count_ern);
7812 +
7813 +/**
7814 + * Turn on HW checksum computation for this outgoing frame.
7815 + * If the current protocol is not something we support in this regard
7816 + * (or if the stack has already computed the SW checksum), we do nothing.
7817 + *
7818 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
7819 + * otherwise.
7820 + *
7821 + * Note that this function may modify the fd->cmd field and the skb data buffer
7822 + * (the Parse Results area).
7823 + */
7824 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
7825 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results)
7826 +{
7827 + fm_prs_result_t *parse_result;
7828 + struct iphdr *iph;
7829 + struct ipv6hdr *ipv6h = NULL;
7830 + u8 l4_proto;
7831 + u16 ethertype = ntohs(skb->protocol);
7832 + int retval = 0;
7833 +
7834 + if (skb->ip_summed != CHECKSUM_PARTIAL)
7835 + return 0;
7836 +
7837 + /* Note: L3 csum seems to be already computed in sw, but we can't choose
7838 + * L4 alone from the FM configuration anyway.
7839 + */
7840 +
7841 + /* Fill in some fields of the Parse Results array, so the FMan
7842 + * can find them as if they came from the FMan Parser.
7843 + */
7844 + parse_result = (fm_prs_result_t *)parse_results;
7845 +
7846 + /* If we're dealing with VLAN, get the real Ethernet type */
7847 + if (ethertype == ETH_P_8021Q) {
7848 + /* We can't always assume the MAC header is set correctly
7849 + * by the stack, so reset to beginning of skb->data
7850 + */
7851 + skb_reset_mac_header(skb);
7852 + ethertype = ntohs(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
7853 + }
7854 +
7855 + /* Fill in the relevant L3 parse result fields
7856 + * and read the L4 protocol type
7857 + */
7858 + switch (ethertype) {
7859 + case ETH_P_IP:
7860 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV4);
7861 + iph = ip_hdr(skb);
7862 + DPA_BUG_ON(iph == NULL);
7863 + l4_proto = iph->protocol;
7864 + break;
7865 + case ETH_P_IPV6:
7866 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV6);
7867 + ipv6h = ipv6_hdr(skb);
7868 + DPA_BUG_ON(ipv6h == NULL);
7869 + l4_proto = ipv6h->nexthdr;
7870 + break;
7871 + default:
7872 + /* We shouldn't even be here */
7873 + if (netif_msg_tx_err(priv) && net_ratelimit())
7874 + netdev_alert(priv->net_dev,
7875 + "Can't compute HW csum for L3 proto 0x%x\n",
7876 + ntohs(skb->protocol));
7877 + retval = -EIO;
7878 + goto return_error;
7879 + }
7880 +
7881 + /* Fill in the relevant L4 parse result fields */
7882 + switch (l4_proto) {
7883 + case IPPROTO_UDP:
7884 + parse_result->l4r = FM_L4_PARSE_RESULT_UDP;
7885 + break;
7886 + case IPPROTO_TCP:
7887 + parse_result->l4r = FM_L4_PARSE_RESULT_TCP;
7888 + break;
7889 + default:
7890 + /* This can as well be a BUG() */
7891 + if (netif_msg_tx_err(priv) && net_ratelimit())
7892 + netdev_alert(priv->net_dev,
7893 + "Can't compute HW csum for L4 proto 0x%x\n",
7894 + l4_proto);
7895 + retval = -EIO;
7896 + goto return_error;
7897 + }
7898 +
7899 + /* At index 0 is IPOffset_1 as defined in the Parse Results */
7900 + parse_result->ip_off[0] = (uint8_t)skb_network_offset(skb);
7901 + parse_result->l4_off = (uint8_t)skb_transport_offset(skb);
7902 +
7903 + /* Enable L3 (and L4, if TCP or UDP) HW checksum. */
7904 + fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
7905 +
7906 + /* On P1023 and similar platforms fd->cmd interpretation could
7907 + * be disabled by setting CONTEXT_A bit ICMD; currently this bit
7908 + * is not set so we do not need to check; in the future, if/when
7909 + * using context_a we need to check this bit
7910 + */
7911 +
7912 +return_error:
7913 + return retval;
7914 +}
7915 +EXPORT_SYMBOL(dpa_enable_tx_csum);
7916 +
7917 +#ifdef CONFIG_FSL_DPAA_CEETM
7918 +void dpa_enable_ceetm(struct net_device *dev)
7919 +{
7920 + struct dpa_priv_s *priv = netdev_priv(dev);
7921 + priv->ceetm_en = true;
7922 +}
7923 +EXPORT_SYMBOL(dpa_enable_ceetm);
7924 +
7925 +void dpa_disable_ceetm(struct net_device *dev)
7926 +{
7927 + struct dpa_priv_s *priv = netdev_priv(dev);
7928 + priv->ceetm_en = false;
7929 +}
7930 +EXPORT_SYMBOL(dpa_disable_ceetm);
7931 +#endif
7932 --- /dev/null
7933 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
7934 @@ -0,0 +1,225 @@
7935 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
7936 + *
7937 + * Redistribution and use in source and binary forms, with or without
7938 + * modification, are permitted provided that the following conditions are met:
7939 + * * Redistributions of source code must retain the above copyright
7940 + * notice, this list of conditions and the following disclaimer.
7941 + * * Redistributions in binary form must reproduce the above copyright
7942 + * notice, this list of conditions and the following disclaimer in the
7943 + * documentation and/or other materials provided with the distribution.
7944 + * * Neither the name of Freescale Semiconductor nor the
7945 + * names of its contributors may be used to endorse or promote products
7946 + * derived from this software without specific prior written permission.
7947 + *
7948 + *
7949 + * ALTERNATIVELY, this software may be distributed under the terms of the
7950 + * GNU General Public License ("GPL") as published by the Free Software
7951 + * Foundation, either version 2 of that License or (at your option) any
7952 + * later version.
7953 + *
7954 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
7955 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7956 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7957 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
7958 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7959 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7960 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7961 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7962 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7963 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7964 + */
7965 +
7966 +#ifndef __DPAA_ETH_COMMON_H
7967 +#define __DPAA_ETH_COMMON_H
7968 +
7969 +#include <linux/etherdevice.h> /* struct net_device */
7970 +#include <linux/fsl_bman.h> /* struct bm_buffer */
7971 +#include <linux/of_platform.h> /* struct platform_device */
7972 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
7973 +
7974 +#include "dpaa_eth.h"
7975 +#include "lnxwrp_fsl_fman.h"
7976 +
7977 +#define dpaa_eth_init_port(type, port, param, errq_id, defq_id, buf_layout,\
7978 + frag_enabled) \
7979 +{ \
7980 + param.errq = errq_id; \
7981 + param.defq = defq_id; \
7982 + param.priv_data_size = buf_layout->priv_data_size; \
7983 + param.parse_results = buf_layout->parse_results; \
7984 + param.hash_results = buf_layout->hash_results; \
7985 + param.frag_enable = frag_enabled; \
7986 + param.time_stamp = buf_layout->time_stamp; \
7987 + param.manip_extra_space = buf_layout->manip_extra_space; \
7988 + param.data_align = buf_layout->data_align; \
7989 + fm_set_##type##_port_params(port, &param); \
7990 +}
7991 +
7992 +#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */
7993 +
7994 +#define DPA_SGT_ENTRIES_THRESHOLD DPA_SGT_MAX_ENTRIES
7995 +
7996 +#define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */
7997 +
7998 +#define DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno) \
7999 + (((dpa_fq)->fq_type == FQ_TYPE_RX_PCD_HI_PRIO) && \
8000 + (_errno == -EIO))
8001 +/* return codes for the dpaa-eth hooks */
8002 +enum dpaa_eth_hook_result {
8003 + /* fd/skb was retained by the hook.
8004 + *
8005 + * On the Rx path, this means the Ethernet driver will _not_
8006 + * deliver the skb to the stack. Instead, the hook implementation
8007 + * is expected to properly dispose of the skb.
8008 + *
8009 + * On the Tx path, the Ethernet driver's dpa_tx() function will
8010 + * immediately return NETDEV_TX_OK. The hook implementation is expected
8011 + * to free the skb. *DO*NOT* release it to BMan, or enqueue it to FMan,
8012 + * unless you know exactly what you're doing!
8013 + *
8014 + * On the confirmation/error paths, the Ethernet driver will _not_
8015 + * perform any fd cleanup, nor update the interface statistics.
8016 + */
8017 + DPAA_ETH_STOLEN,
8018 + /* fd/skb was returned to the Ethernet driver for regular processing.
8019 + * The hook is not allowed to, for instance, reallocate the skb (as if
8020 + * by linearizing, copying, cloning or reallocating the headroom).
8021 + */
8022 + DPAA_ETH_CONTINUE
8023 +};
8024 +
8025 +typedef enum dpaa_eth_hook_result (*dpaa_eth_ingress_hook_t)(
8026 + struct sk_buff *skb, struct net_device *net_dev, u32 fqid);
8027 +typedef enum dpaa_eth_hook_result (*dpaa_eth_egress_hook_t)(
8028 + struct sk_buff *skb, struct net_device *net_dev);
8029 +typedef enum dpaa_eth_hook_result (*dpaa_eth_confirm_hook_t)(
8030 + struct net_device *net_dev, const struct qm_fd *fd, u32 fqid);
8031 +
8032 +/* used in napi related functions */
8033 +extern u16 qman_portal_max;
8034 +
8035 +/* from dpa_ethtool.c */
8036 +extern const struct ethtool_ops dpa_ethtool_ops;
8037 +
8038 +#ifdef CONFIG_FSL_DPAA_HOOKS
8039 +/* Various hooks used for unit-testing and/or fastpath optimizations.
8040 + * Currently only one set of such hooks is supported.
8041 + */
8042 +struct dpaa_eth_hooks_s {
8043 + /* Invoked on the Tx private path, immediately after receiving the skb
8044 + * from the stack.
8045 + */
8046 + dpaa_eth_egress_hook_t tx;
8047 +
8048 + /* Invoked on the Rx private path, right before passing the skb
8049 + * up the stack. At that point, the packet's protocol id has already
8050 + * been set. The skb's data pointer is now at the L3 header, and
8051 + * skb->mac_header points to the L2 header. skb->len has been adjusted
8052 + * to be the length of L3+payload (i.e., the length of the
8053 + * original frame minus the L2 header len).
8054 + * For more details on what the skb looks like, see eth_type_trans().
8055 + */
8056 + dpaa_eth_ingress_hook_t rx_default;
8057 +
8058 + /* Driver hook for the Rx error private path. */
8059 + dpaa_eth_confirm_hook_t rx_error;
8060 + /* Driver hook for the Tx confirmation private path. */
8061 + dpaa_eth_confirm_hook_t tx_confirm;
8062 + /* Driver hook for the Tx error private path. */
8063 + dpaa_eth_confirm_hook_t tx_error;
8064 +};
8065 +
8066 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks);
8067 +
8068 +extern struct dpaa_eth_hooks_s dpaa_eth_hooks;
8069 +#endif
8070 +
8071 +int dpa_netdev_init(struct net_device *net_dev,
8072 + const uint8_t *mac_addr,
8073 + uint16_t tx_timeout);
8074 +int __cold dpa_start(struct net_device *net_dev);
8075 +int __cold dpa_stop(struct net_device *net_dev);
8076 +void __cold dpa_timeout(struct net_device *net_dev);
8077 +void __cold
8078 +dpa_get_stats64(struct net_device *net_dev,
8079 + struct rtnl_link_stats64 *stats);
8080 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu);
8081 +int dpa_ndo_init(struct net_device *net_dev);
8082 +int dpa_set_features(struct net_device *dev, netdev_features_t features);
8083 +netdev_features_t dpa_fix_features(struct net_device *dev,
8084 + netdev_features_t features);
8085 +#ifdef CONFIG_FSL_DPAA_TS
8086 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv,
8087 + enum port_type rx_tx, const void *data);
8088 +/* Updates the skb shared hw timestamp from the hardware timestamp */
8089 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
8090 + struct skb_shared_hwtstamps *shhwtstamps, const void *data);
8091 +#endif /* CONFIG_FSL_DPAA_TS */
8092 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
8093 +int __cold dpa_remove(struct platform_device *of_dev);
8094 +struct mac_device * __cold __must_check
8095 +__attribute__((nonnull)) dpa_mac_probe(struct platform_device *_of_dev);
8096 +int dpa_set_mac_address(struct net_device *net_dev, void *addr);
8097 +void dpa_set_rx_mode(struct net_device *net_dev);
8098 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
8099 + struct dpa_buffer_layout_s *layout);
8100 +int __attribute__((nonnull))
8101 +dpa_bp_alloc(struct dpa_bp *dpa_bp);
8102 +void __cold __attribute__((nonnull))
8103 +dpa_bp_free(struct dpa_priv_s *priv);
8104 +struct dpa_bp *dpa_bpid2pool(int bpid);
8105 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp);
8106 +bool dpa_bpid2pool_use(int bpid);
8107 +void dpa_bp_drain(struct dpa_bp *bp);
8108 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
8109 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
8110 + void *accel_priv, select_queue_fallback_t fallback);
8111 +#endif
8112 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
8113 + u32 fq_start,
8114 + u32 fq_count,
8115 + struct list_head *list,
8116 + enum dpa_fq_type fq_type);
8117 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
8118 + struct fm_port_fqs *port_fqs,
8119 + bool tx_conf_fqs_per_core,
8120 + enum port_type ptype);
8121 +int dpa_get_channel(void);
8122 +void dpa_release_channel(void);
8123 +void dpaa_eth_add_channel(u16 channel);
8124 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv);
8125 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
8126 + struct fm_port *tx_port);
8127 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable);
8128 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable);
8129 +int __cold __attribute__((nonnull))
8130 +dpa_fq_free(struct device *dev, struct list_head *list);
8131 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
8132 + struct dpa_bp *bp, size_t count,
8133 + struct fm_port_fqs *port_fqs,
8134 + struct dpa_buffer_layout_s *buf_layout,
8135 + struct device *dev);
8136 +void dpa_release_sgt(struct qm_sg_entry *sgt);
8137 +void __attribute__((nonnull))
8138 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd);
8139 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
8140 + const struct qm_mr_entry *msg);
8141 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
8142 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
8143 +#ifdef CONFIG_FSL_DPAA_CEETM
8144 +void dpa_enable_ceetm(struct net_device *dev);
8145 +void dpa_disable_ceetm(struct net_device *dev);
8146 +#endif
8147 +struct proxy_device {
8148 + struct mac_device *mac_dev;
8149 +};
8150 +
8151 +/* mac device control functions exposed by proxy interface*/
8152 +int dpa_proxy_start(struct net_device *net_dev);
8153 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev);
8154 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8155 + struct net_device *net_dev);
8156 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8157 + struct net_device *net_dev);
8158 +
8159 +#endif /* __DPAA_ETH_COMMON_H */
8160 --- /dev/null
8161 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
8162 @@ -0,0 +1,381 @@
8163 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
8164 + *
8165 + * Redistribution and use in source and binary forms, with or without
8166 + * modification, are permitted provided that the following conditions are met:
8167 + * * Redistributions of source code must retain the above copyright
8168 + * notice, this list of conditions and the following disclaimer.
8169 + * * Redistributions in binary form must reproduce the above copyright
8170 + * notice, this list of conditions and the following disclaimer in the
8171 + * documentation and/or other materials provided with the distribution.
8172 + * * Neither the name of Freescale Semiconductor nor the
8173 + * names of its contributors may be used to endorse or promote products
8174 + * derived from this software without specific prior written permission.
8175 + *
8176 + *
8177 + * ALTERNATIVELY, this software may be distributed under the terms of the
8178 + * GNU General Public License ("GPL") as published by the Free Software
8179 + * Foundation, either version 2 of that License or (at your option) any
8180 + * later version.
8181 + *
8182 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8183 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8184 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8185 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8186 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8187 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8188 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8189 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8190 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8191 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8192 + */
8193 +
8194 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8195 +#define pr_fmt(fmt) \
8196 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8197 + KBUILD_BASENAME".c", __LINE__, __func__
8198 +#else
8199 +#define pr_fmt(fmt) \
8200 + KBUILD_MODNAME ": " fmt
8201 +#endif
8202 +
8203 +#include <linux/init.h>
8204 +#include <linux/module.h>
8205 +#include <linux/of_platform.h>
8206 +#include "dpaa_eth.h"
8207 +#include "dpaa_eth_common.h"
8208 +#include "dpaa_eth_base.h"
8209 +#include "lnxwrp_fsl_fman.h" /* fm_get_rx_extra_headroom(), fm_get_max_frm() */
8210 +#include "mac.h"
8211 +
8212 +#define DPA_DESCRIPTION "FSL DPAA Proxy initialization driver"
8213 +
8214 +MODULE_LICENSE("Dual BSD/GPL");
8215 +
8216 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
8217 +
8218 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev);
8219 +#ifdef CONFIG_PM
8220 +
8221 +static int proxy_suspend(struct device *dev)
8222 +{
8223 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8224 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8225 + int err = 0;
8226 +
8227 + err = fm_port_suspend(mac_dev->port_dev[RX]);
8228 + if (err)
8229 + goto port_suspend_failed;
8230 +
8231 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8232 + if (err)
8233 + err = fm_port_resume(mac_dev->port_dev[RX]);
8234 +
8235 +port_suspend_failed:
8236 + return err;
8237 +}
8238 +
8239 +static int proxy_resume(struct device *dev)
8240 +{
8241 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8242 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8243 + int err = 0;
8244 +
8245 + err = fm_port_resume(mac_dev->port_dev[TX]);
8246 + if (err)
8247 + goto port_resume_failed;
8248 +
8249 + err = fm_port_resume(mac_dev->port_dev[RX]);
8250 + if (err)
8251 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8252 +
8253 +port_resume_failed:
8254 + return err;
8255 +}
8256 +
8257 +static const struct dev_pm_ops proxy_pm_ops = {
8258 + .suspend = proxy_suspend,
8259 + .resume = proxy_resume,
8260 +};
8261 +
8262 +#define PROXY_PM_OPS (&proxy_pm_ops)
8263 +
8264 +#else /* CONFIG_PM */
8265 +
8266 +#define PROXY_PM_OPS NULL
8267 +
8268 +#endif /* CONFIG_PM */
8269 +
8270 +static int dpaa_eth_proxy_probe(struct platform_device *_of_dev)
8271 +{
8272 + int err = 0, i;
8273 + struct device *dev;
8274 + struct device_node *dpa_node;
8275 + struct dpa_bp *dpa_bp;
8276 + struct list_head proxy_fq_list;
8277 + size_t count;
8278 + struct fm_port_fqs port_fqs;
8279 + struct dpa_buffer_layout_s *buf_layout = NULL;
8280 + struct mac_device *mac_dev;
8281 + struct proxy_device *proxy_dev;
8282 +
8283 + dev = &_of_dev->dev;
8284 +
8285 + dpa_node = dev->of_node;
8286 +
8287 + if (!of_device_is_available(dpa_node))
8288 + return -ENODEV;
8289 +
8290 + /* Get the buffer pools assigned to this interface */
8291 + dpa_bp = dpa_bp_probe(_of_dev, &count);
8292 + if (IS_ERR(dpa_bp))
8293 + return PTR_ERR(dpa_bp);
8294 +
8295 + mac_dev = dpa_mac_probe(_of_dev);
8296 + if (IS_ERR(mac_dev))
8297 + return PTR_ERR(mac_dev);
8298 +
8299 + proxy_dev = devm_kzalloc(dev, sizeof(*proxy_dev), GFP_KERNEL);
8300 + if (!proxy_dev) {
8301 + dev_err(dev, "devm_kzalloc() failed\n");
8302 + return -ENOMEM;
8303 + }
8304 +
8305 + proxy_dev->mac_dev = mac_dev;
8306 + dev_set_drvdata(dev, proxy_dev);
8307 +
8308 + /* We have physical ports, so we need to establish
8309 + * the buffer layout.
8310 + */
8311 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
8312 + GFP_KERNEL);
8313 + if (!buf_layout) {
8314 + dev_err(dev, "devm_kzalloc() failed\n");
8315 + return -ENOMEM;
8316 + }
8317 + dpa_set_buffers_layout(mac_dev, buf_layout);
8318 +
8319 + INIT_LIST_HEAD(&proxy_fq_list);
8320 +
8321 + memset(&port_fqs, 0, sizeof(port_fqs));
8322 +
8323 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true, RX);
8324 + if (!err)
8325 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true,
8326 + TX);
8327 + if (err < 0) {
8328 + devm_kfree(dev, buf_layout);
8329 + return err;
8330 + }
8331 +
8332 + /* Proxy initializer - Just configures the MAC on behalf of
8333 + * another partition.
8334 + */
8335 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
8336 + buf_layout, dev);
8337 +
8338 + /* Proxy interfaces need to be started, and the allocated
8339 + * memory freed
8340 + */
8341 + devm_kfree(dev, buf_layout);
8342 + devm_kfree(dev, dpa_bp);
8343 +
8344 + /* Free FQ structures */
8345 + devm_kfree(dev, port_fqs.rx_defq);
8346 + devm_kfree(dev, port_fqs.rx_errq);
8347 + devm_kfree(dev, port_fqs.tx_defq);
8348 + devm_kfree(dev, port_fqs.tx_errq);
8349 +
8350 + for_each_port_device(i, mac_dev->port_dev) {
8351 + err = fm_port_enable(mac_dev->port_dev[i]);
8352 + if (err)
8353 + goto port_enable_fail;
8354 + }
8355 +
8356 + dev_info(dev, "probed MAC device with MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
8357 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
8358 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
8359 +
8360 + return 0; /* Proxy interface initialization ended */
8361 +
8362 +port_enable_fail:
8363 + for_each_port_device(i, mac_dev->port_dev)
8364 + fm_port_disable(mac_dev->port_dev[i]);
8365 + dpa_eth_proxy_remove(_of_dev);
8366 +
8367 + return err;
8368 +}
8369 +
8370 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8371 + struct net_device *net_dev)
8372 +{
8373 + struct mac_device *mac_dev;
8374 + int _errno;
8375 +
8376 + mac_dev = proxy_dev->mac_dev;
8377 +
8378 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
8379 + net_dev->dev_addr);
8380 + if (_errno < 0)
8381 + return _errno;
8382 +
8383 + return 0;
8384 +}
8385 +EXPORT_SYMBOL(dpa_proxy_set_mac_address);
8386 +
8387 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8388 + struct net_device *net_dev)
8389 +{
8390 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8391 + int _errno;
8392 +
8393 + if (!!(net_dev->flags & IFF_PROMISC) != mac_dev->promisc) {
8394 + mac_dev->promisc = !mac_dev->promisc;
8395 + _errno = mac_dev->set_promisc(mac_dev->get_mac_handle(mac_dev),
8396 + mac_dev->promisc);
8397 + if (unlikely(_errno < 0))
8398 + netdev_err(net_dev, "mac_dev->set_promisc() = %d\n",
8399 + _errno);
8400 + }
8401 +
8402 + _errno = mac_dev->set_multi(net_dev, mac_dev);
8403 + if (unlikely(_errno < 0))
8404 + return _errno;
8405 +
8406 + return 0;
8407 +}
8408 +EXPORT_SYMBOL(dpa_proxy_set_rx_mode);
8409 +
8410 +int dpa_proxy_start(struct net_device *net_dev)
8411 +{
8412 + struct mac_device *mac_dev;
8413 + const struct dpa_priv_s *priv;
8414 + struct proxy_device *proxy_dev;
8415 + int _errno;
8416 + int i;
8417 +
8418 + priv = netdev_priv(net_dev);
8419 + proxy_dev = (struct proxy_device *)priv->peer;
8420 + mac_dev = proxy_dev->mac_dev;
8421 +
8422 + _errno = mac_dev->init_phy(net_dev, mac_dev);
8423 + if (_errno < 0) {
8424 + if (netif_msg_drv(priv))
8425 + netdev_err(net_dev, "init_phy() = %d\n",
8426 + _errno);
8427 + return _errno;
8428 + }
8429 +
8430 + for_each_port_device(i, mac_dev->port_dev) {
8431 + _errno = fm_port_enable(mac_dev->port_dev[i]);
8432 + if (_errno)
8433 + goto port_enable_fail;
8434 + }
8435 +
8436 + _errno = mac_dev->start(mac_dev);
8437 + if (_errno < 0) {
8438 + if (netif_msg_drv(priv))
8439 + netdev_err(net_dev, "mac_dev->start() = %d\n",
8440 + _errno);
8441 + goto port_enable_fail;
8442 + }
8443 +
8444 + return _errno;
8445 +
8446 +port_enable_fail:
8447 + for_each_port_device(i, mac_dev->port_dev)
8448 + fm_port_disable(mac_dev->port_dev[i]);
8449 +
8450 + return _errno;
8451 +}
8452 +EXPORT_SYMBOL(dpa_proxy_start);
8453 +
8454 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev)
8455 +{
8456 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8457 + const struct dpa_priv_s *priv = netdev_priv(net_dev);
8458 + int _errno, i, err;
8459 +
8460 + _errno = mac_dev->stop(mac_dev);
8461 + if (_errno < 0) {
8462 + if (netif_msg_drv(priv))
8463 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
8464 + _errno);
8465 + return _errno;
8466 + }
8467 +
8468 + for_each_port_device(i, mac_dev->port_dev) {
8469 + err = fm_port_disable(mac_dev->port_dev[i]);
8470 + _errno = err ? err : _errno;
8471 + }
8472 +
8473 + if (mac_dev->phy_dev)
8474 + phy_disconnect(mac_dev->phy_dev);
8475 + mac_dev->phy_dev = NULL;
8476 +
8477 + return _errno;
8478 +}
8479 +EXPORT_SYMBOL(dpa_proxy_stop);
8480 +
8481 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev)
8482 +{
8483 + struct device *dev = &of_dev->dev;
8484 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8485 +
8486 + kfree(proxy_dev);
8487 +
8488 + dev_set_drvdata(dev, NULL);
8489 +
8490 + return 0;
8491 +}
8492 +
8493 +static const struct of_device_id dpa_proxy_match[] = {
8494 + {
8495 + .compatible = "fsl,dpa-ethernet-init"
8496 + },
8497 + {}
8498 +};
8499 +MODULE_DEVICE_TABLE(of, dpa_proxy_match);
8500 +
8501 +static struct platform_driver dpa_proxy_driver = {
8502 + .driver = {
8503 + .name = KBUILD_MODNAME "-proxy",
8504 + .of_match_table = dpa_proxy_match,
8505 + .owner = THIS_MODULE,
8506 + .pm = PROXY_PM_OPS,
8507 + },
8508 + .probe = dpaa_eth_proxy_probe,
8509 + .remove = dpa_eth_proxy_remove
8510 +};
8511 +
8512 +static int __init __cold dpa_proxy_load(void)
8513 +{
8514 + int _errno;
8515 +
8516 + pr_info(DPA_DESCRIPTION "\n");
8517 +
8518 + /* Initialize dpaa_eth mirror values */
8519 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
8520 + dpa_max_frm = fm_get_max_frm();
8521 +
8522 + _errno = platform_driver_register(&dpa_proxy_driver);
8523 + if (unlikely(_errno < 0)) {
8524 + pr_err(KBUILD_MODNAME
8525 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
8526 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
8527 + }
8528 +
8529 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8530 + KBUILD_BASENAME".c", __func__);
8531 +
8532 + return _errno;
8533 +}
8534 +module_init(dpa_proxy_load);
8535 +
8536 +static void __exit __cold dpa_proxy_unload(void)
8537 +{
8538 + platform_driver_unregister(&dpa_proxy_driver);
8539 +
8540 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8541 + KBUILD_BASENAME".c", __func__);
8542 +}
8543 +module_exit(dpa_proxy_unload);
8544 --- /dev/null
8545 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
8546 @@ -0,0 +1,1168 @@
8547 +/* Copyright 2012 Freescale Semiconductor Inc.
8548 + *
8549 + * Redistribution and use in source and binary forms, with or without
8550 + * modification, are permitted provided that the following conditions are met:
8551 + * * Redistributions of source code must retain the above copyright
8552 + * notice, this list of conditions and the following disclaimer.
8553 + * * Redistributions in binary form must reproduce the above copyright
8554 + * notice, this list of conditions and the following disclaimer in the
8555 + * documentation and/or other materials provided with the distribution.
8556 + * * Neither the name of Freescale Semiconductor nor the
8557 + * names of its contributors may be used to endorse or promote products
8558 + * derived from this software without specific prior written permission.
8559 + *
8560 + *
8561 + * ALTERNATIVELY, this software may be distributed under the terms of the
8562 + * GNU General Public License ("GPL") as published by the Free Software
8563 + * Foundation, either version 2 of that License or (at your option) any
8564 + * later version.
8565 + *
8566 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8567 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8568 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8569 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8570 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8571 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8572 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8573 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8574 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8575 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8576 + */
8577 +
8578 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8579 +#define pr_fmt(fmt) \
8580 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8581 + KBUILD_BASENAME".c", __LINE__, __func__
8582 +#else
8583 +#define pr_fmt(fmt) \
8584 + KBUILD_MODNAME ": " fmt
8585 +#endif
8586 +
8587 +#include <linux/init.h>
8588 +#include <linux/skbuff.h>
8589 +#include <linux/highmem.h>
8590 +#include <linux/fsl_bman.h>
8591 +#include <net/sock.h>
8592 +
8593 +#include "dpaa_eth.h"
8594 +#include "dpaa_eth_common.h"
8595 +#ifdef CONFIG_FSL_DPAA_1588
8596 +#include "dpaa_1588.h"
8597 +#endif
8598 +#ifdef CONFIG_FSL_DPAA_CEETM
8599 +#include "dpaa_eth_ceetm.h"
8600 +#endif
8601 +
8602 +/* DMA map and add a page frag back into the bpool.
8603 + * @vaddr fragment must have been allocated with netdev_alloc_frag(),
8604 + * specifically for fitting into @dpa_bp.
8605 + */
8606 +static void dpa_bp_recycle_frag(struct dpa_bp *dpa_bp, unsigned long vaddr,
8607 + int *count_ptr)
8608 +{
8609 + struct bm_buffer bmb;
8610 + dma_addr_t addr;
8611 +
8612 + bmb.opaque = 0;
8613 +
8614 + addr = dma_map_single(dpa_bp->dev, (void *)vaddr, dpa_bp->size,
8615 + DMA_BIDIRECTIONAL);
8616 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
8617 + dev_err(dpa_bp->dev, "DMA mapping failed");
8618 + return;
8619 + }
8620 +
8621 + bm_buffer_set64(&bmb, addr);
8622 +
8623 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
8624 + cpu_relax();
8625 +
8626 + (*count_ptr)++;
8627 +}
8628 +
8629 +static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp)
8630 +{
8631 + struct bm_buffer bmb[8];
8632 + void *new_buf;
8633 + dma_addr_t addr;
8634 + uint8_t i;
8635 + struct device *dev = dpa_bp->dev;
8636 + struct sk_buff *skb, **skbh;
8637 +
8638 + memset(bmb, 0, sizeof(struct bm_buffer) * 8);
8639 +
8640 + for (i = 0; i < 8; i++) {
8641 + /* We'll prepend the skb back-pointer; can't use the DPA
8642 + * priv space, because FMan will overwrite it (from offset 0)
8643 + * if it ends up being the second, third, etc. fragment
8644 + * in a S/G frame.
8645 + *
8646 + * We only need enough space to store a pointer, but allocate
8647 + * an entire cacheline for performance reasons.
8648 + */
8649 +#ifndef CONFIG_PPC
8650 + if (unlikely(dpaa_errata_a010022)) {
8651 + struct page *new_page = alloc_page(GFP_ATOMIC);
8652 + if (unlikely(!new_page))
8653 + goto netdev_alloc_failed;
8654 + new_buf = page_address(new_page);
8655 + }
8656 + else
8657 +#endif
8658 + new_buf = netdev_alloc_frag(SMP_CACHE_BYTES + DPA_BP_RAW_SIZE);
8659 +
8660 + if (unlikely(!new_buf))
8661 + goto netdev_alloc_failed;
8662 + new_buf = PTR_ALIGN(new_buf + SMP_CACHE_BYTES, SMP_CACHE_BYTES);
8663 +
8664 + skb = build_skb(new_buf, DPA_SKB_SIZE(dpa_bp->size) +
8665 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
8666 + if (unlikely(!skb)) {
8667 + put_page(virt_to_head_page(new_buf));
8668 + goto build_skb_failed;
8669 + }
8670 + DPA_WRITE_SKB_PTR(skb, skbh, new_buf, -1);
8671 +
8672 + addr = dma_map_single(dev, new_buf,
8673 + dpa_bp->size, DMA_BIDIRECTIONAL);
8674 + if (unlikely(dma_mapping_error(dev, addr)))
8675 + goto dma_map_failed;
8676 +
8677 + bm_buffer_set64(&bmb[i], addr);
8678 + }
8679 +
8680 +release_bufs:
8681 + /* Release the buffers. In case bman is busy, keep trying
8682 + * until successful. bman_release() is guaranteed to succeed
8683 + * in a reasonable amount of time
8684 + */
8685 + while (unlikely(bman_release(dpa_bp->pool, bmb, i, 0)))
8686 + cpu_relax();
8687 + return i;
8688 +
8689 +dma_map_failed:
8690 + kfree_skb(skb);
8691 +
8692 +build_skb_failed:
8693 +netdev_alloc_failed:
8694 + net_err_ratelimited("dpa_bp_add_8_bufs() failed\n");
8695 + WARN_ONCE(1, "Memory allocation failure on Rx\n");
8696 +
8697 + bm_buffer_set64(&bmb[i], 0);
8698 + /* Avoid releasing a completely null buffer; bman_release() requires
8699 + * at least one buffer.
8700 + */
8701 + if (likely(i))
8702 + goto release_bufs;
8703 +
8704 + return 0;
8705 +}
8706 +
8707 +/* Cold path wrapper over _dpa_bp_add_8_bufs(). */
8708 +static void dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp, int cpu)
8709 +{
8710 + int *count_ptr = per_cpu_ptr(dpa_bp->percpu_count, cpu);
8711 + *count_ptr += _dpa_bp_add_8_bufs(dpa_bp);
8712 +}
8713 +
8714 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp)
8715 +{
8716 + int i;
8717 +
8718 + /* Give each CPU an allotment of "config_count" buffers */
8719 + for_each_possible_cpu(i) {
8720 + int j;
8721 +
8722 + /* Although we access another CPU's counters here
8723 + * we do it at boot time so it is safe
8724 + */
8725 + for (j = 0; j < dpa_bp->config_count; j += 8)
8726 + dpa_bp_add_8_bufs(dpa_bp, i);
8727 + }
8728 + return 0;
8729 +}
8730 +EXPORT_SYMBOL(dpa_bp_priv_seed);
8731 +
8732 +/* Add buffers/(pages) for Rx processing whenever bpool count falls below
8733 + * REFILL_THRESHOLD.
8734 + */
8735 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *countptr)
8736 +{
8737 + int count = *countptr;
8738 + int new_bufs;
8739 +
8740 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD)) {
8741 + do {
8742 + new_bufs = _dpa_bp_add_8_bufs(dpa_bp);
8743 + if (unlikely(!new_bufs)) {
8744 + /* Avoid looping forever if we've temporarily
8745 + * run out of memory. We'll try again at the
8746 + * next NAPI cycle.
8747 + */
8748 + break;
8749 + }
8750 + count += new_bufs;
8751 + } while (count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT);
8752 +
8753 + *countptr = count;
8754 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT))
8755 + return -ENOMEM;
8756 + }
8757 +
8758 + return 0;
8759 +}
8760 +EXPORT_SYMBOL(dpaa_eth_refill_bpools);
8761 +
8762 +/* Cleanup function for outgoing frame descriptors that were built on Tx path,
8763 + * either contiguous frames or scatter/gather ones.
8764 + * Skb freeing is not handled here.
8765 + *
8766 + * This function may be called on error paths in the Tx function, so guard
8767 + * against cases when not all fd relevant fields were filled in.
8768 + *
8769 + * Return the skb backpointer, since for S/G frames the buffer containing it
8770 + * gets freed here.
8771 + */
8772 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
8773 + const struct qm_fd *fd)
8774 +{
8775 + const struct qm_sg_entry *sgt;
8776 + int i;
8777 + struct dpa_bp *dpa_bp = priv->dpa_bp;
8778 + dma_addr_t addr = qm_fd_addr(fd);
8779 + dma_addr_t sg_addr;
8780 + struct sk_buff **skbh;
8781 + struct sk_buff *skb = NULL;
8782 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
8783 + int nr_frags;
8784 + int sg_len;
8785 +
8786 + /* retrieve skb back pointer */
8787 + DPA_READ_SKB_PTR(skb, skbh, phys_to_virt(addr), 0);
8788 +
8789 + if (unlikely(fd->format == qm_fd_sg)) {
8790 + nr_frags = skb_shinfo(skb)->nr_frags;
8791 + dma_unmap_single(dpa_bp->dev, addr, dpa_fd_offset(fd) +
8792 + sizeof(struct qm_sg_entry) * (1 + nr_frags),
8793 + dma_dir);
8794 +
8795 + /* The sgt buffer has been allocated with netdev_alloc_frag(),
8796 + * it's from lowmem.
8797 + */
8798 + sgt = phys_to_virt(addr + dpa_fd_offset(fd));
8799 +#ifdef CONFIG_FSL_DPAA_1588
8800 + if (priv->tsu && priv->tsu->valid &&
8801 + priv->tsu->hwts_tx_en_ioctl)
8802 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8803 +#endif
8804 +#ifdef CONFIG_FSL_DPAA_TS
8805 + if (unlikely(priv->ts_tx_en &&
8806 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8807 + struct skb_shared_hwtstamps shhwtstamps;
8808 +
8809 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8810 + skb_tstamp_tx(skb, &shhwtstamps);
8811 + }
8812 +#endif /* CONFIG_FSL_DPAA_TS */
8813 +
8814 + /* sgt[0] is from lowmem, was dma_map_single()-ed */
8815 + sg_addr = qm_sg_addr(&sgt[0]);
8816 + sg_len = qm_sg_entry_get_len(&sgt[0]);
8817 + dma_unmap_single(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8818 +
8819 + /* remaining pages were mapped with dma_map_page() */
8820 + for (i = 1; i <= nr_frags; i++) {
8821 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
8822 + sg_addr = qm_sg_addr(&sgt[i]);
8823 + sg_len = qm_sg_entry_get_len(&sgt[i]);
8824 + dma_unmap_page(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8825 + }
8826 +
8827 + /* Free the page frag that we allocated on Tx */
8828 + put_page(virt_to_head_page(sgt));
8829 + } else {
8830 + dma_unmap_single(dpa_bp->dev, addr,
8831 + skb_tail_pointer(skb) - (u8 *)skbh, dma_dir);
8832 +#ifdef CONFIG_FSL_DPAA_TS
8833 + /* get the timestamp for non-SG frames */
8834 +#ifdef CONFIG_FSL_DPAA_1588
8835 + if (priv->tsu && priv->tsu->valid &&
8836 + priv->tsu->hwts_tx_en_ioctl)
8837 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8838 +#endif
8839 + if (unlikely(priv->ts_tx_en &&
8840 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8841 + struct skb_shared_hwtstamps shhwtstamps;
8842 +
8843 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8844 + skb_tstamp_tx(skb, &shhwtstamps);
8845 + }
8846 +#endif
8847 + }
8848 +
8849 + return skb;
8850 +}
8851 +EXPORT_SYMBOL(_dpa_cleanup_tx_fd);
8852 +
8853 +#ifndef CONFIG_FSL_DPAA_TS
8854 +bool dpa_skb_is_recyclable(struct sk_buff *skb)
8855 +{
8856 +#ifndef CONFIG_PPC
8857 + /* Do no recycle skbs realigned by the errata workaround */
8858 + if (unlikely(dpaa_errata_a010022) && skb->mark == NONREC_MARK)
8859 + return false;
8860 +#endif
8861 +
8862 + /* No recycling possible if skb buffer is kmalloc'ed */
8863 + if (skb->head_frag == 0)
8864 + return false;
8865 +
8866 + /* or if it's an userspace buffer */
8867 + if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)
8868 + return false;
8869 +
8870 + /* or if it's cloned or shared */
8871 + if (skb_shared(skb) || skb_cloned(skb) ||
8872 + skb->fclone != SKB_FCLONE_UNAVAILABLE)
8873 + return false;
8874 +
8875 + return true;
8876 +}
8877 +EXPORT_SYMBOL(dpa_skb_is_recyclable);
8878 +
8879 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
8880 + uint32_t min_size,
8881 + uint16_t min_offset,
8882 + unsigned char **new_buf_start)
8883 +{
8884 + unsigned char *new;
8885 +
8886 + /* In order to recycle a buffer, the following conditions must be met:
8887 + * - buffer size no less than the buffer pool size
8888 + * - buffer size no higher than an upper limit (to avoid moving too much
8889 + * system memory to the buffer pools)
8890 + * - buffer address aligned to cacheline bytes
8891 + * - offset of data from start of buffer no lower than a minimum value
8892 + * - offset of data from start of buffer no higher than a maximum value
8893 + */
8894 + new = min(skb_end_pointer(skb) - min_size, skb->data - min_offset);
8895 +
8896 + /* left align to the nearest cacheline */
8897 + new = (unsigned char *)((unsigned long)new & ~(SMP_CACHE_BYTES - 1));
8898 +
8899 + if (likely(new >= skb->head &&
8900 + new >= (skb->data - DPA_MAX_FD_OFFSET) &&
8901 + skb_end_pointer(skb) - new <= DPA_RECYCLE_MAX_SIZE)) {
8902 + *new_buf_start = new;
8903 + return true;
8904 + }
8905 +
8906 + return false;
8907 +}
8908 +EXPORT_SYMBOL(dpa_buf_is_recyclable);
8909 +#endif
8910 +
8911 +/* Build a linear skb around the received buffer.
8912 + * We are guaranteed there is enough room at the end of the data buffer to
8913 + * accommodate the shared info area of the skb.
8914 + */
8915 +static struct sk_buff *__hot contig_fd_to_skb(const struct dpa_priv_s *priv,
8916 + const struct qm_fd *fd, int *use_gro)
8917 +{
8918 + dma_addr_t addr = qm_fd_addr(fd);
8919 + ssize_t fd_off = dpa_fd_offset(fd);
8920 + void *vaddr;
8921 + const fm_prs_result_t *parse_results;
8922 + struct sk_buff *skb = NULL, **skbh;
8923 +
8924 + vaddr = phys_to_virt(addr);
8925 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
8926 +
8927 + /* Retrieve the skb and adjust data and tail pointers, to make sure
8928 + * forwarded skbs will have enough space on Tx if extra headers
8929 + * are added.
8930 + */
8931 + DPA_READ_SKB_PTR(skb, skbh, vaddr, -1);
8932 +
8933 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
8934 + /* When using jumbo Rx buffers, we risk having frames dropped due to
8935 + * the socket backlog reaching its maximum allowed size.
8936 + * Use the frame length for the skb truesize instead of the buffer
8937 + * size, as this is the size of the data that actually gets copied to
8938 + * userspace.
8939 + * The stack may increase the payload. In this case, it will want to
8940 + * warn us that the frame length is larger than the truesize. We
8941 + * bypass the warning.
8942 + */
8943 +#ifndef CONFIG_PPC
8944 + /* We do not support Jumbo frames on LS1043 and thus we edit
8945 + * the skb truesize only when the 4k errata is not present.
8946 + */
8947 + if (likely(!dpaa_errata_a010022))
8948 +#endif
8949 + skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd));
8950 +#endif
8951 +
8952 + DPA_BUG_ON(fd_off != priv->rx_headroom);
8953 + skb_reserve(skb, fd_off);
8954 + skb_put(skb, dpa_fd_length(fd));
8955 +
8956 + /* Peek at the parse results for csum validation */
8957 + parse_results = (const fm_prs_result_t *)(vaddr +
8958 + DPA_RX_PRIV_DATA_SIZE);
8959 + _dpa_process_parse_results(parse_results, fd, skb, use_gro);
8960 +
8961 +#ifdef CONFIG_FSL_DPAA_1588
8962 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl)
8963 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
8964 +#endif
8965 +#ifdef CONFIG_FSL_DPAA_TS
8966 + if (priv->ts_rx_en)
8967 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
8968 +#endif /* CONFIG_FSL_DPAA_TS */
8969 +
8970 + return skb;
8971 +}
8972 +
8973 +
8974 +/* Build an skb with the data of the first S/G entry in the linear portion and
8975 + * the rest of the frame as skb fragments.
8976 + *
8977 + * The page fragment holding the S/G Table is recycled here.
8978 + */
8979 +static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
8980 + const struct qm_fd *fd, int *use_gro,
8981 + int *count_ptr)
8982 +{
8983 + const struct qm_sg_entry *sgt;
8984 + dma_addr_t addr = qm_fd_addr(fd);
8985 + ssize_t fd_off = dpa_fd_offset(fd);
8986 + dma_addr_t sg_addr;
8987 + void *vaddr, *sg_vaddr;
8988 + struct dpa_bp *dpa_bp;
8989 + struct page *page, *head_page;
8990 + int frag_offset, frag_len;
8991 + int page_offset;
8992 + int i;
8993 + const fm_prs_result_t *parse_results;
8994 + struct sk_buff *skb = NULL, *skb_tmp, **skbh;
8995 +
8996 + vaddr = phys_to_virt(addr);
8997 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
8998 +
8999 + dpa_bp = priv->dpa_bp;
9000 + /* Iterate through the SGT entries and add data buffers to the skb */
9001 + sgt = vaddr + fd_off;
9002 + for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
9003 + /* Extension bit is not supported */
9004 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
9005 +
9006 + /* We use a single global Rx pool */
9007 + DPA_BUG_ON(dpa_bp !=
9008 + dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i])));
9009 +
9010 + sg_addr = qm_sg_addr(&sgt[i]);
9011 + sg_vaddr = phys_to_virt(sg_addr);
9012 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
9013 + SMP_CACHE_BYTES));
9014 +
9015 + dma_unmap_single(dpa_bp->dev, sg_addr, dpa_bp->size,
9016 + DMA_BIDIRECTIONAL);
9017 + if (i == 0) {
9018 + DPA_READ_SKB_PTR(skb, skbh, sg_vaddr, -1);
9019 + DPA_BUG_ON(skb->head != sg_vaddr);
9020 +#ifdef CONFIG_FSL_DPAA_1588
9021 + if (priv->tsu && priv->tsu->valid &&
9022 + priv->tsu->hwts_rx_en_ioctl)
9023 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
9024 +#endif
9025 +#ifdef CONFIG_FSL_DPAA_TS
9026 + if (priv->ts_rx_en)
9027 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
9028 +#endif /* CONFIG_FSL_DPAA_TS */
9029 +
9030 + /* In the case of a SG frame, FMan stores the Internal
9031 + * Context in the buffer containing the sgt.
9032 + * Inspect the parse results before anything else.
9033 + */
9034 + parse_results = (const fm_prs_result_t *)(vaddr +
9035 + DPA_RX_PRIV_DATA_SIZE);
9036 + _dpa_process_parse_results(parse_results, fd, skb,
9037 + use_gro);
9038 +
9039 + /* Make sure forwarded skbs will have enough space
9040 + * on Tx, if extra headers are added.
9041 + */
9042 + DPA_BUG_ON(fd_off != priv->rx_headroom);
9043 + skb_reserve(skb, fd_off);
9044 + skb_put(skb, qm_sg_entry_get_len(&sgt[i]));
9045 + } else {
9046 + /* Not the first S/G entry; all data from buffer will
9047 + * be added in an skb fragment; fragment index is offset
9048 + * by one since first S/G entry was incorporated in the
9049 + * linear part of the skb.
9050 + *
9051 + * Caution: 'page' may be a tail page.
9052 + */
9053 + DPA_READ_SKB_PTR(skb_tmp, skbh, sg_vaddr, -1);
9054 + page = virt_to_page(sg_vaddr);
9055 + head_page = virt_to_head_page(sg_vaddr);
9056 +
9057 + /* Free (only) the skbuff shell because its data buffer
9058 + * is already a frag in the main skb.
9059 + */
9060 + get_page(head_page);
9061 + dev_kfree_skb(skb_tmp);
9062 +
9063 + /* Compute offset in (possibly tail) page */
9064 + page_offset = ((unsigned long)sg_vaddr &
9065 + (PAGE_SIZE - 1)) +
9066 + (page_address(page) - page_address(head_page));
9067 + /* page_offset only refers to the beginning of sgt[i];
9068 + * but the buffer itself may have an internal offset.
9069 + */
9070 + frag_offset = qm_sg_entry_get_offset(&sgt[i]) +
9071 + page_offset;
9072 + frag_len = qm_sg_entry_get_len(&sgt[i]);
9073 + /* skb_add_rx_frag() does no checking on the page; if
9074 + * we pass it a tail page, we'll end up with
9075 + * bad page accounting and eventually with segafults.
9076 + */
9077 + skb_add_rx_frag(skb, i - 1, head_page, frag_offset,
9078 + frag_len, dpa_bp->size);
9079 + }
9080 + /* Update the pool count for the current {cpu x bpool} */
9081 + (*count_ptr)--;
9082 +
9083 + if (qm_sg_entry_get_final(&sgt[i]))
9084 + break;
9085 + }
9086 + WARN_ONCE(i == DPA_SGT_MAX_ENTRIES, "No final bit on SGT\n");
9087 +
9088 + /* recycle the SGT fragment */
9089 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9090 + dpa_bp_recycle_frag(dpa_bp, (unsigned long)vaddr, count_ptr);
9091 + return skb;
9092 +}
9093 +
9094 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9095 +static inline int dpa_skb_loop(const struct dpa_priv_s *priv,
9096 + struct sk_buff *skb)
9097 +{
9098 + if (unlikely(priv->loop_to < 0))
9099 + return 0; /* loop disabled by default */
9100 +
9101 + skb_push(skb, ETH_HLEN); /* compensate for eth_type_trans */
9102 + dpa_tx(skb, dpa_loop_netdevs[priv->loop_to]);
9103 +
9104 + return 1; /* Frame Tx on the selected interface */
9105 +}
9106 +#endif
9107 +
9108 +void __hot _dpa_rx(struct net_device *net_dev,
9109 + struct qman_portal *portal,
9110 + const struct dpa_priv_s *priv,
9111 + struct dpa_percpu_priv_s *percpu_priv,
9112 + const struct qm_fd *fd,
9113 + u32 fqid,
9114 + int *count_ptr)
9115 +{
9116 + struct dpa_bp *dpa_bp;
9117 + struct sk_buff *skb;
9118 + dma_addr_t addr = qm_fd_addr(fd);
9119 + u32 fd_status = fd->status;
9120 + unsigned int skb_len;
9121 + struct rtnl_link_stats64 *percpu_stats = &percpu_priv->stats;
9122 + int use_gro = net_dev->features & NETIF_F_GRO;
9123 +
9124 + if (unlikely(fd_status & FM_FD_STAT_RX_ERRORS) != 0) {
9125 + if (netif_msg_hw(priv) && net_ratelimit())
9126 + netdev_warn(net_dev, "FD status = 0x%08x\n",
9127 + fd_status & FM_FD_STAT_RX_ERRORS);
9128 +
9129 + percpu_stats->rx_errors++;
9130 + goto _release_frame;
9131 + }
9132 +
9133 + dpa_bp = priv->dpa_bp;
9134 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9135 +
9136 + /* prefetch the first 64 bytes of the frame or the SGT start */
9137 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
9138 + prefetch(phys_to_virt(addr) + dpa_fd_offset(fd));
9139 +
9140 + /* The only FD types that we may receive are contig and S/G */
9141 + DPA_BUG_ON((fd->format != qm_fd_contig) && (fd->format != qm_fd_sg));
9142 +
9143 + if (likely(fd->format == qm_fd_contig)) {
9144 +#ifdef CONFIG_FSL_DPAA_HOOKS
9145 + /* Execute the Rx processing hook, if it exists. */
9146 + if (dpaa_eth_hooks.rx_default &&
9147 + dpaa_eth_hooks.rx_default((void *)fd, net_dev,
9148 + fqid) == DPAA_ETH_STOLEN) {
9149 + /* won't count the rx bytes in */
9150 + return;
9151 + }
9152 +#endif
9153 + skb = contig_fd_to_skb(priv, fd, &use_gro);
9154 + } else {
9155 + skb = sg_fd_to_skb(priv, fd, &use_gro, count_ptr);
9156 + percpu_priv->rx_sg++;
9157 + }
9158 +
9159 + /* Account for either the contig buffer or the SGT buffer (depending on
9160 + * which case we were in) having been removed from the pool.
9161 + */
9162 + (*count_ptr)--;
9163 + skb->protocol = eth_type_trans(skb, net_dev);
9164 +
9165 + skb_len = skb->len;
9166 +
9167 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9168 + if (dpa_skb_loop(priv, skb)) {
9169 + percpu_stats->rx_packets++;
9170 + percpu_stats->rx_bytes += skb_len;
9171 + return;
9172 + }
9173 +#endif
9174 +
9175 + if (use_gro) {
9176 + gro_result_t gro_result;
9177 + const struct qman_portal_config *pc =
9178 + qman_p_get_portal_config(portal);
9179 + struct dpa_napi_portal *np = &percpu_priv->np[pc->index];
9180 +
9181 + np->p = portal;
9182 + gro_result = napi_gro_receive(&np->napi, skb);
9183 + /* If frame is dropped by the stack, rx_dropped counter is
9184 + * incremented automatically, so no need for us to update it
9185 + */
9186 + if (unlikely(gro_result == GRO_DROP))
9187 + goto packet_dropped;
9188 + } else if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
9189 + goto packet_dropped;
9190 +
9191 + percpu_stats->rx_packets++;
9192 + percpu_stats->rx_bytes += skb_len;
9193 +
9194 +packet_dropped:
9195 + return;
9196 +
9197 +_release_frame:
9198 + dpa_fd_release(net_dev, fd);
9199 +}
9200 +
9201 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
9202 + struct sk_buff *skb, struct qm_fd *fd,
9203 + int *count_ptr, int *offset)
9204 +{
9205 + struct sk_buff **skbh;
9206 + dma_addr_t addr;
9207 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9208 + struct net_device *net_dev = priv->net_dev;
9209 + int err;
9210 + enum dma_data_direction dma_dir;
9211 + unsigned char *buffer_start;
9212 + int dma_map_size;
9213 +
9214 +#ifndef CONFIG_FSL_DPAA_TS
9215 + /* Check recycling conditions; only if timestamp support is not
9216 + * enabled, otherwise we need the fd back on tx confirmation
9217 + */
9218 +
9219 + /* We can recycle the buffer if:
9220 + * - the pool is not full
9221 + * - the buffer meets the skb recycling conditions
9222 + * - the buffer meets our own (size, offset, align) conditions
9223 + */
9224 + if (likely((*count_ptr < dpa_bp->target_count) &&
9225 + dpa_skb_is_recyclable(skb) &&
9226 + dpa_buf_is_recyclable(skb, dpa_bp->size,
9227 + priv->tx_headroom, &buffer_start))) {
9228 + /* Buffer is recyclable; use the new start address
9229 + * and set fd parameters and DMA mapping direction
9230 + */
9231 + fd->bpid = dpa_bp->bpid;
9232 + DPA_BUG_ON(skb->data - buffer_start > DPA_MAX_FD_OFFSET);
9233 + fd->offset = (uint16_t)(skb->data - buffer_start);
9234 + dma_dir = DMA_BIDIRECTIONAL;
9235 + dma_map_size = dpa_bp->size;
9236 +
9237 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, -1);
9238 + *offset = skb_headroom(skb) - fd->offset;
9239 + } else
9240 +#endif
9241 + {
9242 + /* Not recyclable.
9243 + * We are guaranteed to have at least tx_headroom bytes
9244 + * available, so just use that for offset.
9245 + */
9246 + fd->bpid = 0xff;
9247 + buffer_start = skb->data - priv->tx_headroom;
9248 + fd->offset = priv->tx_headroom;
9249 + dma_dir = DMA_TO_DEVICE;
9250 + dma_map_size = skb_tail_pointer(skb) - buffer_start;
9251 +
9252 + /* The buffer will be Tx-confirmed, but the TxConf cb must
9253 + * necessarily look at our Tx private data to retrieve the
9254 + * skbuff. (In short: can't use DPA_WRITE_SKB_PTR() here.)
9255 + */
9256 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, 0);
9257 + }
9258 +
9259 + /* Enable L3/L4 hardware checksum computation.
9260 + *
9261 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9262 + * need to write into the skb.
9263 + */
9264 + err = dpa_enable_tx_csum(priv, skb, fd,
9265 + ((char *)skbh) + DPA_TX_PRIV_DATA_SIZE);
9266 + if (unlikely(err < 0)) {
9267 + if (netif_msg_tx_err(priv) && net_ratelimit())
9268 + netdev_err(net_dev, "HW csum error: %d\n", err);
9269 + return err;
9270 + }
9271 +
9272 + /* Fill in the rest of the FD fields */
9273 + fd->format = qm_fd_contig;
9274 + fd->length20 = skb->len;
9275 + fd->cmd |= FM_FD_CMD_FCO;
9276 +
9277 + /* Map the entire buffer size that may be seen by FMan, but no more */
9278 + addr = dma_map_single(dpa_bp->dev, skbh, dma_map_size, dma_dir);
9279 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9280 + if (netif_msg_tx_err(priv) && net_ratelimit())
9281 + netdev_err(net_dev, "dma_map_single() failed\n");
9282 + return -EINVAL;
9283 + }
9284 + qm_fd_addr_set64(fd, addr);
9285 +
9286 + return 0;
9287 +}
9288 +EXPORT_SYMBOL(skb_to_contig_fd);
9289 +
9290 +#ifndef CONFIG_PPC
9291 +/* Verify the conditions that trigger the A010022 errata: data unaligned to
9292 + * 16 bytes and 4K memory address crossings.
9293 + */
9294 +static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv)
9295 +{
9296 + int nr_frags, i = 0;
9297 + skb_frag_t *frag;
9298 +
9299 + /* Check if the headroom is aligned */
9300 + if (((uintptr_t)skb->data - priv->tx_headroom) %
9301 + priv->buf_layout[TX].data_align != 0)
9302 + return true;
9303 +
9304 + /* Check if the headroom crosses a boundary */
9305 + if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb)))
9306 + return true;
9307 +
9308 + /* Check if the non-paged data crosses a boundary */
9309 + if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb)))
9310 + return true;
9311 +
9312 + /* Check if the entire linear skb crosses a boundary */
9313 + if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb)))
9314 + return true;
9315 +
9316 + nr_frags = skb_shinfo(skb)->nr_frags;
9317 +
9318 + while (i < nr_frags) {
9319 + frag = &skb_shinfo(skb)->frags[i];
9320 +
9321 + /* Check if a paged fragment crosses a boundary from its
9322 + * offset to its end.
9323 + */
9324 + if (HAS_DMA_ISSUE(frag->page_offset, frag->size))
9325 + return true;
9326 +
9327 + i++;
9328 + }
9329 +
9330 + return false;
9331 +}
9332 +
9333 +/* Realign the skb by copying its contents at the start of a newly allocated
9334 + * page. Build a new skb around the new buffer and release the old one.
9335 + * A performance drop should be expected.
9336 + */
9337 +static struct sk_buff *a010022_realign_skb(struct sk_buff *skb,
9338 + struct dpa_priv_s *priv)
9339 +{
9340 + int trans_offset = skb_transport_offset(skb);
9341 + int net_offset = skb_network_offset(skb);
9342 + struct sk_buff *nskb = NULL;
9343 + int nsize, headroom;
9344 + struct page *npage;
9345 + void *npage_addr;
9346 +
9347 + /* Guarantee the minimum required headroom */
9348 + if (skb_headroom(skb) >= priv->tx_headroom)
9349 + headroom = skb_headroom(skb);
9350 + else
9351 + headroom = priv->tx_headroom;
9352 +
9353 + npage = alloc_page(GFP_ATOMIC);
9354 + if (unlikely(!npage)) {
9355 + WARN_ONCE(1, "Memory allocation failure\n");
9356 + return NULL;
9357 + }
9358 + npage_addr = page_address(npage);
9359 +
9360 + /* For the new skb we only need the old one's data (both non-paged and
9361 + * paged) and a headroom large enough to fit our private info. We can
9362 + * skip the old tailroom.
9363 + *
9364 + * Make sure the new linearized buffer will not exceed a page's size.
9365 + */
9366 + nsize = headroom + skb->len +
9367 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
9368 + if (unlikely(nsize > 4096))
9369 + goto err;
9370 +
9371 + nskb = build_skb(npage_addr, nsize);
9372 + if (unlikely(!nskb))
9373 + goto err;
9374 +
9375 + /* Reserve only the needed headroom in order to guarantee the data's
9376 + * alignment.
9377 + * Code borrowed and adapted from skb_copy().
9378 + */
9379 + skb_reserve(nskb, priv->tx_headroom);
9380 + skb_put(nskb, skb->len);
9381 + if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
9382 + WARN_ONCE(1, "skb parsing failure\n");
9383 + goto err;
9384 + }
9385 + copy_skb_header(nskb, skb);
9386 +
9387 +#ifdef CONFIG_FSL_DPAA_TS
9388 + /* Copy relevant timestamp info from the old skb to the new */
9389 + if (priv->ts_tx_en) {
9390 + skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags;
9391 + skb_shinfo(nskb)->hwtstamps = skb_shinfo(skb)->hwtstamps;
9392 + skb_shinfo(nskb)->tskey = skb_shinfo(skb)->tskey;
9393 + if (skb->sk)
9394 + skb_set_owner_w(nskb, skb->sk);
9395 + }
9396 +#endif
9397 + /* We move the headroom when we align it so we have to reset the
9398 + * network and transport header offsets relative to the new data
9399 + * pointer. The checksum offload relies on these offsets.
9400 + */
9401 + skb_set_network_header(nskb, net_offset);
9402 + skb_set_transport_header(nskb, trans_offset);
9403 +
9404 + /* We don't want the buffer to be recycled so we mark it accordingly */
9405 + nskb->mark = NONREC_MARK;
9406 +
9407 + dev_kfree_skb(skb);
9408 + return nskb;
9409 +
9410 +err:
9411 + if (nskb)
9412 + dev_kfree_skb(nskb);
9413 + put_page(npage);
9414 + return NULL;
9415 +}
9416 +#endif
9417 +
9418 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
9419 + struct sk_buff *skb, struct qm_fd *fd)
9420 +{
9421 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9422 + dma_addr_t addr;
9423 + dma_addr_t sg_addr;
9424 + struct sk_buff **skbh;
9425 + struct net_device *net_dev = priv->net_dev;
9426 + int sg_len, sgt_size;
9427 + int err;
9428 +
9429 + struct qm_sg_entry *sgt;
9430 + void *sgt_buf;
9431 + skb_frag_t *frag;
9432 + int i = 0, j = 0;
9433 + int nr_frags;
9434 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
9435 +
9436 + nr_frags = skb_shinfo(skb)->nr_frags;
9437 + fd->format = qm_fd_sg;
9438 +
9439 + sgt_size = sizeof(struct qm_sg_entry) * (1 + nr_frags);
9440 +
9441 + /* Get a page frag to store the SGTable, or a full page if the errata
9442 + * is in place and we need to avoid crossing a 4k boundary.
9443 + */
9444 +#ifndef CONFIG_PPC
9445 + if (unlikely(dpaa_errata_a010022))
9446 + sgt_buf = page_address(alloc_page(GFP_ATOMIC));
9447 + else
9448 +#endif
9449 + sgt_buf = netdev_alloc_frag(priv->tx_headroom + sgt_size);
9450 + if (unlikely(!sgt_buf)) {
9451 + dev_err(dpa_bp->dev, "netdev_alloc_frag() failed\n");
9452 + return -ENOMEM;
9453 + }
9454 +
9455 + /* it seems that the memory allocator does not zero the allocated mem */
9456 + memset(sgt_buf, 0, priv->tx_headroom + sgt_size);
9457 +
9458 + /* Enable L3/L4 hardware checksum computation.
9459 + *
9460 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9461 + * need to write into the skb.
9462 + */
9463 + err = dpa_enable_tx_csum(priv, skb, fd,
9464 + sgt_buf + DPA_TX_PRIV_DATA_SIZE);
9465 + if (unlikely(err < 0)) {
9466 + if (netif_msg_tx_err(priv) && net_ratelimit())
9467 + netdev_err(net_dev, "HW csum error: %d\n", err);
9468 + goto csum_failed;
9469 + }
9470 +
9471 + /* Assign the data from skb->data to the first SG list entry */
9472 + sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
9473 + sg_len = skb_headlen(skb);
9474 + qm_sg_entry_set_bpid(&sgt[0], 0xff);
9475 + qm_sg_entry_set_offset(&sgt[0], 0);
9476 + qm_sg_entry_set_len(&sgt[0], sg_len);
9477 + qm_sg_entry_set_ext(&sgt[0], 0);
9478 + qm_sg_entry_set_final(&sgt[0], 0);
9479 +
9480 + addr = dma_map_single(dpa_bp->dev, skb->data, sg_len, dma_dir);
9481 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9482 + dev_err(dpa_bp->dev, "DMA mapping failed");
9483 + err = -EINVAL;
9484 + goto sg0_map_failed;
9485 + }
9486 +
9487 + qm_sg_entry_set64(&sgt[0], addr);
9488 +
9489 + /* populate the rest of SGT entries */
9490 + for (i = 1; i <= nr_frags; i++) {
9491 + frag = &skb_shinfo(skb)->frags[i - 1];
9492 + qm_sg_entry_set_bpid(&sgt[i], 0xff);
9493 + qm_sg_entry_set_offset(&sgt[i], 0);
9494 + qm_sg_entry_set_len(&sgt[i], frag->size);
9495 + qm_sg_entry_set_ext(&sgt[i], 0);
9496 +
9497 + if (i == nr_frags)
9498 + qm_sg_entry_set_final(&sgt[i], 1);
9499 + else
9500 + qm_sg_entry_set_final(&sgt[i], 0);
9501 +
9502 + DPA_BUG_ON(!skb_frag_page(frag));
9503 + addr = skb_frag_dma_map(dpa_bp->dev, frag, 0, frag->size,
9504 + dma_dir);
9505 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9506 + dev_err(dpa_bp->dev, "DMA mapping failed");
9507 + err = -EINVAL;
9508 + goto sg_map_failed;
9509 + }
9510 +
9511 + /* keep the offset in the address */
9512 + qm_sg_entry_set64(&sgt[i], addr);
9513 + }
9514 +
9515 + fd->length20 = skb->len;
9516 + fd->offset = priv->tx_headroom;
9517 +
9518 + /* DMA map the SGT page */
9519 + DPA_WRITE_SKB_PTR(skb, skbh, sgt_buf, 0);
9520 + addr = dma_map_single(dpa_bp->dev, sgt_buf,
9521 + priv->tx_headroom + sgt_size,
9522 + dma_dir);
9523 +
9524 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9525 + dev_err(dpa_bp->dev, "DMA mapping failed");
9526 + err = -EINVAL;
9527 + goto sgt_map_failed;
9528 + }
9529 +
9530 + qm_fd_addr_set64(fd, addr);
9531 + fd->bpid = 0xff;
9532 + fd->cmd |= FM_FD_CMD_FCO;
9533 +
9534 + return 0;
9535 +
9536 +sgt_map_failed:
9537 +sg_map_failed:
9538 + for (j = 0; j < i; j++) {
9539 + sg_addr = qm_sg_addr(&sgt[j]);
9540 + dma_unmap_page(dpa_bp->dev, sg_addr,
9541 + qm_sg_entry_get_len(&sgt[j]), dma_dir);
9542 + }
9543 +sg0_map_failed:
9544 +csum_failed:
9545 + put_page(virt_to_head_page(sgt_buf));
9546 +
9547 + return err;
9548 +}
9549 +EXPORT_SYMBOL(skb_to_sg_fd);
9550 +
9551 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev)
9552 +{
9553 + struct dpa_priv_s *priv;
9554 + const int queue_mapping = dpa_get_queue_mapping(skb);
9555 + struct qman_fq *egress_fq, *conf_fq;
9556 +
9557 +#ifdef CONFIG_FSL_DPAA_HOOKS
9558 + /* If there is a Tx hook, run it. */
9559 + if (dpaa_eth_hooks.tx &&
9560 + dpaa_eth_hooks.tx(skb, net_dev) == DPAA_ETH_STOLEN)
9561 + /* won't update any Tx stats */
9562 + return NETDEV_TX_OK;
9563 +#endif
9564 +
9565 + priv = netdev_priv(net_dev);
9566 +
9567 +#ifdef CONFIG_FSL_DPAA_CEETM
9568 + if (priv->ceetm_en)
9569 + return ceetm_tx(skb, net_dev);
9570 +#endif
9571 +
9572 + egress_fq = priv->egress_fqs[queue_mapping];
9573 + conf_fq = priv->conf_fqs[queue_mapping];
9574 +
9575 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
9576 +}
9577 +
9578 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
9579 + struct qman_fq *egress_fq, struct qman_fq *conf_fq)
9580 +{
9581 + struct dpa_priv_s *priv;
9582 + struct qm_fd fd;
9583 + struct dpa_percpu_priv_s *percpu_priv;
9584 + struct rtnl_link_stats64 *percpu_stats;
9585 + int err = 0;
9586 + bool nonlinear;
9587 + int *countptr, offset = 0;
9588 +
9589 + priv = netdev_priv(net_dev);
9590 + /* Non-migratable context, safe to use raw_cpu_ptr */
9591 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
9592 + percpu_stats = &percpu_priv->stats;
9593 + countptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
9594 +
9595 + clear_fd(&fd);
9596 +
9597 +#ifndef CONFIG_PPC
9598 + if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) {
9599 + skb = a010022_realign_skb(skb, priv);
9600 + if (!skb)
9601 + goto skb_to_fd_failed;
9602 + }
9603 +#endif
9604 +
9605 + nonlinear = skb_is_nonlinear(skb);
9606 +
9607 +#ifdef CONFIG_FSL_DPAA_1588
9608 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl)
9609 + fd.cmd |= FM_FD_CMD_UPD;
9610 +#endif
9611 +#ifdef CONFIG_FSL_DPAA_TS
9612 + if (unlikely(priv->ts_tx_en &&
9613 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
9614 + fd.cmd |= FM_FD_CMD_UPD;
9615 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
9616 +#endif /* CONFIG_FSL_DPAA_TS */
9617 +
9618 + /* MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure
9619 + * we don't feed FMan with more fragments than it supports.
9620 + * Btw, we're using the first sgt entry to store the linear part of
9621 + * the skb, so we're one extra frag short.
9622 + */
9623 + if (nonlinear &&
9624 + likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) {
9625 + /* Just create a S/G fd based on the skb */
9626 + err = skb_to_sg_fd(priv, skb, &fd);
9627 + percpu_priv->tx_frag_skbuffs++;
9628 + } else {
9629 + /* Make sure we have enough headroom to accommodate private
9630 + * data, parse results, etc. Normally this shouldn't happen if
9631 + * we're here via the standard kernel stack.
9632 + */
9633 + if (unlikely(skb_headroom(skb) < priv->tx_headroom)) {
9634 + struct sk_buff *skb_new;
9635 +
9636 + skb_new = skb_realloc_headroom(skb, priv->tx_headroom);
9637 + if (unlikely(!skb_new)) {
9638 + dev_kfree_skb(skb);
9639 + percpu_stats->tx_errors++;
9640 + return NETDEV_TX_OK;
9641 + }
9642 + dev_kfree_skb(skb);
9643 + skb = skb_new;
9644 + }
9645 +
9646 + /* We're going to store the skb backpointer at the beginning
9647 + * of the data buffer, so we need a privately owned skb
9648 + */
9649 +
9650 + /* Code borrowed from skb_unshare(). */
9651 + if (skb_cloned(skb)) {
9652 + struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
9653 + kfree_skb(skb);
9654 + skb = nskb;
9655 +#ifndef CONFIG_PPC
9656 + if (unlikely(dpaa_errata_a010022) &&
9657 + a010022_check_skb(skb, priv)) {
9658 + skb = a010022_realign_skb(skb, priv);
9659 + if (!skb)
9660 + goto skb_to_fd_failed;
9661 + }
9662 +#endif
9663 + /* skb_copy() has now linearized the skbuff. */
9664 + } else if (unlikely(nonlinear)) {
9665 + /* We are here because the egress skb contains
9666 + * more fragments than we support. In this case,
9667 + * we have no choice but to linearize it ourselves.
9668 + */
9669 + err = __skb_linearize(skb);
9670 + }
9671 + if (unlikely(!skb || err < 0))
9672 + /* Common out-of-memory error path */
9673 + goto enomem;
9674 +
9675 + err = skb_to_contig_fd(priv, skb, &fd, countptr, &offset);
9676 + }
9677 + if (unlikely(err < 0))
9678 + goto skb_to_fd_failed;
9679 +
9680 + if (fd.bpid != 0xff) {
9681 + skb_recycle(skb);
9682 + /* skb_recycle() reserves NET_SKB_PAD as skb headroom,
9683 + * but we need the skb to look as if returned by build_skb().
9684 + * We need to manually adjust the tailptr as well.
9685 + */
9686 + skb->data = skb->head + offset;
9687 + skb_reset_tail_pointer(skb);
9688 +
9689 + (*countptr)++;
9690 + percpu_priv->tx_returned++;
9691 + }
9692 +
9693 + if (unlikely(dpa_xmit(priv, percpu_stats, &fd, egress_fq, conf_fq) < 0))
9694 + goto xmit_failed;
9695 +
9696 + netif_trans_update(net_dev);
9697 + return NETDEV_TX_OK;
9698 +
9699 +xmit_failed:
9700 + if (fd.bpid != 0xff) {
9701 + (*countptr)--;
9702 + percpu_priv->tx_returned--;
9703 + dpa_fd_release(net_dev, &fd);
9704 + percpu_stats->tx_errors++;
9705 + return NETDEV_TX_OK;
9706 + }
9707 + _dpa_cleanup_tx_fd(priv, &fd);
9708 +skb_to_fd_failed:
9709 +enomem:
9710 + percpu_stats->tx_errors++;
9711 + dev_kfree_skb(skb);
9712 + return NETDEV_TX_OK;
9713 +}
9714 +EXPORT_SYMBOL(dpa_tx_extended);
9715 --- /dev/null
9716 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
9717 @@ -0,0 +1,278 @@
9718 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
9719 + *
9720 + * Redistribution and use in source and binary forms, with or without
9721 + * modification, are permitted provided that the following conditions are met:
9722 + * * Redistributions of source code must retain the above copyright
9723 + * notice, this list of conditions and the following disclaimer.
9724 + * * Redistributions in binary form must reproduce the above copyright
9725 + * notice, this list of conditions and the following disclaimer in the
9726 + * documentation and/or other materials provided with the distribution.
9727 + * * Neither the name of Freescale Semiconductor nor the
9728 + * names of its contributors may be used to endorse or promote products
9729 + * derived from this software without specific prior written permission.
9730 + *
9731 + *
9732 + * ALTERNATIVELY, this software may be distributed under the terms of the
9733 + * GNU General Public License ("GPL") as published by the Free Software
9734 + * Foundation, either version 2 of that License or (at your option) any
9735 + * later version.
9736 + *
9737 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
9738 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9739 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9740 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
9741 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
9742 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9743 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
9744 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9745 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
9746 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9747 + */
9748 +
9749 +#include <linux/init.h>
9750 +#include <linux/module.h>
9751 +#include <linux/kthread.h>
9752 +#include <linux/io.h>
9753 +#include <linux/of_net.h>
9754 +#include "dpaa_eth.h"
9755 +#include "mac.h" /* struct mac_device */
9756 +#ifdef CONFIG_FSL_DPAA_1588
9757 +#include "dpaa_1588.h"
9758 +#endif
9759 +
9760 +static ssize_t dpaa_eth_show_addr(struct device *dev,
9761 + struct device_attribute *attr, char *buf)
9762 +{
9763 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9764 + struct mac_device *mac_dev = priv->mac_dev;
9765 +
9766 + if (mac_dev)
9767 + return sprintf(buf, "%llx",
9768 + (unsigned long long)mac_dev->res->start);
9769 + else
9770 + return sprintf(buf, "none");
9771 +}
9772 +
9773 +static ssize_t dpaa_eth_show_type(struct device *dev,
9774 + struct device_attribute *attr, char *buf)
9775 +{
9776 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9777 + ssize_t res = 0;
9778 +
9779 + if (priv)
9780 + res = sprintf(buf, "%s", priv->if_type);
9781 +
9782 + return res;
9783 +}
9784 +
9785 +static ssize_t dpaa_eth_show_fqids(struct device *dev,
9786 + struct device_attribute *attr, char *buf)
9787 +{
9788 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9789 + ssize_t bytes = 0;
9790 + int i = 0;
9791 + char *str;
9792 + struct dpa_fq *fq;
9793 + struct dpa_fq *tmp;
9794 + struct dpa_fq *prev = NULL;
9795 + u32 first_fqid = 0;
9796 + u32 last_fqid = 0;
9797 + char *prevstr = NULL;
9798 +
9799 + list_for_each_entry_safe(fq, tmp, &priv->dpa_fq_list, list) {
9800 + switch (fq->fq_type) {
9801 + case FQ_TYPE_RX_DEFAULT:
9802 + str = "Rx default";
9803 + break;
9804 + case FQ_TYPE_RX_ERROR:
9805 + str = "Rx error";
9806 + break;
9807 + case FQ_TYPE_RX_PCD:
9808 + str = "Rx PCD";
9809 + break;
9810 + case FQ_TYPE_TX_CONFIRM:
9811 + str = "Tx default confirmation";
9812 + break;
9813 + case FQ_TYPE_TX_CONF_MQ:
9814 + str = "Tx confirmation (mq)";
9815 + break;
9816 + case FQ_TYPE_TX_ERROR:
9817 + str = "Tx error";
9818 + break;
9819 + case FQ_TYPE_TX:
9820 + str = "Tx";
9821 + break;
9822 + case FQ_TYPE_RX_PCD_HI_PRIO:
9823 + str ="Rx PCD High Priority";
9824 + break;
9825 + default:
9826 + str = "Unknown";
9827 + }
9828 +
9829 + if (prev && (abs(fq->fqid - prev->fqid) != 1 ||
9830 + str != prevstr)) {
9831 + if (last_fqid == first_fqid)
9832 + bytes += sprintf(buf + bytes,
9833 + "%s: %d\n", prevstr, prev->fqid);
9834 + else
9835 + bytes += sprintf(buf + bytes,
9836 + "%s: %d - %d\n", prevstr,
9837 + first_fqid, last_fqid);
9838 + }
9839 +
9840 + if (prev && abs(fq->fqid - prev->fqid) == 1 && str == prevstr)
9841 + last_fqid = fq->fqid;
9842 + else
9843 + first_fqid = last_fqid = fq->fqid;
9844 +
9845 + prev = fq;
9846 + prevstr = str;
9847 + i++;
9848 + }
9849 +
9850 + if (prev) {
9851 + if (last_fqid == first_fqid)
9852 + bytes += sprintf(buf + bytes, "%s: %d\n", prevstr,
9853 + prev->fqid);
9854 + else
9855 + bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr,
9856 + first_fqid, last_fqid);
9857 + }
9858 +
9859 + return bytes;
9860 +}
9861 +
9862 +static ssize_t dpaa_eth_show_bpids(struct device *dev,
9863 + struct device_attribute *attr, char *buf)
9864 +{
9865 + ssize_t bytes = 0;
9866 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9867 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9868 + int i = 0;
9869 +
9870 + for (i = 0; i < priv->bp_count; i++)
9871 + bytes += snprintf(buf + bytes, PAGE_SIZE, "%u\n",
9872 + dpa_bp[i].bpid);
9873 +
9874 + return bytes;
9875 +}
9876 +
9877 +static ssize_t dpaa_eth_show_mac_regs(struct device *dev,
9878 + struct device_attribute *attr, char *buf)
9879 +{
9880 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9881 + struct mac_device *mac_dev = priv->mac_dev;
9882 + int n = 0;
9883 +
9884 + if (mac_dev)
9885 + n = fm_mac_dump_regs(mac_dev, buf, n);
9886 + else
9887 + return sprintf(buf, "no mac registers\n");
9888 +
9889 + return n;
9890 +}
9891 +
9892 +static ssize_t dpaa_eth_show_mac_rx_stats(struct device *dev,
9893 + struct device_attribute *attr, char *buf)
9894 +{
9895 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9896 + struct mac_device *mac_dev = priv->mac_dev;
9897 + int n = 0;
9898 +
9899 + if (mac_dev)
9900 + n = fm_mac_dump_rx_stats(mac_dev, buf, n);
9901 + else
9902 + return sprintf(buf, "no mac rx stats\n");
9903 +
9904 + return n;
9905 +}
9906 +
9907 +static ssize_t dpaa_eth_show_mac_tx_stats(struct device *dev,
9908 + struct device_attribute *attr, char *buf)
9909 +{
9910 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9911 + struct mac_device *mac_dev = priv->mac_dev;
9912 + int n = 0;
9913 +
9914 + if (mac_dev)
9915 + n = fm_mac_dump_tx_stats(mac_dev, buf, n);
9916 + else
9917 + return sprintf(buf, "no mac tx stats\n");
9918 +
9919 + return n;
9920 +}
9921 +
9922 +#ifdef CONFIG_FSL_DPAA_1588
9923 +static ssize_t dpaa_eth_show_ptp_1588(struct device *dev,
9924 + struct device_attribute *attr, char *buf)
9925 +{
9926 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9927 +
9928 + if (priv->tsu && priv->tsu->valid)
9929 + return sprintf(buf, "1\n");
9930 + else
9931 + return sprintf(buf, "0\n");
9932 +}
9933 +
9934 +static ssize_t dpaa_eth_set_ptp_1588(struct device *dev,
9935 + struct device_attribute *attr,
9936 + const char *buf, size_t count)
9937 +{
9938 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9939 + unsigned int num;
9940 + unsigned long flags;
9941 +
9942 + if (kstrtouint(buf, 0, &num) < 0)
9943 + return -EINVAL;
9944 +
9945 + local_irq_save(flags);
9946 +
9947 + if (num) {
9948 + if (priv->tsu)
9949 + priv->tsu->valid = TRUE;
9950 + } else {
9951 + if (priv->tsu)
9952 + priv->tsu->valid = FALSE;
9953 + }
9954 +
9955 + local_irq_restore(flags);
9956 +
9957 + return count;
9958 +}
9959 +#endif
9960 +
9961 +static struct device_attribute dpaa_eth_attrs[] = {
9962 + __ATTR(device_addr, S_IRUGO, dpaa_eth_show_addr, NULL),
9963 + __ATTR(device_type, S_IRUGO, dpaa_eth_show_type, NULL),
9964 + __ATTR(fqids, S_IRUGO, dpaa_eth_show_fqids, NULL),
9965 + __ATTR(bpids, S_IRUGO, dpaa_eth_show_bpids, NULL),
9966 + __ATTR(mac_regs, S_IRUGO, dpaa_eth_show_mac_regs, NULL),
9967 + __ATTR(mac_rx_stats, S_IRUGO, dpaa_eth_show_mac_rx_stats, NULL),
9968 + __ATTR(mac_tx_stats, S_IRUGO, dpaa_eth_show_mac_tx_stats, NULL),
9969 +#ifdef CONFIG_FSL_DPAA_1588
9970 + __ATTR(ptp_1588, S_IRUGO | S_IWUSR, dpaa_eth_show_ptp_1588,
9971 + dpaa_eth_set_ptp_1588),
9972 +#endif
9973 +};
9974 +
9975 +void dpaa_eth_sysfs_init(struct device *dev)
9976 +{
9977 + int i;
9978 +
9979 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
9980 + if (device_create_file(dev, &dpaa_eth_attrs[i])) {
9981 + dev_err(dev, "Error creating sysfs file\n");
9982 + while (i > 0)
9983 + device_remove_file(dev, &dpaa_eth_attrs[--i]);
9984 + return;
9985 + }
9986 +}
9987 +EXPORT_SYMBOL(dpaa_eth_sysfs_init);
9988 +
9989 +void dpaa_eth_sysfs_remove(struct device *dev)
9990 +{
9991 + int i;
9992 +
9993 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
9994 + device_remove_file(dev, &dpaa_eth_attrs[i]);
9995 +}
9996 --- /dev/null
9997 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
9998 @@ -0,0 +1,144 @@
9999 +/* Copyright 2013 Freescale Semiconductor Inc.
10000 + *
10001 + * Redistribution and use in source and binary forms, with or without
10002 + * modification, are permitted provided that the following conditions are met:
10003 + * * Redistributions of source code must retain the above copyright
10004 + * notice, this list of conditions and the following disclaimer.
10005 + * * Redistributions in binary form must reproduce the above copyright
10006 + * notice, this list of conditions and the following disclaimer in the
10007 + * documentation and/or other materials provided with the distribution.
10008 + * * Neither the name of Freescale Semiconductor nor the
10009 + * names of its contributors may be used to endorse or promote products
10010 + * derived from this software without specific prior written permission.
10011 + *
10012 + *
10013 + * ALTERNATIVELY, this software may be distributed under the terms of the
10014 + * GNU General Public License ("GPL") as published by the Free Software
10015 + * Foundation, either version 2 of that License or (at your option) any
10016 + * later version.
10017 + *
10018 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10019 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10020 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10021 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10022 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10023 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10024 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10025 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10026 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10027 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10028 + */
10029 +
10030 +#undef TRACE_SYSTEM
10031 +#define TRACE_SYSTEM dpaa_eth
10032 +
10033 +#if !defined(_DPAA_ETH_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
10034 +#define _DPAA_ETH_TRACE_H
10035 +
10036 +#include <linux/skbuff.h>
10037 +#include <linux/netdevice.h>
10038 +#include "dpaa_eth.h"
10039 +#include <linux/tracepoint.h>
10040 +
10041 +#define fd_format_name(format) { qm_fd_##format, #format }
10042 +#define fd_format_list \
10043 + fd_format_name(contig), \
10044 + fd_format_name(sg)
10045 +#define TR_FMT "[%s] fqid=%d, fd: addr=0x%llx, format=%s, off=%u, len=%u," \
10046 + " status=0x%08x"
10047 +
10048 +/* This is used to declare a class of events.
10049 + * individual events of this type will be defined below.
10050 + */
10051 +
10052 +/* Store details about a frame descriptor and the FQ on which it was
10053 + * transmitted/received.
10054 + */
10055 +DECLARE_EVENT_CLASS(dpaa_eth_fd,
10056 + /* Trace function prototype */
10057 + TP_PROTO(struct net_device *netdev,
10058 + struct qman_fq *fq,
10059 + const struct qm_fd *fd),
10060 +
10061 + /* Repeat argument list here */
10062 + TP_ARGS(netdev, fq, fd),
10063 +
10064 + /* A structure containing the relevant information we want to record.
10065 + * Declare name and type for each normal element, name, type and size
10066 + * for arrays. Use __string for variable length strings.
10067 + */
10068 + TP_STRUCT__entry(
10069 + __field(u32, fqid)
10070 + __field(u64, fd_addr)
10071 + __field(u8, fd_format)
10072 + __field(u16, fd_offset)
10073 + __field(u32, fd_length)
10074 + __field(u32, fd_status)
10075 + __string(name, netdev->name)
10076 + ),
10077 +
10078 + /* The function that assigns values to the above declared fields */
10079 + TP_fast_assign(
10080 + __entry->fqid = fq->fqid;
10081 + __entry->fd_addr = qm_fd_addr_get64(fd);
10082 + __entry->fd_format = fd->format;
10083 + __entry->fd_offset = dpa_fd_offset(fd);
10084 + __entry->fd_length = dpa_fd_length(fd);
10085 + __entry->fd_status = fd->status;
10086 + __assign_str(name, netdev->name);
10087 + ),
10088 +
10089 + /* This is what gets printed when the trace event is triggered */
10090 + /* TODO: print the status using __print_flags() */
10091 + TP_printk(TR_FMT,
10092 + __get_str(name), __entry->fqid, __entry->fd_addr,
10093 + __print_symbolic(__entry->fd_format, fd_format_list),
10094 + __entry->fd_offset, __entry->fd_length, __entry->fd_status)
10095 +);
10096 +
10097 +/* Now declare events of the above type. Format is:
10098 + * DEFINE_EVENT(class, name, proto, args), with proto and args same as for class
10099 + */
10100 +
10101 +/* Tx (egress) fd */
10102 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_fd,
10103 +
10104 + TP_PROTO(struct net_device *netdev,
10105 + struct qman_fq *fq,
10106 + const struct qm_fd *fd),
10107 +
10108 + TP_ARGS(netdev, fq, fd)
10109 +);
10110 +
10111 +/* Rx fd */
10112 +DEFINE_EVENT(dpaa_eth_fd, dpa_rx_fd,
10113 +
10114 + TP_PROTO(struct net_device *netdev,
10115 + struct qman_fq *fq,
10116 + const struct qm_fd *fd),
10117 +
10118 + TP_ARGS(netdev, fq, fd)
10119 +);
10120 +
10121 +/* Tx confirmation fd */
10122 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_conf_fd,
10123 +
10124 + TP_PROTO(struct net_device *netdev,
10125 + struct qman_fq *fq,
10126 + const struct qm_fd *fd),
10127 +
10128 + TP_ARGS(netdev, fq, fd)
10129 +);
10130 +
10131 +/* If only one event of a certain type needs to be declared, use TRACE_EVENT().
10132 + * The syntax is the same as for DECLARE_EVENT_CLASS().
10133 + */
10134 +
10135 +#endif /* _DPAA_ETH_TRACE_H */
10136 +
10137 +/* This must be outside ifdef _DPAA_ETH_TRACE_H */
10138 +#undef TRACE_INCLUDE_PATH
10139 +#define TRACE_INCLUDE_PATH .
10140 +#undef TRACE_INCLUDE_FILE
10141 +#define TRACE_INCLUDE_FILE dpaa_eth_trace
10142 +#include <trace/define_trace.h>
10143 --- /dev/null
10144 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
10145 @@ -0,0 +1,544 @@
10146 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
10147 + *
10148 + * Redistribution and use in source and binary forms, with or without
10149 + * modification, are permitted provided that the following conditions are met:
10150 + * * Redistributions of source code must retain the above copyright
10151 + * notice, this list of conditions and the following disclaimer.
10152 + * * Redistributions in binary form must reproduce the above copyright
10153 + * notice, this list of conditions and the following disclaimer in the
10154 + * documentation and/or other materials provided with the distribution.
10155 + * * Neither the name of Freescale Semiconductor nor the
10156 + * names of its contributors may be used to endorse or promote products
10157 + * derived from this software without specific prior written permission.
10158 + *
10159 + *
10160 + * ALTERNATIVELY, this software may be distributed under the terms of the
10161 + * GNU General Public License ("GPL") as published by the Free Software
10162 + * Foundation, either version 2 of that License or (at your option) any
10163 + * later version.
10164 + *
10165 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10166 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10167 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10168 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10169 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10170 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10171 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10172 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10173 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10174 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10175 + */
10176 +
10177 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
10178 +#define pr_fmt(fmt) \
10179 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
10180 + KBUILD_BASENAME".c", __LINE__, __func__
10181 +#else
10182 +#define pr_fmt(fmt) \
10183 + KBUILD_MODNAME ": " fmt
10184 +#endif
10185 +
10186 +#include <linux/string.h>
10187 +
10188 +#include "dpaa_eth.h"
10189 +#include "mac.h" /* struct mac_device */
10190 +#include "dpaa_eth_common.h"
10191 +
10192 +static const char dpa_stats_percpu[][ETH_GSTRING_LEN] = {
10193 + "interrupts",
10194 + "rx packets",
10195 + "tx packets",
10196 + "tx recycled",
10197 + "tx confirm",
10198 + "tx S/G",
10199 + "rx S/G",
10200 + "tx error",
10201 + "rx error",
10202 + "bp count"
10203 +};
10204 +
10205 +static char dpa_stats_global[][ETH_GSTRING_LEN] = {
10206 + /* dpa rx errors */
10207 + "rx dma error",
10208 + "rx frame physical error",
10209 + "rx frame size error",
10210 + "rx header error",
10211 + "rx csum error",
10212 +
10213 + /* demultiplexing errors */
10214 + "qman cg_tdrop",
10215 + "qman wred",
10216 + "qman error cond",
10217 + "qman early window",
10218 + "qman late window",
10219 + "qman fq tdrop",
10220 + "qman fq retired",
10221 + "qman orp disabled",
10222 +
10223 + /* congestion related stats */
10224 + "congestion time (ms)",
10225 + "entered congestion",
10226 + "congested (0/1)"
10227 +};
10228 +
10229 +#define DPA_STATS_PERCPU_LEN ARRAY_SIZE(dpa_stats_percpu)
10230 +#define DPA_STATS_GLOBAL_LEN ARRAY_SIZE(dpa_stats_global)
10231 +
10232 +static int __cold dpa_get_settings(struct net_device *net_dev,
10233 + struct ethtool_cmd *et_cmd)
10234 +{
10235 + int _errno;
10236 + struct dpa_priv_s *priv;
10237 +
10238 + priv = netdev_priv(net_dev);
10239 +
10240 + if (priv->mac_dev == NULL) {
10241 + netdev_info(net_dev, "This is a MAC-less interface\n");
10242 + return -ENODEV;
10243 + }
10244 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10245 + netdev_dbg(net_dev, "phy device not initialized\n");
10246 + return 0;
10247 + }
10248 +
10249 + _errno = phy_ethtool_gset(priv->mac_dev->phy_dev, et_cmd);
10250 + if (unlikely(_errno < 0))
10251 + netdev_err(net_dev, "phy_ethtool_gset() = %d\n", _errno);
10252 +
10253 + return _errno;
10254 +}
10255 +
10256 +static int __cold dpa_set_settings(struct net_device *net_dev,
10257 + struct ethtool_cmd *et_cmd)
10258 +{
10259 + int _errno;
10260 + struct dpa_priv_s *priv;
10261 +
10262 + priv = netdev_priv(net_dev);
10263 +
10264 + if (priv->mac_dev == NULL) {
10265 + netdev_info(net_dev, "This is a MAC-less interface\n");
10266 + return -ENODEV;
10267 + }
10268 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10269 + netdev_err(net_dev, "phy device not initialized\n");
10270 + return -ENODEV;
10271 + }
10272 +
10273 + _errno = phy_ethtool_sset(priv->mac_dev->phy_dev, et_cmd);
10274 + if (unlikely(_errno < 0))
10275 + netdev_err(net_dev, "phy_ethtool_sset() = %d\n", _errno);
10276 +
10277 + return _errno;
10278 +}
10279 +
10280 +static void __cold dpa_get_drvinfo(struct net_device *net_dev,
10281 + struct ethtool_drvinfo *drvinfo)
10282 +{
10283 + int _errno;
10284 +
10285 + strncpy(drvinfo->driver, KBUILD_MODNAME,
10286 + sizeof(drvinfo->driver) - 1)[sizeof(drvinfo->driver)-1] = 0;
10287 + _errno = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
10288 + "%X", 0);
10289 +
10290 + if (unlikely(_errno >= sizeof(drvinfo->fw_version))) {
10291 + /* Truncated output */
10292 + netdev_notice(net_dev, "snprintf() = %d\n", _errno);
10293 + } else if (unlikely(_errno < 0)) {
10294 + netdev_warn(net_dev, "snprintf() = %d\n", _errno);
10295 + memset(drvinfo->fw_version, 0, sizeof(drvinfo->fw_version));
10296 + }
10297 + strncpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
10298 + sizeof(drvinfo->bus_info)-1)[sizeof(drvinfo->bus_info)-1] = 0;
10299 +}
10300 +
10301 +static uint32_t __cold dpa_get_msglevel(struct net_device *net_dev)
10302 +{
10303 + return ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable;
10304 +}
10305 +
10306 +static void __cold dpa_set_msglevel(struct net_device *net_dev,
10307 + uint32_t msg_enable)
10308 +{
10309 + ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable = msg_enable;
10310 +}
10311 +
10312 +static int __cold dpa_nway_reset(struct net_device *net_dev)
10313 +{
10314 + int _errno;
10315 + struct dpa_priv_s *priv;
10316 +
10317 + priv = netdev_priv(net_dev);
10318 +
10319 + if (priv->mac_dev == NULL) {
10320 + netdev_info(net_dev, "This is a MAC-less interface\n");
10321 + return -ENODEV;
10322 + }
10323 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10324 + netdev_err(net_dev, "phy device not initialized\n");
10325 + return -ENODEV;
10326 + }
10327 +
10328 + _errno = 0;
10329 + if (priv->mac_dev->phy_dev->autoneg) {
10330 + _errno = phy_start_aneg(priv->mac_dev->phy_dev);
10331 + if (unlikely(_errno < 0))
10332 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10333 + _errno);
10334 + }
10335 +
10336 + return _errno;
10337 +}
10338 +
10339 +static void __cold dpa_get_pauseparam(struct net_device *net_dev,
10340 + struct ethtool_pauseparam *epause)
10341 +{
10342 + struct dpa_priv_s *priv;
10343 + struct mac_device *mac_dev;
10344 + struct phy_device *phy_dev;
10345 +
10346 + priv = netdev_priv(net_dev);
10347 + mac_dev = priv->mac_dev;
10348 +
10349 + if (mac_dev == NULL) {
10350 + netdev_info(net_dev, "This is a MAC-less interface\n");
10351 + return;
10352 + }
10353 +
10354 + phy_dev = mac_dev->phy_dev;
10355 + if (unlikely(phy_dev == NULL)) {
10356 + netdev_err(net_dev, "phy device not initialized\n");
10357 + return;
10358 + }
10359 +
10360 + epause->autoneg = mac_dev->autoneg_pause;
10361 + epause->rx_pause = mac_dev->rx_pause_active;
10362 + epause->tx_pause = mac_dev->tx_pause_active;
10363 +}
10364 +
10365 +static int __cold dpa_set_pauseparam(struct net_device *net_dev,
10366 + struct ethtool_pauseparam *epause)
10367 +{
10368 + struct dpa_priv_s *priv;
10369 + struct mac_device *mac_dev;
10370 + struct phy_device *phy_dev;
10371 + int _errno;
10372 + u32 newadv, oldadv;
10373 + bool rx_pause, tx_pause;
10374 +
10375 + priv = netdev_priv(net_dev);
10376 + mac_dev = priv->mac_dev;
10377 +
10378 + if (mac_dev == NULL) {
10379 + netdev_info(net_dev, "This is a MAC-less interface\n");
10380 + return -ENODEV;
10381 + }
10382 +
10383 + phy_dev = mac_dev->phy_dev;
10384 + if (unlikely(phy_dev == NULL)) {
10385 + netdev_err(net_dev, "phy device not initialized\n");
10386 + return -ENODEV;
10387 + }
10388 +
10389 + if (!(phy_dev->supported & SUPPORTED_Pause) ||
10390 + (!(phy_dev->supported & SUPPORTED_Asym_Pause) &&
10391 + (epause->rx_pause != epause->tx_pause)))
10392 + return -EINVAL;
10393 +
10394 + /* The MAC should know how to handle PAUSE frame autonegotiation before
10395 + * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
10396 + * settings.
10397 + */
10398 + mac_dev->autoneg_pause = !!epause->autoneg;
10399 + mac_dev->rx_pause_req = !!epause->rx_pause;
10400 + mac_dev->tx_pause_req = !!epause->tx_pause;
10401 +
10402 + /* Determine the sym/asym advertised PAUSE capabilities from the desired
10403 + * rx/tx pause settings.
10404 + */
10405 + newadv = 0;
10406 + if (epause->rx_pause)
10407 + newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause;
10408 + if (epause->tx_pause)
10409 + newadv |= ADVERTISED_Asym_Pause;
10410 +
10411 + oldadv = phy_dev->advertising &
10412 + (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
10413 +
10414 + /* If there are differences between the old and the new advertised
10415 + * values, restart PHY autonegotiation and advertise the new values.
10416 + */
10417 + if (oldadv != newadv) {
10418 + phy_dev->advertising &= ~(ADVERTISED_Pause
10419 + | ADVERTISED_Asym_Pause);
10420 + phy_dev->advertising |= newadv;
10421 + if (phy_dev->autoneg) {
10422 + _errno = phy_start_aneg(phy_dev);
10423 + if (unlikely(_errno < 0))
10424 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10425 + _errno);
10426 + }
10427 + }
10428 +
10429 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
10430 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
10431 + if (unlikely(_errno < 0))
10432 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
10433 +
10434 + return _errno;
10435 +}
10436 +
10437 +#ifdef CONFIG_PM
10438 +static void dpa_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10439 +{
10440 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10441 +
10442 + wol->supported = 0;
10443 + wol->wolopts = 0;
10444 +
10445 + if (!priv->wol || !device_can_wakeup(net_dev->dev.parent))
10446 + return;
10447 +
10448 + if (priv->wol & DPAA_WOL_MAGIC) {
10449 + wol->supported = WAKE_MAGIC;
10450 + wol->wolopts = WAKE_MAGIC;
10451 + }
10452 +}
10453 +
10454 +static int dpa_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10455 +{
10456 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10457 +
10458 + if (priv->mac_dev == NULL) {
10459 + netdev_info(net_dev, "This is a MAC-less interface\n");
10460 + return -ENODEV;
10461 + }
10462 +
10463 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10464 + netdev_dbg(net_dev, "phy device not initialized\n");
10465 + return -ENODEV;
10466 + }
10467 +
10468 + if (!device_can_wakeup(net_dev->dev.parent) ||
10469 + (wol->wolopts & ~WAKE_MAGIC))
10470 + return -EOPNOTSUPP;
10471 +
10472 + priv->wol = 0;
10473 +
10474 + if (wol->wolopts & WAKE_MAGIC) {
10475 + priv->wol = DPAA_WOL_MAGIC;
10476 + device_set_wakeup_enable(net_dev->dev.parent, 1);
10477 + } else {
10478 + device_set_wakeup_enable(net_dev->dev.parent, 0);
10479 + }
10480 +
10481 + return 0;
10482 +}
10483 +#endif
10484 +
10485 +static int dpa_get_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10486 +{
10487 + struct dpa_priv_s *priv;
10488 +
10489 + priv = netdev_priv(net_dev);
10490 + if (priv->mac_dev == NULL) {
10491 + netdev_info(net_dev, "This is a MAC-less interface\n");
10492 + return -ENODEV;
10493 + }
10494 +
10495 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10496 + netdev_err(net_dev, "phy device not initialized\n");
10497 + return -ENODEV;
10498 + }
10499 +
10500 + return phy_ethtool_get_eee(priv->mac_dev->phy_dev, et_eee);
10501 +}
10502 +
10503 +static int dpa_set_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10504 +{
10505 + struct dpa_priv_s *priv;
10506 +
10507 + priv = netdev_priv(net_dev);
10508 + if (priv->mac_dev == NULL) {
10509 + netdev_info(net_dev, "This is a MAC-less interface\n");
10510 + return -ENODEV;
10511 + }
10512 +
10513 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10514 + netdev_err(net_dev, "phy device not initialized\n");
10515 + return -ENODEV;
10516 + }
10517 +
10518 + return phy_ethtool_set_eee(priv->mac_dev->phy_dev, et_eee);
10519 +}
10520 +
10521 +static int dpa_get_sset_count(struct net_device *net_dev, int type)
10522 +{
10523 + unsigned int total_stats, num_stats;
10524 +
10525 + num_stats = num_online_cpus() + 1;
10526 + total_stats = num_stats * DPA_STATS_PERCPU_LEN + DPA_STATS_GLOBAL_LEN;
10527 +
10528 + switch (type) {
10529 + case ETH_SS_STATS:
10530 + return total_stats;
10531 + default:
10532 + return -EOPNOTSUPP;
10533 + }
10534 +}
10535 +
10536 +static void copy_stats(struct dpa_percpu_priv_s *percpu_priv, int num_cpus,
10537 + int crr_cpu, u64 bp_count, u64 *data)
10538 +{
10539 + int num_stat_values = num_cpus + 1;
10540 + int crr_stat = 0;
10541 +
10542 + /* update current CPU's stats and also add them to the total values */
10543 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->in_interrupt;
10544 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->in_interrupt;
10545 +
10546 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_packets;
10547 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_packets;
10548 +
10549 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_packets;
10550 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_packets;
10551 +
10552 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_returned;
10553 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_returned;
10554 +
10555 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_confirm;
10556 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_confirm;
10557 +
10558 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_frag_skbuffs;
10559 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_frag_skbuffs;
10560 +
10561 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->rx_sg;
10562 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->rx_sg;
10563 +
10564 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_errors;
10565 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_errors;
10566 +
10567 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_errors;
10568 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_errors;
10569 +
10570 + data[crr_stat * num_stat_values + crr_cpu] = bp_count;
10571 + data[crr_stat++ * num_stat_values + num_cpus] += bp_count;
10572 +}
10573 +
10574 +static void dpa_get_ethtool_stats(struct net_device *net_dev,
10575 + struct ethtool_stats *stats, u64 *data)
10576 +{
10577 + u64 bp_count, cg_time, cg_num, cg_status;
10578 + struct dpa_percpu_priv_s *percpu_priv;
10579 + struct qm_mcr_querycgr query_cgr;
10580 + struct dpa_rx_errors rx_errors;
10581 + struct dpa_ern_cnt ern_cnt;
10582 + struct dpa_priv_s *priv;
10583 + unsigned int num_cpus, offset;
10584 + struct dpa_bp *dpa_bp;
10585 + int total_stats, i;
10586 +
10587 + total_stats = dpa_get_sset_count(net_dev, ETH_SS_STATS);
10588 + priv = netdev_priv(net_dev);
10589 + dpa_bp = priv->dpa_bp;
10590 + num_cpus = num_online_cpus();
10591 + bp_count = 0;
10592 +
10593 + memset(&rx_errors, 0, sizeof(struct dpa_rx_errors));
10594 + memset(&ern_cnt, 0, sizeof(struct dpa_ern_cnt));
10595 + memset(data, 0, total_stats * sizeof(u64));
10596 +
10597 + for_each_online_cpu(i) {
10598 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
10599 +
10600 + if (dpa_bp->percpu_count)
10601 + bp_count = *(per_cpu_ptr(dpa_bp->percpu_count, i));
10602 +
10603 + rx_errors.dme += percpu_priv->rx_errors.dme;
10604 + rx_errors.fpe += percpu_priv->rx_errors.fpe;
10605 + rx_errors.fse += percpu_priv->rx_errors.fse;
10606 + rx_errors.phe += percpu_priv->rx_errors.phe;
10607 + rx_errors.cse += percpu_priv->rx_errors.cse;
10608 +
10609 + ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop;
10610 + ern_cnt.wred += percpu_priv->ern_cnt.wred;
10611 + ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond;
10612 + ern_cnt.early_window += percpu_priv->ern_cnt.early_window;
10613 + ern_cnt.late_window += percpu_priv->ern_cnt.late_window;
10614 + ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop;
10615 + ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired;
10616 + ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero;
10617 +
10618 + copy_stats(percpu_priv, num_cpus, i, bp_count, data);
10619 + }
10620 +
10621 + offset = (num_cpus + 1) * DPA_STATS_PERCPU_LEN;
10622 + memcpy(data + offset, &rx_errors, sizeof(struct dpa_rx_errors));
10623 +
10624 + offset += sizeof(struct dpa_rx_errors) / sizeof(u64);
10625 + memcpy(data + offset, &ern_cnt, sizeof(struct dpa_ern_cnt));
10626 +
10627 + /* gather congestion related counters */
10628 + cg_num = 0;
10629 + cg_status = 0;
10630 + cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies);
10631 + if (qman_query_cgr(&priv->cgr_data.cgr, &query_cgr) == 0) {
10632 + cg_num = priv->cgr_data.cgr_congested_count;
10633 + cg_status = query_cgr.cgr.cs;
10634 +
10635 + /* reset congestion stats (like QMan API does */
10636 + priv->cgr_data.congested_jiffies = 0;
10637 + priv->cgr_data.cgr_congested_count = 0;
10638 + }
10639 +
10640 + offset += sizeof(struct dpa_ern_cnt) / sizeof(u64);
10641 + data[offset++] = cg_time;
10642 + data[offset++] = cg_num;
10643 + data[offset++] = cg_status;
10644 +}
10645 +
10646 +static void dpa_get_strings(struct net_device *net_dev, u32 stringset, u8 *data)
10647 +{
10648 + unsigned int i, j, num_cpus, size;
10649 + char stat_string_cpu[ETH_GSTRING_LEN];
10650 + u8 *strings;
10651 +
10652 + strings = data;
10653 + num_cpus = num_online_cpus();
10654 + size = DPA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN;
10655 +
10656 + for (i = 0; i < DPA_STATS_PERCPU_LEN; i++) {
10657 + for (j = 0; j < num_cpus; j++) {
10658 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", dpa_stats_percpu[i], j);
10659 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10660 + strings += ETH_GSTRING_LEN;
10661 + }
10662 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", dpa_stats_percpu[i]);
10663 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10664 + strings += ETH_GSTRING_LEN;
10665 + }
10666 + memcpy(strings, dpa_stats_global, size);
10667 +}
10668 +
10669 +const struct ethtool_ops dpa_ethtool_ops = {
10670 + .get_settings = dpa_get_settings,
10671 + .set_settings = dpa_set_settings,
10672 + .get_drvinfo = dpa_get_drvinfo,
10673 + .get_msglevel = dpa_get_msglevel,
10674 + .set_msglevel = dpa_set_msglevel,
10675 + .nway_reset = dpa_nway_reset,
10676 + .get_pauseparam = dpa_get_pauseparam,
10677 + .set_pauseparam = dpa_set_pauseparam,
10678 + .self_test = NULL, /* TODO invoke the cold-boot unit-test? */
10679 + .get_link = ethtool_op_get_link,
10680 + .get_eee = dpa_get_eee,
10681 + .set_eee = dpa_set_eee,
10682 + .get_sset_count = dpa_get_sset_count,
10683 + .get_ethtool_stats = dpa_get_ethtool_stats,
10684 + .get_strings = dpa_get_strings,
10685 +#ifdef CONFIG_PM
10686 + .get_wol = dpa_get_wol,
10687 + .set_wol = dpa_set_wol,
10688 +#endif
10689 +};
10690 --- /dev/null
10691 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
10692 @@ -0,0 +1,291 @@
10693 +/*
10694 + * DPAA Ethernet Driver -- PTP 1588 clock using the dTSEC
10695 + *
10696 + * Author: Yangbo Lu <yangbo.lu@freescale.com>
10697 + *
10698 + * Copyright 2014 Freescale Semiconductor, Inc.
10699 + *
10700 + * This program is free software; you can redistribute it and/or modify it
10701 + * under the terms of the GNU General Public License as published by the
10702 + * Free Software Foundation; either version 2 of the License, or (at your
10703 + * option) any later version.
10704 +*/
10705 +
10706 +#include <linux/device.h>
10707 +#include <linux/hrtimer.h>
10708 +#include <linux/init.h>
10709 +#include <linux/interrupt.h>
10710 +#include <linux/kernel.h>
10711 +#include <linux/module.h>
10712 +#include <linux/of.h>
10713 +#include <linux/of_platform.h>
10714 +#include <linux/timex.h>
10715 +#include <linux/io.h>
10716 +
10717 +#include <linux/ptp_clock_kernel.h>
10718 +
10719 +#include "dpaa_eth.h"
10720 +#include "mac.h"
10721 +
10722 +static struct mac_device *mac_dev;
10723 +static u32 freqCompensation;
10724 +
10725 +/* Bit definitions for the TMR_CTRL register */
10726 +#define ALM1P (1<<31) /* Alarm1 output polarity */
10727 +#define ALM2P (1<<30) /* Alarm2 output polarity */
10728 +#define FS (1<<28) /* FIPER start indication */
10729 +#define PP1L (1<<27) /* Fiper1 pulse loopback mode enabled. */
10730 +#define PP2L (1<<26) /* Fiper2 pulse loopback mode enabled. */
10731 +#define TCLK_PERIOD_SHIFT (16) /* 1588 timer reference clock period. */
10732 +#define TCLK_PERIOD_MASK (0x3ff)
10733 +#define RTPE (1<<15) /* Record Tx Timestamp to PAL Enable. */
10734 +#define FRD (1<<14) /* FIPER Realignment Disable */
10735 +#define ESFDP (1<<11) /* External Tx/Rx SFD Polarity. */
10736 +#define ESFDE (1<<10) /* External Tx/Rx SFD Enable. */
10737 +#define ETEP2 (1<<9) /* External trigger 2 edge polarity */
10738 +#define ETEP1 (1<<8) /* External trigger 1 edge polarity */
10739 +#define COPH (1<<7) /* Generated clock output phase. */
10740 +#define CIPH (1<<6) /* External oscillator input clock phase */
10741 +#define TMSR (1<<5) /* Timer soft reset. */
10742 +#define BYP (1<<3) /* Bypass drift compensated clock */
10743 +#define TE (1<<2) /* 1588 timer enable. */
10744 +#define CKSEL_SHIFT (0) /* 1588 Timer reference clock source */
10745 +#define CKSEL_MASK (0x3)
10746 +
10747 +/* Bit definitions for the TMR_TEVENT register */
10748 +#define ETS2 (1<<25) /* External trigger 2 timestamp sampled */
10749 +#define ETS1 (1<<24) /* External trigger 1 timestamp sampled */
10750 +#define ALM2 (1<<17) /* Current time = alarm time register 2 */
10751 +#define ALM1 (1<<16) /* Current time = alarm time register 1 */
10752 +#define PP1 (1<<7) /* periodic pulse generated on FIPER1 */
10753 +#define PP2 (1<<6) /* periodic pulse generated on FIPER2 */
10754 +#define PP3 (1<<5) /* periodic pulse generated on FIPER3 */
10755 +
10756 +/* Bit definitions for the TMR_TEMASK register */
10757 +#define ETS2EN (1<<25) /* External trigger 2 timestamp enable */
10758 +#define ETS1EN (1<<24) /* External trigger 1 timestamp enable */
10759 +#define ALM2EN (1<<17) /* Timer ALM2 event enable */
10760 +#define ALM1EN (1<<16) /* Timer ALM1 event enable */
10761 +#define PP1EN (1<<7) /* Periodic pulse event 1 enable */
10762 +#define PP2EN (1<<6) /* Periodic pulse event 2 enable */
10763 +
10764 +/* Bit definitions for the TMR_PEVENT register */
10765 +#define TXP2 (1<<9) /* PTP transmitted timestamp im TXTS2 */
10766 +#define TXP1 (1<<8) /* PTP transmitted timestamp in TXTS1 */
10767 +#define RXP (1<<0) /* PTP frame has been received */
10768 +
10769 +/* Bit definitions for the TMR_PEMASK register */
10770 +#define TXP2EN (1<<9) /* Transmit PTP packet event 2 enable */
10771 +#define TXP1EN (1<<8) /* Transmit PTP packet event 1 enable */
10772 +#define RXPEN (1<<0) /* Receive PTP packet event enable */
10773 +
10774 +/* Bit definitions for the TMR_STAT register */
10775 +#define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */
10776 +#define STAT_VEC_MASK (0x3f)
10777 +
10778 +/* Bit definitions for the TMR_PRSC register */
10779 +#define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */
10780 +#define PRSC_OCK_MASK (0xffff)
10781 +
10782 +
10783 +#define N_EXT_TS 2
10784 +
10785 +static void set_alarm(void)
10786 +{
10787 + u64 ns;
10788 +
10789 + if (mac_dev->fm_rtc_get_cnt)
10790 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
10791 + ns += 1500000000ULL;
10792 + ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
10793 + ns -= DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10794 + if (mac_dev->fm_rtc_set_alarm)
10795 + mac_dev->fm_rtc_set_alarm(mac_dev->fm_dev, 0, ns);
10796 +}
10797 +
10798 +static void set_fipers(void)
10799 +{
10800 + u64 fiper;
10801 +
10802 + if (mac_dev->fm_rtc_disable)
10803 + mac_dev->fm_rtc_disable(mac_dev->fm_dev);
10804 +
10805 + set_alarm();
10806 + fiper = 1000000000ULL - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10807 + if (mac_dev->fm_rtc_set_fiper)
10808 + mac_dev->fm_rtc_set_fiper(mac_dev->fm_dev, 0, fiper);
10809 +
10810 + if (mac_dev->fm_rtc_enable)
10811 + mac_dev->fm_rtc_enable(mac_dev->fm_dev);
10812 +}
10813 +
10814 +/* PTP clock operations */
10815 +
10816 +static int ptp_dpa_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
10817 +{
10818 + u64 adj;
10819 + u32 diff, tmr_add;
10820 + int neg_adj = 0;
10821 +
10822 + if (ppb < 0) {
10823 + neg_adj = 1;
10824 + ppb = -ppb;
10825 + }
10826 +
10827 + tmr_add = freqCompensation;
10828 + adj = tmr_add;
10829 + adj *= ppb;
10830 + diff = div_u64(adj, 1000000000ULL);
10831 +
10832 + tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
10833 +
10834 + if (mac_dev->fm_rtc_set_drift)
10835 + mac_dev->fm_rtc_set_drift(mac_dev->fm_dev, tmr_add);
10836 +
10837 + return 0;
10838 +}
10839 +
10840 +static int ptp_dpa_adjtime(struct ptp_clock_info *ptp, s64 delta)
10841 +{
10842 + s64 now;
10843 +
10844 + if (mac_dev->fm_rtc_get_cnt)
10845 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &now);
10846 +
10847 + now += delta;
10848 +
10849 + if (mac_dev->fm_rtc_set_cnt)
10850 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, now);
10851 + set_fipers();
10852 +
10853 + return 0;
10854 +}
10855 +
10856 +static int ptp_dpa_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
10857 +{
10858 + u64 ns;
10859 + u32 remainder;
10860 +
10861 + if (mac_dev->fm_rtc_get_cnt)
10862 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
10863 +
10864 + ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
10865 + ts->tv_nsec = remainder;
10866 + return 0;
10867 +}
10868 +
10869 +static int ptp_dpa_settime(struct ptp_clock_info *ptp,
10870 + const struct timespec64 *ts)
10871 +{
10872 + u64 ns;
10873 +
10874 + ns = ts->tv_sec * 1000000000ULL;
10875 + ns += ts->tv_nsec;
10876 +
10877 + if (mac_dev->fm_rtc_set_cnt)
10878 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, ns);
10879 + set_fipers();
10880 + return 0;
10881 +}
10882 +
10883 +static int ptp_dpa_enable(struct ptp_clock_info *ptp,
10884 + struct ptp_clock_request *rq, int on)
10885 +{
10886 + u32 bit;
10887 +
10888 + switch (rq->type) {
10889 + case PTP_CLK_REQ_EXTTS:
10890 + switch (rq->extts.index) {
10891 + case 0:
10892 + bit = ETS1EN;
10893 + break;
10894 + case 1:
10895 + bit = ETS2EN;
10896 + break;
10897 + default:
10898 + return -EINVAL;
10899 + }
10900 + if (on) {
10901 + if (mac_dev->fm_rtc_enable_interrupt)
10902 + mac_dev->fm_rtc_enable_interrupt(
10903 + mac_dev->fm_dev, bit);
10904 + } else {
10905 + if (mac_dev->fm_rtc_disable_interrupt)
10906 + mac_dev->fm_rtc_disable_interrupt(
10907 + mac_dev->fm_dev, bit);
10908 + }
10909 + return 0;
10910 +
10911 + case PTP_CLK_REQ_PPS:
10912 + if (on) {
10913 + if (mac_dev->fm_rtc_enable_interrupt)
10914 + mac_dev->fm_rtc_enable_interrupt(
10915 + mac_dev->fm_dev, PP1EN);
10916 + } else {
10917 + if (mac_dev->fm_rtc_disable_interrupt)
10918 + mac_dev->fm_rtc_disable_interrupt(
10919 + mac_dev->fm_dev, PP1EN);
10920 + }
10921 + return 0;
10922 +
10923 + default:
10924 + break;
10925 + }
10926 +
10927 + return -EOPNOTSUPP;
10928 +}
10929 +
10930 +static struct ptp_clock_info ptp_dpa_caps = {
10931 + .owner = THIS_MODULE,
10932 + .name = "dpaa clock",
10933 + .max_adj = 512000,
10934 + .n_alarm = 0,
10935 + .n_ext_ts = N_EXT_TS,
10936 + .n_per_out = 0,
10937 + .pps = 1,
10938 + .adjfreq = ptp_dpa_adjfreq,
10939 + .adjtime = ptp_dpa_adjtime,
10940 + .gettime64 = ptp_dpa_gettime,
10941 + .settime64 = ptp_dpa_settime,
10942 + .enable = ptp_dpa_enable,
10943 +};
10944 +
10945 +static int __init __cold dpa_ptp_load(void)
10946 +{
10947 + struct device *ptp_dev;
10948 + struct timespec64 now;
10949 + struct ptp_clock *clock = ptp_priv.clock;
10950 + int dpa_phc_index;
10951 + int err;
10952 +
10953 + if (!(ptp_priv.of_dev && ptp_priv.mac_dev))
10954 + return -ENODEV;
10955 +
10956 + ptp_dev = &ptp_priv.of_dev->dev;
10957 + mac_dev = ptp_priv.mac_dev;
10958 +
10959 + if (mac_dev->fm_rtc_get_drift)
10960 + mac_dev->fm_rtc_get_drift(mac_dev->fm_dev, &freqCompensation);
10961 +
10962 + getnstimeofday64(&now);
10963 + ptp_dpa_settime(&ptp_dpa_caps, &now);
10964 +
10965 + clock = ptp_clock_register(&ptp_dpa_caps, ptp_dev);
10966 + if (IS_ERR(clock)) {
10967 + err = PTR_ERR(clock);
10968 + return err;
10969 + }
10970 + dpa_phc_index = ptp_clock_index(clock);
10971 + return 0;
10972 +}
10973 +module_init(dpa_ptp_load);
10974 +
10975 +static void __exit __cold dpa_ptp_unload(void)
10976 +{
10977 + struct ptp_clock *clock = ptp_priv.clock;
10978 +
10979 + if (mac_dev->fm_rtc_disable_interrupt)
10980 + mac_dev->fm_rtc_disable_interrupt(mac_dev->fm_dev, 0xffffffff);
10981 + ptp_clock_unregister(clock);
10982 +}
10983 +module_exit(dpa_ptp_unload);
10984 --- /dev/null
10985 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
10986 @@ -0,0 +1,907 @@
10987 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
10988 + *
10989 + * Redistribution and use in source and binary forms, with or without
10990 + * modification, are permitted provided that the following conditions are met:
10991 + * * Redistributions of source code must retain the above copyright
10992 + * notice, this list of conditions and the following disclaimer.
10993 + * * Redistributions in binary form must reproduce the above copyright
10994 + * notice, this list of conditions and the following disclaimer in the
10995 + * documentation and/or other materials provided with the distribution.
10996 + * * Neither the name of Freescale Semiconductor nor the
10997 + * names of its contributors may be used to endorse or promote products
10998 + * derived from this software without specific prior written permission.
10999 + *
11000 + *
11001 + * ALTERNATIVELY, this software may be distributed under the terms of the
11002 + * GNU General Public License ("GPL") as published by the Free Software
11003 + * Foundation, either version 2 of that License or (at your option) any
11004 + * later version.
11005 + *
11006 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11007 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11008 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11009 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11010 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11011 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11012 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11013 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11014 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11015 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11016 + */
11017 +
11018 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
11019 +#define pr_fmt(fmt) \
11020 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
11021 + KBUILD_BASENAME".c", __LINE__, __func__
11022 +#else
11023 +#define pr_fmt(fmt) \
11024 + KBUILD_MODNAME ": " fmt
11025 +#endif
11026 +
11027 +#include <linux/init.h>
11028 +#include <linux/module.h>
11029 +#include <linux/io.h>
11030 +#include <linux/of_platform.h>
11031 +#include <linux/of_mdio.h>
11032 +#include <linux/phy.h>
11033 +#include <linux/netdevice.h>
11034 +
11035 +#include "dpaa_eth.h"
11036 +#include "mac.h"
11037 +#include "lnxwrp_fsl_fman.h"
11038 +
11039 +#include "error_ext.h" /* GET_ERROR_TYPE, E_OK */
11040 +
11041 +#include "fsl_fman_dtsec.h"
11042 +#include "fsl_fman_tgec.h"
11043 +#include "fsl_fman_memac.h"
11044 +#include "../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h"
11045 +
11046 +#define MAC_DESCRIPTION "FSL FMan MAC API based driver"
11047 +
11048 +MODULE_LICENSE("Dual BSD/GPL");
11049 +
11050 +MODULE_AUTHOR("Emil Medve <Emilian.Medve@Freescale.com>");
11051 +
11052 +MODULE_DESCRIPTION(MAC_DESCRIPTION);
11053 +
11054 +struct mac_priv_s {
11055 + struct fm_mac_dev *fm_mac;
11056 +};
11057 +
11058 +const char *mac_driver_description __initconst = MAC_DESCRIPTION;
11059 +const size_t mac_sizeof_priv[] = {
11060 + [DTSEC] = sizeof(struct mac_priv_s),
11061 + [XGMAC] = sizeof(struct mac_priv_s),
11062 + [MEMAC] = sizeof(struct mac_priv_s)
11063 +};
11064 +
11065 +static const enet_mode_t _100[] = {
11066 + [PHY_INTERFACE_MODE_MII] = e_ENET_MODE_MII_100,
11067 + [PHY_INTERFACE_MODE_RMII] = e_ENET_MODE_RMII_100
11068 +};
11069 +
11070 +static const enet_mode_t _1000[] = {
11071 + [PHY_INTERFACE_MODE_GMII] = e_ENET_MODE_GMII_1000,
11072 + [PHY_INTERFACE_MODE_SGMII] = e_ENET_MODE_SGMII_1000,
11073 + [PHY_INTERFACE_MODE_QSGMII] = e_ENET_MODE_QSGMII_1000,
11074 + [PHY_INTERFACE_MODE_TBI] = e_ENET_MODE_TBI_1000,
11075 + [PHY_INTERFACE_MODE_RGMII] = e_ENET_MODE_RGMII_1000,
11076 + [PHY_INTERFACE_MODE_RGMII_ID] = e_ENET_MODE_RGMII_1000,
11077 + [PHY_INTERFACE_MODE_RGMII_RXID] = e_ENET_MODE_RGMII_1000,
11078 + [PHY_INTERFACE_MODE_RGMII_TXID] = e_ENET_MODE_RGMII_1000,
11079 + [PHY_INTERFACE_MODE_RTBI] = e_ENET_MODE_RTBI_1000
11080 +};
11081 +
11082 +static enet_mode_t __cold __attribute__((nonnull))
11083 +macdev2enetinterface(const struct mac_device *mac_dev)
11084 +{
11085 + switch (mac_dev->max_speed) {
11086 + case SPEED_100:
11087 + return _100[mac_dev->phy_if];
11088 + case SPEED_1000:
11089 + return _1000[mac_dev->phy_if];
11090 + case SPEED_2500:
11091 + return e_ENET_MODE_SGMII_2500;
11092 + case SPEED_10000:
11093 + return e_ENET_MODE_XGMII_10000;
11094 + default:
11095 + return e_ENET_MODE_MII_100;
11096 + }
11097 +}
11098 +
11099 +static void mac_exception(handle_t _mac_dev, e_FmMacExceptions exception)
11100 +{
11101 + struct mac_device *mac_dev;
11102 +
11103 + mac_dev = (struct mac_device *)_mac_dev;
11104 +
11105 + if (e_FM_MAC_EX_10G_RX_FIFO_OVFL == exception) {
11106 + /* don't flag RX FIFO after the first */
11107 + fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11108 + e_FM_MAC_EX_10G_RX_FIFO_OVFL, false);
11109 + dev_err(mac_dev->dev, "10G MAC got RX FIFO Error = %x\n",
11110 + exception);
11111 + }
11112 +
11113 + dev_dbg(mac_dev->dev, "%s:%s() -> %d\n", KBUILD_BASENAME".c", __func__,
11114 + exception);
11115 +}
11116 +
11117 +static int __cold init(struct mac_device *mac_dev)
11118 +{
11119 + int _errno;
11120 + struct mac_priv_s *priv;
11121 + t_FmMacParams param;
11122 + uint32_t version;
11123 +
11124 + priv = macdev_priv(mac_dev);
11125 +
11126 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11127 + mac_dev->dev, mac_dev->res->start, 0x2000);
11128 + param.enetMode = macdev2enetinterface(mac_dev);
11129 + memcpy(&param.addr, mac_dev->addr, min(sizeof(param.addr),
11130 + sizeof(mac_dev->addr)));
11131 + param.macId = mac_dev->cell_index;
11132 + param.h_Fm = (handle_t)mac_dev->fm;
11133 + param.mdioIrq = NO_IRQ;
11134 + param.f_Exception = mac_exception;
11135 + param.f_Event = mac_exception;
11136 + param.h_App = mac_dev;
11137 +
11138 + priv->fm_mac = fm_mac_config(&param);
11139 + if (unlikely(priv->fm_mac == NULL)) {
11140 + _errno = -EINVAL;
11141 + goto _return;
11142 + }
11143 +
11144 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11145 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11146 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11147 +
11148 + _errno = fm_mac_config_max_frame_length(priv->fm_mac,
11149 + fm_get_max_frm());
11150 + if (unlikely(_errno < 0))
11151 + goto _return_fm_mac_free;
11152 +
11153 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11154 + /* 10G always works with pad and CRC */
11155 + _errno = fm_mac_config_pad_and_crc(priv->fm_mac, true);
11156 + if (unlikely(_errno < 0))
11157 + goto _return_fm_mac_free;
11158 +
11159 + _errno = fm_mac_config_half_duplex(priv->fm_mac,
11160 + mac_dev->half_duplex);
11161 + if (unlikely(_errno < 0))
11162 + goto _return_fm_mac_free;
11163 + } else {
11164 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11165 + if (unlikely(_errno < 0))
11166 + goto _return_fm_mac_free;
11167 + }
11168 +
11169 + _errno = fm_mac_init(priv->fm_mac);
11170 + if (unlikely(_errno < 0))
11171 + goto _return_fm_mac_free;
11172 +
11173 +#ifndef CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN
11174 + /* For 1G MAC, disable by default the MIB counters overflow interrupt */
11175 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11176 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11177 + e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL, FALSE);
11178 + if (unlikely(_errno < 0))
11179 + goto _return_fm_mac_free;
11180 + }
11181 +#endif /* !CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN */
11182 +
11183 + /* For 10G MAC, disable Tx ECC exception */
11184 + if (macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) {
11185 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11186 + e_FM_MAC_EX_10G_1TX_ECC_ER, FALSE);
11187 + if (unlikely(_errno < 0))
11188 + goto _return_fm_mac_free;
11189 + }
11190 +
11191 + _errno = fm_mac_get_version(priv->fm_mac, &version);
11192 + if (unlikely(_errno < 0))
11193 + goto _return_fm_mac_free;
11194 +
11195 + dev_info(mac_dev->dev, "FMan %s version: 0x%08x\n",
11196 + ((macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11197 + "dTSEC" : "XGEC"), version);
11198 +
11199 + goto _return;
11200 +
11201 +
11202 +_return_fm_mac_free:
11203 + fm_mac_free(mac_dev->get_mac_handle(mac_dev));
11204 +
11205 +_return:
11206 + return _errno;
11207 +}
11208 +
11209 +static int __cold memac_init(struct mac_device *mac_dev)
11210 +{
11211 + int _errno;
11212 + struct mac_priv_s *priv;
11213 + t_FmMacParams param;
11214 +
11215 + priv = macdev_priv(mac_dev);
11216 +
11217 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11218 + mac_dev->dev, mac_dev->res->start, 0x2000);
11219 + param.enetMode = macdev2enetinterface(mac_dev);
11220 + memcpy(&param.addr, mac_dev->addr, sizeof(mac_dev->addr));
11221 + param.macId = mac_dev->cell_index;
11222 + param.h_Fm = (handle_t)mac_dev->fm;
11223 + param.mdioIrq = NO_IRQ;
11224 + param.f_Exception = mac_exception;
11225 + param.f_Event = mac_exception;
11226 + param.h_App = mac_dev;
11227 +
11228 + priv->fm_mac = fm_mac_config(&param);
11229 + if (unlikely(priv->fm_mac == NULL)) {
11230 + _errno = -EINVAL;
11231 + goto _return;
11232 + }
11233 +
11234 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11235 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11236 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11237 +
11238 + _errno = fm_mac_config_max_frame_length(priv->fm_mac, fm_get_max_frm());
11239 + if (unlikely(_errno < 0))
11240 + goto _return_fm_mac_free;
11241 +
11242 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11243 + if (unlikely(_errno < 0))
11244 + goto _return_fm_mac_free;
11245 +
11246 + _errno = fm_mac_init(priv->fm_mac);
11247 + if (unlikely(_errno < 0))
11248 + goto _return_fm_mac_free;
11249 +
11250 + dev_info(mac_dev->dev, "FMan MEMAC\n");
11251 +
11252 + goto _return;
11253 +
11254 +_return_fm_mac_free:
11255 + fm_mac_free(priv->fm_mac);
11256 +
11257 +_return:
11258 + return _errno;
11259 +}
11260 +
11261 +static int __cold start(struct mac_device *mac_dev)
11262 +{
11263 + int _errno;
11264 + struct phy_device *phy_dev = mac_dev->phy_dev;
11265 +
11266 + _errno = fm_mac_enable(mac_dev->get_mac_handle(mac_dev));
11267 +
11268 + if (!_errno && phy_dev)
11269 + phy_start(phy_dev);
11270 +
11271 + return _errno;
11272 +}
11273 +
11274 +static int __cold stop(struct mac_device *mac_dev)
11275 +{
11276 + if (mac_dev->phy_dev)
11277 + phy_stop(mac_dev->phy_dev);
11278 +
11279 + return fm_mac_disable(mac_dev->get_mac_handle(mac_dev));
11280 +}
11281 +
11282 +static int __cold set_multi(struct net_device *net_dev,
11283 + struct mac_device *mac_dev)
11284 +{
11285 + struct mac_priv_s *mac_priv;
11286 + struct mac_address *old_addr, *tmp;
11287 + struct netdev_hw_addr *ha;
11288 + int _errno;
11289 +
11290 + mac_priv = macdev_priv(mac_dev);
11291 +
11292 + /* Clear previous address list */
11293 + list_for_each_entry_safe(old_addr, tmp, &mac_dev->mc_addr_list, list) {
11294 + _errno = fm_mac_remove_hash_mac_addr(mac_priv->fm_mac,
11295 + (t_EnetAddr *)old_addr->addr);
11296 + if (_errno < 0)
11297 + return _errno;
11298 +
11299 + list_del(&old_addr->list);
11300 + kfree(old_addr);
11301 + }
11302 +
11303 + /* Add all the addresses from the new list */
11304 + netdev_for_each_mc_addr(ha, net_dev) {
11305 + _errno = fm_mac_add_hash_mac_addr(mac_priv->fm_mac,
11306 + (t_EnetAddr *)ha->addr);
11307 + if (_errno < 0)
11308 + return _errno;
11309 +
11310 + tmp = kmalloc(sizeof(struct mac_address), GFP_ATOMIC);
11311 + if (!tmp) {
11312 + dev_err(mac_dev->dev, "Out of memory\n");
11313 + return -ENOMEM;
11314 + }
11315 + memcpy(tmp->addr, ha->addr, ETH_ALEN);
11316 + list_add(&tmp->list, &mac_dev->mc_addr_list);
11317 + }
11318 + return 0;
11319 +}
11320 +
11321 +/* Avoid redundant calls to FMD, if the MAC driver already contains the desired
11322 + * active PAUSE settings. Otherwise, the new active settings should be reflected
11323 + * in FMan.
11324 + */
11325 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
11326 +{
11327 + struct fm_mac_dev *fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11328 + int _errno = 0;
11329 +
11330 + if (unlikely(rx != mac_dev->rx_pause_active)) {
11331 + _errno = fm_mac_set_rx_pause_frames(fm_mac_dev, rx);
11332 + if (likely(_errno == 0))
11333 + mac_dev->rx_pause_active = rx;
11334 + }
11335 +
11336 + if (unlikely(tx != mac_dev->tx_pause_active)) {
11337 + _errno = fm_mac_set_tx_pause_frames(fm_mac_dev, tx);
11338 + if (likely(_errno == 0))
11339 + mac_dev->tx_pause_active = tx;
11340 + }
11341 +
11342 + return _errno;
11343 +}
11344 +EXPORT_SYMBOL(set_mac_active_pause);
11345 +
11346 +/* Determine the MAC RX/TX PAUSE frames settings based on PHY
11347 + * autonegotiation or values set by eththool.
11348 + */
11349 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause)
11350 +{
11351 + struct phy_device *phy_dev = mac_dev->phy_dev;
11352 + u16 lcl_adv, rmt_adv;
11353 + u8 flowctrl;
11354 +
11355 + *rx_pause = *tx_pause = false;
11356 +
11357 + if (!phy_dev->duplex)
11358 + return;
11359 +
11360 + /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
11361 + * are those set by ethtool.
11362 + */
11363 + if (!mac_dev->autoneg_pause) {
11364 + *rx_pause = mac_dev->rx_pause_req;
11365 + *tx_pause = mac_dev->tx_pause_req;
11366 + return;
11367 + }
11368 +
11369 + /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
11370 + * settings depend on the result of the link negotiation.
11371 + */
11372 +
11373 + /* get local capabilities */
11374 + lcl_adv = 0;
11375 + if (phy_dev->advertising & ADVERTISED_Pause)
11376 + lcl_adv |= ADVERTISE_PAUSE_CAP;
11377 + if (phy_dev->advertising & ADVERTISED_Asym_Pause)
11378 + lcl_adv |= ADVERTISE_PAUSE_ASYM;
11379 +
11380 + /* get link partner capabilities */
11381 + rmt_adv = 0;
11382 + if (phy_dev->pause)
11383 + rmt_adv |= LPA_PAUSE_CAP;
11384 + if (phy_dev->asym_pause)
11385 + rmt_adv |= LPA_PAUSE_ASYM;
11386 +
11387 + /* Calculate TX/RX settings based on local and peer advertised
11388 + * symmetric/asymmetric PAUSE capabilities.
11389 + */
11390 + flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
11391 + if (flowctrl & FLOW_CTRL_RX)
11392 + *rx_pause = true;
11393 + if (flowctrl & FLOW_CTRL_TX)
11394 + *tx_pause = true;
11395 +}
11396 +EXPORT_SYMBOL(get_pause_cfg);
11397 +
11398 +static void adjust_link_void(struct net_device *net_dev)
11399 +{
11400 +}
11401 +
11402 +static void adjust_link(struct net_device *net_dev)
11403 +{
11404 + struct dpa_priv_s *priv = netdev_priv(net_dev);
11405 + struct mac_device *mac_dev = priv->mac_dev;
11406 + struct phy_device *phy_dev = mac_dev->phy_dev;
11407 + struct fm_mac_dev *fm_mac_dev;
11408 + bool rx_pause, tx_pause;
11409 + int _errno;
11410 +
11411 + fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11412 + fm_mac_adjust_link(fm_mac_dev, phy_dev->link, phy_dev->speed,
11413 + phy_dev->duplex);
11414 +
11415 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
11416 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
11417 + if (unlikely(_errno < 0))
11418 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
11419 +}
11420 +
11421 +/* Initializes driver's PHY state, and attaches to the PHY.
11422 + * Returns 0 on success.
11423 + */
11424 +static int dtsec_init_phy(struct net_device *net_dev,
11425 + struct mac_device *mac_dev)
11426 +{
11427 + struct phy_device *phy_dev;
11428 +
11429 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11430 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11431 + 0, mac_dev->phy_if);
11432 + else
11433 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11434 + &adjust_link, 0, mac_dev->phy_if);
11435 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11436 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11437 + mac_dev->phy_node ?
11438 + mac_dev->phy_node->full_name :
11439 + mac_dev->fixed_bus_id);
11440 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11441 + }
11442 +
11443 + /* Remove any features not supported by the controller */
11444 + phy_dev->supported &= mac_dev->if_support;
11445 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11446 + * as most of the PHY drivers do not enable them by default.
11447 + */
11448 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11449 + phy_dev->advertising = phy_dev->supported;
11450 +
11451 + mac_dev->phy_dev = phy_dev;
11452 +
11453 + return 0;
11454 +}
11455 +
11456 +static int xgmac_init_phy(struct net_device *net_dev,
11457 + struct mac_device *mac_dev)
11458 +{
11459 + struct phy_device *phy_dev;
11460 +
11461 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11462 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11463 + 0, mac_dev->phy_if);
11464 + else
11465 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11466 + &adjust_link_void, 0, mac_dev->phy_if);
11467 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11468 + netdev_err(net_dev, "Could not attach to PHY %s\n",
11469 + mac_dev->phy_node ?
11470 + mac_dev->phy_node->full_name :
11471 + mac_dev->fixed_bus_id);
11472 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11473 + }
11474 +
11475 + phy_dev->supported &= mac_dev->if_support;
11476 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11477 + * as most of the PHY drivers do not enable them by default.
11478 + */
11479 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11480 + phy_dev->advertising = phy_dev->supported;
11481 +
11482 + mac_dev->phy_dev = phy_dev;
11483 +
11484 + return 0;
11485 +}
11486 +
11487 +static int memac_init_phy(struct net_device *net_dev,
11488 + struct mac_device *mac_dev)
11489 +{
11490 + struct phy_device *phy_dev;
11491 +
11492 + if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) ||
11493 + (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500) ||
11494 + of_phy_is_fixed_link(mac_dev->phy_node)) {
11495 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11496 + &adjust_link_void, 0,
11497 + mac_dev->phy_if);
11498 + } else {
11499 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11500 + &adjust_link, 0, mac_dev->phy_if);
11501 + }
11502 +
11503 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11504 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11505 + mac_dev->phy_node ?
11506 + mac_dev->phy_node->full_name :
11507 + mac_dev->fixed_bus_id);
11508 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11509 + }
11510 +
11511 + /* Remove any features not supported by the controller */
11512 + phy_dev->supported &= mac_dev->if_support;
11513 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11514 + * as most of the PHY drivers do not enable them by default.
11515 + */
11516 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11517 + phy_dev->advertising = phy_dev->supported;
11518 +
11519 + mac_dev->phy_dev = phy_dev;
11520 +
11521 + return 0;
11522 +}
11523 +
11524 +static int __cold uninit(struct fm_mac_dev *fm_mac_dev)
11525 +{
11526 + int _errno, __errno;
11527 +
11528 + _errno = fm_mac_disable(fm_mac_dev);
11529 + __errno = fm_mac_free(fm_mac_dev);
11530 +
11531 + if (unlikely(__errno < 0))
11532 + _errno = __errno;
11533 +
11534 + return _errno;
11535 +}
11536 +
11537 +static struct fm_mac_dev *get_mac_handle(struct mac_device *mac_dev)
11538 +{
11539 + const struct mac_priv_s *priv;
11540 + priv = macdev_priv(mac_dev);
11541 + return priv->fm_mac;
11542 +}
11543 +
11544 +static int dtsec_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11545 +{
11546 + struct dtsec_regs *p_mm = (struct dtsec_regs *) h_mac->vaddr;
11547 + int i = 0, n = nn;
11548 +
11549 + FM_DMP_SUBTITLE(buf, n, "\n");
11550 +
11551 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - DTSEC-%d", h_mac->cell_index);
11552 +
11553 + FM_DMP_V32(buf, n, p_mm, tsec_id);
11554 + FM_DMP_V32(buf, n, p_mm, tsec_id2);
11555 + FM_DMP_V32(buf, n, p_mm, ievent);
11556 + FM_DMP_V32(buf, n, p_mm, imask);
11557 + FM_DMP_V32(buf, n, p_mm, ecntrl);
11558 + FM_DMP_V32(buf, n, p_mm, ptv);
11559 + FM_DMP_V32(buf, n, p_mm, tmr_ctrl);
11560 + FM_DMP_V32(buf, n, p_mm, tmr_pevent);
11561 + FM_DMP_V32(buf, n, p_mm, tmr_pemask);
11562 + FM_DMP_V32(buf, n, p_mm, tctrl);
11563 + FM_DMP_V32(buf, n, p_mm, rctrl);
11564 + FM_DMP_V32(buf, n, p_mm, maccfg1);
11565 + FM_DMP_V32(buf, n, p_mm, maccfg2);
11566 + FM_DMP_V32(buf, n, p_mm, ipgifg);
11567 + FM_DMP_V32(buf, n, p_mm, hafdup);
11568 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11569 +
11570 + FM_DMP_V32(buf, n, p_mm, macstnaddr1);
11571 + FM_DMP_V32(buf, n, p_mm, macstnaddr2);
11572 +
11573 + for (i = 0; i < 7; ++i) {
11574 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match1);
11575 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match2);
11576 + }
11577 +
11578 + FM_DMP_V32(buf, n, p_mm, car1);
11579 + FM_DMP_V32(buf, n, p_mm, car2);
11580 +
11581 + return n;
11582 +}
11583 +
11584 +static int xgmac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11585 +{
11586 + struct tgec_regs *p_mm = (struct tgec_regs *) h_mac->vaddr;
11587 + int n = nn;
11588 +
11589 + FM_DMP_SUBTITLE(buf, n, "\n");
11590 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - TGEC -%d", h_mac->cell_index);
11591 +
11592 + FM_DMP_V32(buf, n, p_mm, tgec_id);
11593 + FM_DMP_V32(buf, n, p_mm, command_config);
11594 + FM_DMP_V32(buf, n, p_mm, mac_addr_0);
11595 + FM_DMP_V32(buf, n, p_mm, mac_addr_1);
11596 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11597 + FM_DMP_V32(buf, n, p_mm, pause_quant);
11598 + FM_DMP_V32(buf, n, p_mm, rx_fifo_sections);
11599 + FM_DMP_V32(buf, n, p_mm, tx_fifo_sections);
11600 + FM_DMP_V32(buf, n, p_mm, rx_fifo_almost_f_e);
11601 + FM_DMP_V32(buf, n, p_mm, tx_fifo_almost_f_e);
11602 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11603 + FM_DMP_V32(buf, n, p_mm, mdio_cfg_status);
11604 + FM_DMP_V32(buf, n, p_mm, mdio_command);
11605 + FM_DMP_V32(buf, n, p_mm, mdio_data);
11606 + FM_DMP_V32(buf, n, p_mm, mdio_regaddr);
11607 + FM_DMP_V32(buf, n, p_mm, status);
11608 + FM_DMP_V32(buf, n, p_mm, tx_ipg_len);
11609 + FM_DMP_V32(buf, n, p_mm, mac_addr_2);
11610 + FM_DMP_V32(buf, n, p_mm, mac_addr_3);
11611 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_rd);
11612 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_wr);
11613 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_rd);
11614 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_wr);
11615 + FM_DMP_V32(buf, n, p_mm, imask);
11616 + FM_DMP_V32(buf, n, p_mm, ievent);
11617 +
11618 + return n;
11619 +}
11620 +
11621 +static int memac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11622 +{
11623 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11624 + int i = 0, n = nn;
11625 +
11626 + FM_DMP_SUBTITLE(buf, n, "\n");
11627 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d", h_mac->cell_index);
11628 +
11629 + FM_DMP_V32(buf, n, p_mm, command_config);
11630 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_l);
11631 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_u);
11632 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11633 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11634 + FM_DMP_V32(buf, n, p_mm, ievent);
11635 + FM_DMP_V32(buf, n, p_mm, tx_ipg_length);
11636 + FM_DMP_V32(buf, n, p_mm, imask);
11637 +
11638 + for (i = 0; i < 4; ++i)
11639 + FM_DMP_V32(buf, n, p_mm, pause_quanta[i]);
11640 +
11641 + for (i = 0; i < 4; ++i)
11642 + FM_DMP_V32(buf, n, p_mm, pause_thresh[i]);
11643 +
11644 + FM_DMP_V32(buf, n, p_mm, rx_pause_status);
11645 +
11646 + for (i = 0; i < MEMAC_NUM_OF_PADDRS; ++i) {
11647 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_l);
11648 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_u);
11649 + }
11650 +
11651 + FM_DMP_V32(buf, n, p_mm, lpwake_timer);
11652 + FM_DMP_V32(buf, n, p_mm, sleep_timer);
11653 + FM_DMP_V32(buf, n, p_mm, statn_config);
11654 + FM_DMP_V32(buf, n, p_mm, if_mode);
11655 + FM_DMP_V32(buf, n, p_mm, if_status);
11656 + FM_DMP_V32(buf, n, p_mm, hg_config);
11657 + FM_DMP_V32(buf, n, p_mm, hg_pause_quanta);
11658 + FM_DMP_V32(buf, n, p_mm, hg_pause_thresh);
11659 + FM_DMP_V32(buf, n, p_mm, hgrx_pause_status);
11660 + FM_DMP_V32(buf, n, p_mm, hg_fifos_status);
11661 + FM_DMP_V32(buf, n, p_mm, rhm);
11662 + FM_DMP_V32(buf, n, p_mm, thm);
11663 +
11664 + return n;
11665 +}
11666 +
11667 +static int memac_dump_regs_rx(struct mac_device *h_mac, char *buf, int nn)
11668 +{
11669 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11670 + int n = nn;
11671 +
11672 + FM_DMP_SUBTITLE(buf, n, "\n");
11673 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Rx stats", h_mac->cell_index);
11674 +
11675 + /* Rx Statistics Counter */
11676 + FM_DMP_V32(buf, n, p_mm, reoct_l);
11677 + FM_DMP_V32(buf, n, p_mm, reoct_u);
11678 + FM_DMP_V32(buf, n, p_mm, roct_l);
11679 + FM_DMP_V32(buf, n, p_mm, roct_u);
11680 + FM_DMP_V32(buf, n, p_mm, raln_l);
11681 + FM_DMP_V32(buf, n, p_mm, raln_u);
11682 + FM_DMP_V32(buf, n, p_mm, rxpf_l);
11683 + FM_DMP_V32(buf, n, p_mm, rxpf_u);
11684 + FM_DMP_V32(buf, n, p_mm, rfrm_l);
11685 + FM_DMP_V32(buf, n, p_mm, rfrm_u);
11686 + FM_DMP_V32(buf, n, p_mm, rfcs_l);
11687 + FM_DMP_V32(buf, n, p_mm, rfcs_u);
11688 + FM_DMP_V32(buf, n, p_mm, rvlan_l);
11689 + FM_DMP_V32(buf, n, p_mm, rvlan_u);
11690 + FM_DMP_V32(buf, n, p_mm, rerr_l);
11691 + FM_DMP_V32(buf, n, p_mm, rerr_u);
11692 + FM_DMP_V32(buf, n, p_mm, ruca_l);
11693 + FM_DMP_V32(buf, n, p_mm, ruca_u);
11694 + FM_DMP_V32(buf, n, p_mm, rmca_l);
11695 + FM_DMP_V32(buf, n, p_mm, rmca_u);
11696 + FM_DMP_V32(buf, n, p_mm, rbca_l);
11697 + FM_DMP_V32(buf, n, p_mm, rbca_u);
11698 + FM_DMP_V32(buf, n, p_mm, rdrp_l);
11699 + FM_DMP_V32(buf, n, p_mm, rdrp_u);
11700 + FM_DMP_V32(buf, n, p_mm, rpkt_l);
11701 + FM_DMP_V32(buf, n, p_mm, rpkt_u);
11702 + FM_DMP_V32(buf, n, p_mm, rund_l);
11703 + FM_DMP_V32(buf, n, p_mm, rund_u);
11704 + FM_DMP_V32(buf, n, p_mm, r64_l);
11705 + FM_DMP_V32(buf, n, p_mm, r64_u);
11706 + FM_DMP_V32(buf, n, p_mm, r127_l);
11707 + FM_DMP_V32(buf, n, p_mm, r127_u);
11708 + FM_DMP_V32(buf, n, p_mm, r255_l);
11709 + FM_DMP_V32(buf, n, p_mm, r255_u);
11710 + FM_DMP_V32(buf, n, p_mm, r511_l);
11711 + FM_DMP_V32(buf, n, p_mm, r511_u);
11712 + FM_DMP_V32(buf, n, p_mm, r1023_l);
11713 + FM_DMP_V32(buf, n, p_mm, r1023_u);
11714 + FM_DMP_V32(buf, n, p_mm, r1518_l);
11715 + FM_DMP_V32(buf, n, p_mm, r1518_u);
11716 + FM_DMP_V32(buf, n, p_mm, r1519x_l);
11717 + FM_DMP_V32(buf, n, p_mm, r1519x_u);
11718 + FM_DMP_V32(buf, n, p_mm, rovr_l);
11719 + FM_DMP_V32(buf, n, p_mm, rovr_u);
11720 + FM_DMP_V32(buf, n, p_mm, rjbr_l);
11721 + FM_DMP_V32(buf, n, p_mm, rjbr_u);
11722 + FM_DMP_V32(buf, n, p_mm, rfrg_l);
11723 + FM_DMP_V32(buf, n, p_mm, rfrg_u);
11724 + FM_DMP_V32(buf, n, p_mm, rcnp_l);
11725 + FM_DMP_V32(buf, n, p_mm, rcnp_u);
11726 + FM_DMP_V32(buf, n, p_mm, rdrntp_l);
11727 + FM_DMP_V32(buf, n, p_mm, rdrntp_u);
11728 +
11729 + return n;
11730 +}
11731 +
11732 +static int memac_dump_regs_tx(struct mac_device *h_mac, char *buf, int nn)
11733 +{
11734 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11735 + int n = nn;
11736 +
11737 + FM_DMP_SUBTITLE(buf, n, "\n");
11738 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Tx stats", h_mac->cell_index);
11739 +
11740 +
11741 + /* Tx Statistics Counter */
11742 + FM_DMP_V32(buf, n, p_mm, teoct_l);
11743 + FM_DMP_V32(buf, n, p_mm, teoct_u);
11744 + FM_DMP_V32(buf, n, p_mm, toct_l);
11745 + FM_DMP_V32(buf, n, p_mm, toct_u);
11746 + FM_DMP_V32(buf, n, p_mm, txpf_l);
11747 + FM_DMP_V32(buf, n, p_mm, txpf_u);
11748 + FM_DMP_V32(buf, n, p_mm, tfrm_l);
11749 + FM_DMP_V32(buf, n, p_mm, tfrm_u);
11750 + FM_DMP_V32(buf, n, p_mm, tfcs_l);
11751 + FM_DMP_V32(buf, n, p_mm, tfcs_u);
11752 + FM_DMP_V32(buf, n, p_mm, tvlan_l);
11753 + FM_DMP_V32(buf, n, p_mm, tvlan_u);
11754 + FM_DMP_V32(buf, n, p_mm, terr_l);
11755 + FM_DMP_V32(buf, n, p_mm, terr_u);
11756 + FM_DMP_V32(buf, n, p_mm, tuca_l);
11757 + FM_DMP_V32(buf, n, p_mm, tuca_u);
11758 + FM_DMP_V32(buf, n, p_mm, tmca_l);
11759 + FM_DMP_V32(buf, n, p_mm, tmca_u);
11760 + FM_DMP_V32(buf, n, p_mm, tbca_l);
11761 + FM_DMP_V32(buf, n, p_mm, tbca_u);
11762 + FM_DMP_V32(buf, n, p_mm, tpkt_l);
11763 + FM_DMP_V32(buf, n, p_mm, tpkt_u);
11764 + FM_DMP_V32(buf, n, p_mm, tund_l);
11765 + FM_DMP_V32(buf, n, p_mm, tund_u);
11766 + FM_DMP_V32(buf, n, p_mm, t64_l);
11767 + FM_DMP_V32(buf, n, p_mm, t64_u);
11768 + FM_DMP_V32(buf, n, p_mm, t127_l);
11769 + FM_DMP_V32(buf, n, p_mm, t127_u);
11770 + FM_DMP_V32(buf, n, p_mm, t255_l);
11771 + FM_DMP_V32(buf, n, p_mm, t255_u);
11772 + FM_DMP_V32(buf, n, p_mm, t511_l);
11773 + FM_DMP_V32(buf, n, p_mm, t511_u);
11774 + FM_DMP_V32(buf, n, p_mm, t1023_l);
11775 + FM_DMP_V32(buf, n, p_mm, t1023_u);
11776 + FM_DMP_V32(buf, n, p_mm, t1518_l);
11777 + FM_DMP_V32(buf, n, p_mm, t1518_u);
11778 + FM_DMP_V32(buf, n, p_mm, t1519x_l);
11779 + FM_DMP_V32(buf, n, p_mm, t1519x_u);
11780 + FM_DMP_V32(buf, n, p_mm, tcnp_l);
11781 + FM_DMP_V32(buf, n, p_mm, tcnp_u);
11782 +
11783 + return n;
11784 +}
11785 +
11786 +int fm_mac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11787 +{
11788 + int n = nn;
11789 +
11790 + n = h_mac->dump_mac_regs(h_mac, buf, n);
11791 +
11792 + return n;
11793 +}
11794 +EXPORT_SYMBOL(fm_mac_dump_regs);
11795 +
11796 +int fm_mac_dump_rx_stats(struct mac_device *h_mac, char *buf, int nn)
11797 +{
11798 + int n = nn;
11799 +
11800 + if(h_mac->dump_mac_rx_stats)
11801 + n = h_mac->dump_mac_rx_stats(h_mac, buf, n);
11802 +
11803 + return n;
11804 +}
11805 +EXPORT_SYMBOL(fm_mac_dump_rx_stats);
11806 +
11807 +int fm_mac_dump_tx_stats(struct mac_device *h_mac, char *buf, int nn)
11808 +{
11809 + int n = nn;
11810 +
11811 + if(h_mac->dump_mac_tx_stats)
11812 + n = h_mac->dump_mac_tx_stats(h_mac, buf, n);
11813 +
11814 + return n;
11815 +}
11816 +EXPORT_SYMBOL(fm_mac_dump_tx_stats);
11817 +
11818 +static void __cold setup_dtsec(struct mac_device *mac_dev)
11819 +{
11820 + mac_dev->init_phy = dtsec_init_phy;
11821 + mac_dev->init = init;
11822 + mac_dev->start = start;
11823 + mac_dev->stop = stop;
11824 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11825 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11826 + mac_dev->set_multi = set_multi;
11827 + mac_dev->uninit = uninit;
11828 + mac_dev->ptp_enable = fm_mac_enable_1588_time_stamp;
11829 + mac_dev->ptp_disable = fm_mac_disable_1588_time_stamp;
11830 + mac_dev->get_mac_handle = get_mac_handle;
11831 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11832 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11833 + mac_dev->fm_rtc_enable = fm_rtc_enable;
11834 + mac_dev->fm_rtc_disable = fm_rtc_disable;
11835 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
11836 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
11837 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
11838 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
11839 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
11840 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
11841 + mac_dev->set_wol = fm_mac_set_wol;
11842 + mac_dev->dump_mac_regs = dtsec_dump_regs;
11843 +}
11844 +
11845 +static void __cold setup_xgmac(struct mac_device *mac_dev)
11846 +{
11847 + mac_dev->init_phy = xgmac_init_phy;
11848 + mac_dev->init = init;
11849 + mac_dev->start = start;
11850 + mac_dev->stop = stop;
11851 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11852 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11853 + mac_dev->set_multi = set_multi;
11854 + mac_dev->uninit = uninit;
11855 + mac_dev->get_mac_handle = get_mac_handle;
11856 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11857 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11858 + mac_dev->set_wol = fm_mac_set_wol;
11859 + mac_dev->dump_mac_regs = xgmac_dump_regs;
11860 +}
11861 +
11862 +static void __cold setup_memac(struct mac_device *mac_dev)
11863 +{
11864 + mac_dev->init_phy = memac_init_phy;
11865 + mac_dev->init = memac_init;
11866 + mac_dev->start = start;
11867 + mac_dev->stop = stop;
11868 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11869 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11870 + mac_dev->set_multi = set_multi;
11871 + mac_dev->uninit = uninit;
11872 + mac_dev->get_mac_handle = get_mac_handle;
11873 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11874 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11875 + mac_dev->fm_rtc_enable = fm_rtc_enable;
11876 + mac_dev->fm_rtc_disable = fm_rtc_disable;
11877 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
11878 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
11879 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
11880 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
11881 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
11882 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
11883 + mac_dev->set_wol = fm_mac_set_wol;
11884 + mac_dev->dump_mac_regs = memac_dump_regs;
11885 + mac_dev->dump_mac_rx_stats = memac_dump_regs_rx;
11886 + mac_dev->dump_mac_tx_stats = memac_dump_regs_tx;
11887 +}
11888 +
11889 +void (*const mac_setup[])(struct mac_device *mac_dev) = {
11890 + [DTSEC] = setup_dtsec,
11891 + [XGMAC] = setup_xgmac,
11892 + [MEMAC] = setup_memac
11893 +};
11894 --- /dev/null
11895 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
11896 @@ -0,0 +1,489 @@
11897 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
11898 + *
11899 + * Redistribution and use in source and binary forms, with or without
11900 + * modification, are permitted provided that the following conditions are met:
11901 + * * Redistributions of source code must retain the above copyright
11902 + * notice, this list of conditions and the following disclaimer.
11903 + * * Redistributions in binary form must reproduce the above copyright
11904 + * notice, this list of conditions and the following disclaimer in the
11905 + * documentation and/or other materials provided with the distribution.
11906 + * * Neither the name of Freescale Semiconductor nor the
11907 + * names of its contributors may be used to endorse or promote products
11908 + * derived from this software without specific prior written permission.
11909 + *
11910 + *
11911 + * ALTERNATIVELY, this software may be distributed under the terms of the
11912 + * GNU General Public License ("GPL") as published by the Free Software
11913 + * Foundation, either version 2 of that License or (at your option) any
11914 + * later version.
11915 + *
11916 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11917 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11918 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11919 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11920 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11921 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11922 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11923 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11924 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11925 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11926 + */
11927 +
11928 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
11929 +#define pr_fmt(fmt) \
11930 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
11931 + KBUILD_BASENAME".c", __LINE__, __func__
11932 +#else
11933 +#define pr_fmt(fmt) \
11934 + KBUILD_MODNAME ": " fmt
11935 +#endif
11936 +
11937 +#include <linux/init.h>
11938 +#include <linux/module.h>
11939 +#include <linux/of_address.h>
11940 +#include <linux/of_platform.h>
11941 +#include <linux/of_net.h>
11942 +#include <linux/of_mdio.h>
11943 +#include <linux/phy_fixed.h>
11944 +#include <linux/device.h>
11945 +#include <linux/phy.h>
11946 +#include <linux/io.h>
11947 +
11948 +#include "lnxwrp_fm_ext.h"
11949 +
11950 +#include "mac.h"
11951 +
11952 +#define DTSEC_SUPPORTED \
11953 + (SUPPORTED_10baseT_Half \
11954 + | SUPPORTED_10baseT_Full \
11955 + | SUPPORTED_100baseT_Half \
11956 + | SUPPORTED_100baseT_Full \
11957 + | SUPPORTED_Autoneg \
11958 + | SUPPORTED_Pause \
11959 + | SUPPORTED_Asym_Pause \
11960 + | SUPPORTED_MII)
11961 +
11962 +static const char phy_str[][11] = {
11963 + [PHY_INTERFACE_MODE_MII] = "mii",
11964 + [PHY_INTERFACE_MODE_GMII] = "gmii",
11965 + [PHY_INTERFACE_MODE_SGMII] = "sgmii",
11966 + [PHY_INTERFACE_MODE_QSGMII] = "qsgmii",
11967 + [PHY_INTERFACE_MODE_TBI] = "tbi",
11968 + [PHY_INTERFACE_MODE_RMII] = "rmii",
11969 + [PHY_INTERFACE_MODE_RGMII] = "rgmii",
11970 + [PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id",
11971 + [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
11972 + [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
11973 + [PHY_INTERFACE_MODE_RTBI] = "rtbi",
11974 + [PHY_INTERFACE_MODE_XGMII] = "xgmii",
11975 + [PHY_INTERFACE_MODE_SGMII_2500] = "sgmii-2500",
11976 +};
11977 +
11978 +static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str)
11979 +{
11980 + int i;
11981 +
11982 + for (i = 0; i < ARRAY_SIZE(phy_str); i++)
11983 + if (strcmp(str, phy_str[i]) == 0)
11984 + return (phy_interface_t)i;
11985 +
11986 + return PHY_INTERFACE_MODE_MII;
11987 +}
11988 +
11989 +static const uint16_t phy2speed[] = {
11990 + [PHY_INTERFACE_MODE_MII] = SPEED_100,
11991 + [PHY_INTERFACE_MODE_GMII] = SPEED_1000,
11992 + [PHY_INTERFACE_MODE_SGMII] = SPEED_1000,
11993 + [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000,
11994 + [PHY_INTERFACE_MODE_TBI] = SPEED_1000,
11995 + [PHY_INTERFACE_MODE_RMII] = SPEED_100,
11996 + [PHY_INTERFACE_MODE_RGMII] = SPEED_1000,
11997 + [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000,
11998 + [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
11999 + [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
12000 + [PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
12001 + [PHY_INTERFACE_MODE_XGMII] = SPEED_10000,
12002 + [PHY_INTERFACE_MODE_SGMII_2500] = SPEED_2500,
12003 +};
12004 +
12005 +static struct mac_device * __cold
12006 +alloc_macdev(struct device *dev, size_t sizeof_priv,
12007 + void (*setup)(struct mac_device *mac_dev))
12008 +{
12009 + struct mac_device *mac_dev;
12010 +
12011 + mac_dev = devm_kzalloc(dev, sizeof(*mac_dev) + sizeof_priv, GFP_KERNEL);
12012 + if (unlikely(mac_dev == NULL))
12013 + mac_dev = ERR_PTR(-ENOMEM);
12014 + else {
12015 + mac_dev->dev = dev;
12016 + dev_set_drvdata(dev, mac_dev);
12017 + setup(mac_dev);
12018 + }
12019 +
12020 + return mac_dev;
12021 +}
12022 +
12023 +static int __cold free_macdev(struct mac_device *mac_dev)
12024 +{
12025 + dev_set_drvdata(mac_dev->dev, NULL);
12026 +
12027 + return mac_dev->uninit(mac_dev->get_mac_handle(mac_dev));
12028 +}
12029 +
12030 +static const struct of_device_id mac_match[] = {
12031 + [DTSEC] = {
12032 + .compatible = "fsl,fman-1g-mac"
12033 + },
12034 + [XGMAC] = {
12035 + .compatible = "fsl,fman-10g-mac"
12036 + },
12037 + [MEMAC] = {
12038 + .compatible = "fsl,fman-memac"
12039 + },
12040 + {}
12041 +};
12042 +MODULE_DEVICE_TABLE(of, mac_match);
12043 +
12044 +static int __cold mac_probe(struct platform_device *_of_dev)
12045 +{
12046 + int _errno, i;
12047 + struct device *dev;
12048 + struct device_node *mac_node, *dev_node;
12049 + struct mac_device *mac_dev;
12050 + struct platform_device *of_dev;
12051 + struct resource res;
12052 + const uint8_t *mac_addr;
12053 + const char *char_prop;
12054 + int nph;
12055 + u32 cell_index;
12056 + const struct of_device_id *match;
12057 +
12058 + dev = &_of_dev->dev;
12059 + mac_node = dev->of_node;
12060 +
12061 + match = of_match_device(mac_match, dev);
12062 + if (!match)
12063 + return -EINVAL;
12064 +
12065 + for (i = 0; i < ARRAY_SIZE(mac_match) - 1 && match != mac_match + i;
12066 + i++)
12067 + ;
12068 + BUG_ON(i >= ARRAY_SIZE(mac_match) - 1);
12069 +
12070 + mac_dev = alloc_macdev(dev, mac_sizeof_priv[i], mac_setup[i]);
12071 + if (IS_ERR(mac_dev)) {
12072 + _errno = PTR_ERR(mac_dev);
12073 + dev_err(dev, "alloc_macdev() = %d\n", _errno);
12074 + goto _return;
12075 + }
12076 +
12077 + INIT_LIST_HEAD(&mac_dev->mc_addr_list);
12078 +
12079 + /* Get the FM node */
12080 + dev_node = of_get_parent(mac_node);
12081 + if (unlikely(dev_node == NULL)) {
12082 + dev_err(dev, "of_get_parent(%s) failed\n",
12083 + mac_node->full_name);
12084 + _errno = -EINVAL;
12085 + goto _return_dev_set_drvdata;
12086 + }
12087 +
12088 + of_dev = of_find_device_by_node(dev_node);
12089 + if (unlikely(of_dev == NULL)) {
12090 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12091 + dev_node->full_name);
12092 + _errno = -EINVAL;
12093 + goto _return_of_node_put;
12094 + }
12095 +
12096 + mac_dev->fm_dev = fm_bind(&of_dev->dev);
12097 + if (unlikely(mac_dev->fm_dev == NULL)) {
12098 + dev_err(dev, "fm_bind(%s) failed\n", dev_node->full_name);
12099 + _errno = -ENODEV;
12100 + goto _return_of_node_put;
12101 + }
12102 +
12103 + mac_dev->fm = (void *)fm_get_handle(mac_dev->fm_dev);
12104 + of_node_put(dev_node);
12105 +
12106 + /* Get the address of the memory mapped registers */
12107 + _errno = of_address_to_resource(mac_node, 0, &res);
12108 + if (unlikely(_errno < 0)) {
12109 + dev_err(dev, "of_address_to_resource(%s) = %d\n",
12110 + mac_node->full_name, _errno);
12111 + goto _return_dev_set_drvdata;
12112 + }
12113 +
12114 + mac_dev->res = __devm_request_region(
12115 + dev,
12116 + fm_get_mem_region(mac_dev->fm_dev),
12117 + res.start, res.end + 1 - res.start, "mac");
12118 + if (unlikely(mac_dev->res == NULL)) {
12119 + dev_err(dev, "__devm_request_mem_region(mac) failed\n");
12120 + _errno = -EBUSY;
12121 + goto _return_dev_set_drvdata;
12122 + }
12123 +
12124 + mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start,
12125 + mac_dev->res->end + 1
12126 + - mac_dev->res->start);
12127 + if (unlikely(mac_dev->vaddr == NULL)) {
12128 + dev_err(dev, "devm_ioremap() failed\n");
12129 + _errno = -EIO;
12130 + goto _return_dev_set_drvdata;
12131 + }
12132 +
12133 +#define TBIPA_OFFSET 0x1c
12134 +#define TBIPA_DEFAULT_ADDR 5 /* override if used as external PHY addr. */
12135 + mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0);
12136 + if (mac_dev->tbi_node) {
12137 + u32 tbiaddr = TBIPA_DEFAULT_ADDR;
12138 + const __be32 *tbi_reg;
12139 + void __iomem *addr;
12140 +
12141 + tbi_reg = of_get_property(mac_dev->tbi_node, "reg", NULL);
12142 + if (tbi_reg)
12143 + tbiaddr = be32_to_cpup(tbi_reg);
12144 + addr = mac_dev->vaddr + TBIPA_OFFSET;
12145 + /* TODO: out_be32 does not exist on ARM */
12146 + out_be32(addr, tbiaddr);
12147 + }
12148 +
12149 + if (!of_device_is_available(mac_node)) {
12150 + devm_iounmap(dev, mac_dev->vaddr);
12151 + __devm_release_region(dev, fm_get_mem_region(mac_dev->fm_dev),
12152 + res.start, res.end + 1 - res.start);
12153 + fm_unbind(mac_dev->fm_dev);
12154 + devm_kfree(dev, mac_dev);
12155 + dev_set_drvdata(dev, NULL);
12156 + return -ENODEV;
12157 + }
12158 +
12159 + /* Get the cell-index */
12160 + _errno = of_property_read_u32(mac_node, "cell-index", &cell_index);
12161 + if (unlikely(_errno)) {
12162 + dev_err(dev, "Cannot read cell-index of mac node %s from device tree\n",
12163 + mac_node->full_name);
12164 + goto _return_dev_set_drvdata;
12165 + }
12166 + mac_dev->cell_index = (uint8_t)cell_index;
12167 + if (mac_dev->cell_index >= 8)
12168 + mac_dev->cell_index -= 8;
12169 +
12170 + /* Get the MAC address */
12171 + mac_addr = of_get_mac_address(mac_node);
12172 + if (unlikely(mac_addr == NULL)) {
12173 + dev_err(dev, "of_get_mac_address(%s) failed\n",
12174 + mac_node->full_name);
12175 + _errno = -EINVAL;
12176 + goto _return_dev_set_drvdata;
12177 + }
12178 + memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
12179 +
12180 + /* Verify the number of port handles */
12181 + nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
12182 + if (unlikely(nph < 0)) {
12183 + dev_err(dev, "Cannot read port handles of mac node %s from device tree\n",
12184 + mac_node->full_name);
12185 + _errno = nph;
12186 + goto _return_dev_set_drvdata;
12187 + }
12188 +
12189 + if (nph != ARRAY_SIZE(mac_dev->port_dev)) {
12190 + dev_err(dev, "Not supported number of port handles of mac node %s from device tree\n",
12191 + mac_node->full_name);
12192 + _errno = -EINVAL;
12193 + goto _return_dev_set_drvdata;
12194 + }
12195 +
12196 + for_each_port_device(i, mac_dev->port_dev) {
12197 + dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
12198 + if (unlikely(dev_node == NULL)) {
12199 + dev_err(dev, "Cannot find port node referenced by mac node %s from device tree\n",
12200 + mac_node->full_name);
12201 + _errno = -EINVAL;
12202 + goto _return_of_node_put;
12203 + }
12204 +
12205 + of_dev = of_find_device_by_node(dev_node);
12206 + if (unlikely(of_dev == NULL)) {
12207 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12208 + dev_node->full_name);
12209 + _errno = -EINVAL;
12210 + goto _return_of_node_put;
12211 + }
12212 +
12213 + mac_dev->port_dev[i] = fm_port_bind(&of_dev->dev);
12214 + if (unlikely(mac_dev->port_dev[i] == NULL)) {
12215 + dev_err(dev, "dev_get_drvdata(%s) failed\n",
12216 + dev_node->full_name);
12217 + _errno = -EINVAL;
12218 + goto _return_of_node_put;
12219 + }
12220 + of_node_put(dev_node);
12221 + }
12222 +
12223 + /* Get the PHY connection type */
12224 + _errno = of_property_read_string(mac_node, "phy-connection-type",
12225 + &char_prop);
12226 + if (unlikely(_errno)) {
12227 + dev_warn(dev,
12228 + "Cannot read PHY connection type of mac node %s from device tree. Defaulting to MII\n",
12229 + mac_node->full_name);
12230 + mac_dev->phy_if = PHY_INTERFACE_MODE_MII;
12231 + } else
12232 + mac_dev->phy_if = str2phy(char_prop);
12233 +
12234 + mac_dev->link = false;
12235 + mac_dev->half_duplex = false;
12236 + mac_dev->speed = phy2speed[mac_dev->phy_if];
12237 + mac_dev->max_speed = mac_dev->speed;
12238 + mac_dev->if_support = DTSEC_SUPPORTED;
12239 + /* We don't support half-duplex in SGMII mode */
12240 + if (strstr(char_prop, "sgmii") || strstr(char_prop, "qsgmii") ||
12241 + strstr(char_prop, "sgmii-2500"))
12242 + mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
12243 + SUPPORTED_100baseT_Half);
12244 +
12245 + /* Gigabit support (no half-duplex) */
12246 + if (mac_dev->max_speed == SPEED_1000 ||
12247 + mac_dev->max_speed == SPEED_2500)
12248 + mac_dev->if_support |= SUPPORTED_1000baseT_Full;
12249 +
12250 + /* The 10G interface only supports one mode */
12251 + if (strstr(char_prop, "xgmii"))
12252 + mac_dev->if_support = SUPPORTED_10000baseT_Full;
12253 +
12254 + /* Get the rest of the PHY information */
12255 + mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
12256 + if (!mac_dev->phy_node) {
12257 + struct phy_device *phy;
12258 +
12259 + if (!of_phy_is_fixed_link(mac_node)) {
12260 + dev_err(dev, "Wrong PHY information of mac node %s\n",
12261 + mac_node->full_name);
12262 + goto _return_dev_set_drvdata;
12263 + }
12264 +
12265 + _errno = of_phy_register_fixed_link(mac_node);
12266 + if (_errno)
12267 + goto _return_dev_set_drvdata;
12268 +
12269 + mac_dev->fixed_link = devm_kzalloc(mac_dev->dev,
12270 + sizeof(*mac_dev->fixed_link),
12271 + GFP_KERNEL);
12272 + if (!mac_dev->fixed_link)
12273 + goto _return_dev_set_drvdata;
12274 +
12275 + mac_dev->phy_node = of_node_get(mac_node);
12276 + phy = of_phy_find_device(mac_dev->phy_node);
12277 + if (!phy)
12278 + goto _return_dev_set_drvdata;
12279 +
12280 + mac_dev->fixed_link->link = phy->link;
12281 + mac_dev->fixed_link->speed = phy->speed;
12282 + mac_dev->fixed_link->duplex = phy->duplex;
12283 + mac_dev->fixed_link->pause = phy->pause;
12284 + mac_dev->fixed_link->asym_pause = phy->asym_pause;
12285 + }
12286 +
12287 + _errno = mac_dev->init(mac_dev);
12288 + if (unlikely(_errno < 0)) {
12289 + dev_err(dev, "mac_dev->init() = %d\n", _errno);
12290 + goto _return_dev_set_drvdata;
12291 + }
12292 +
12293 + /* pause frame autonegotiation enabled*/
12294 + mac_dev->autoneg_pause = true;
12295 +
12296 + /* by intializing the values to false, force FMD to enable PAUSE frames
12297 + * on RX and TX
12298 + */
12299 + mac_dev->rx_pause_req = mac_dev->tx_pause_req = true;
12300 + mac_dev->rx_pause_active = mac_dev->tx_pause_active = false;
12301 + _errno = set_mac_active_pause(mac_dev, true, true);
12302 + if (unlikely(_errno < 0))
12303 + dev_err(dev, "set_mac_active_pause() = %d\n", _errno);
12304 +
12305 + dev_info(dev,
12306 + "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
12307 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
12308 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
12309 +
12310 + goto _return;
12311 +
12312 +_return_of_node_put:
12313 + of_node_put(dev_node);
12314 +_return_dev_set_drvdata:
12315 + dev_set_drvdata(dev, NULL);
12316 +_return:
12317 + return _errno;
12318 +}
12319 +
12320 +static int __cold mac_remove(struct platform_device *of_dev)
12321 +{
12322 + int i, _errno;
12323 + struct device *dev;
12324 + struct mac_device *mac_dev;
12325 +
12326 + dev = &of_dev->dev;
12327 + mac_dev = (struct mac_device *)dev_get_drvdata(dev);
12328 +
12329 + for_each_port_device(i, mac_dev->port_dev)
12330 + fm_port_unbind(mac_dev->port_dev[i]);
12331 +
12332 + fm_unbind(mac_dev->fm_dev);
12333 +
12334 + _errno = free_macdev(mac_dev);
12335 +
12336 + return _errno;
12337 +}
12338 +
12339 +static struct platform_driver mac_driver = {
12340 + .driver = {
12341 + .name = KBUILD_MODNAME,
12342 + .of_match_table = mac_match,
12343 + .owner = THIS_MODULE,
12344 + },
12345 + .probe = mac_probe,
12346 + .remove = mac_remove
12347 +};
12348 +
12349 +static int __init __cold mac_load(void)
12350 +{
12351 + int _errno;
12352 +
12353 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12354 + KBUILD_BASENAME".c", __func__);
12355 +
12356 + pr_info(KBUILD_MODNAME ": %s\n", mac_driver_description);
12357 +
12358 + _errno = platform_driver_register(&mac_driver);
12359 + if (unlikely(_errno < 0)) {
12360 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): platform_driver_register() = %d\n",
12361 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
12362 + goto _return;
12363 + }
12364 +
12365 + goto _return;
12366 +
12367 +_return:
12368 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12369 + KBUILD_BASENAME".c", __func__);
12370 +
12371 + return _errno;
12372 +}
12373 +module_init(mac_load);
12374 +
12375 +static void __exit __cold mac_unload(void)
12376 +{
12377 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12378 + KBUILD_BASENAME".c", __func__);
12379 +
12380 + platform_driver_unregister(&mac_driver);
12381 +
12382 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12383 + KBUILD_BASENAME".c", __func__);
12384 +}
12385 +module_exit(mac_unload);
12386 --- /dev/null
12387 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h
12388 @@ -0,0 +1,135 @@
12389 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
12390 + *
12391 + * Redistribution and use in source and binary forms, with or without
12392 + * modification, are permitted provided that the following conditions are met:
12393 + * * Redistributions of source code must retain the above copyright
12394 + * notice, this list of conditions and the following disclaimer.
12395 + * * Redistributions in binary form must reproduce the above copyright
12396 + * notice, this list of conditions and the following disclaimer in the
12397 + * documentation and/or other materials provided with the distribution.
12398 + * * Neither the name of Freescale Semiconductor nor the
12399 + * names of its contributors may be used to endorse or promote products
12400 + * derived from this software without specific prior written permission.
12401 + *
12402 + *
12403 + * ALTERNATIVELY, this software may be distributed under the terms of the
12404 + * GNU General Public License ("GPL") as published by the Free Software
12405 + * Foundation, either version 2 of that License or (at your option) any
12406 + * later version.
12407 + *
12408 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12409 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12410 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12411 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12412 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12413 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12414 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12415 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12416 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12417 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12418 + */
12419 +
12420 +#ifndef __MAC_H
12421 +#define __MAC_H
12422 +
12423 +#include <linux/device.h> /* struct device, BUS_ID_SIZE */
12424 +#include <linux/if_ether.h> /* ETH_ALEN */
12425 +#include <linux/phy.h> /* phy_interface_t, struct phy_device */
12426 +#include <linux/list.h>
12427 +
12428 +#include "lnxwrp_fsl_fman.h" /* struct port_device */
12429 +
12430 +enum {DTSEC, XGMAC, MEMAC};
12431 +
12432 +struct mac_device {
12433 + struct device *dev;
12434 + void *priv;
12435 + uint8_t cell_index;
12436 + struct resource *res;
12437 + void __iomem *vaddr;
12438 + uint8_t addr[ETH_ALEN];
12439 + bool promisc;
12440 +
12441 + struct fm *fm_dev;
12442 + struct fm_port *port_dev[2];
12443 +
12444 + phy_interface_t phy_if;
12445 + u32 if_support;
12446 + bool link;
12447 + bool half_duplex;
12448 + uint16_t speed;
12449 + uint16_t max_speed;
12450 + struct device_node *phy_node;
12451 + char fixed_bus_id[MII_BUS_ID_SIZE + 3];
12452 + struct device_node *tbi_node;
12453 + struct phy_device *phy_dev;
12454 + void *fm;
12455 + /* List of multicast addresses */
12456 + struct list_head mc_addr_list;
12457 + struct fixed_phy_status *fixed_link;
12458 +
12459 + bool autoneg_pause;
12460 + bool rx_pause_req;
12461 + bool tx_pause_req;
12462 + bool rx_pause_active;
12463 + bool tx_pause_active;
12464 +
12465 + struct fm_mac_dev *(*get_mac_handle)(struct mac_device *mac_dev);
12466 + int (*init_phy)(struct net_device *net_dev, struct mac_device *mac_dev);
12467 + int (*init)(struct mac_device *mac_dev);
12468 + int (*start)(struct mac_device *mac_dev);
12469 + int (*stop)(struct mac_device *mac_dev);
12470 + int (*set_promisc)(struct fm_mac_dev *fm_mac_dev, bool enable);
12471 + int (*change_addr)(struct fm_mac_dev *fm_mac_dev, uint8_t *addr);
12472 + int (*set_multi)(struct net_device *net_dev,
12473 + struct mac_device *mac_dev);
12474 + int (*uninit)(struct fm_mac_dev *fm_mac_dev);
12475 + int (*ptp_enable)(struct fm_mac_dev *fm_mac_dev);
12476 + int (*ptp_disable)(struct fm_mac_dev *fm_mac_dev);
12477 + int (*set_rx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12478 + int (*set_tx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12479 + int (*fm_rtc_enable)(struct fm *fm_dev);
12480 + int (*fm_rtc_disable)(struct fm *fm_dev);
12481 + int (*fm_rtc_get_cnt)(struct fm *fm_dev, uint64_t *ts);
12482 + int (*fm_rtc_set_cnt)(struct fm *fm_dev, uint64_t ts);
12483 + int (*fm_rtc_get_drift)(struct fm *fm_dev, uint32_t *drift);
12484 + int (*fm_rtc_set_drift)(struct fm *fm_dev, uint32_t drift);
12485 + int (*fm_rtc_set_alarm)(struct fm *fm_dev, uint32_t id, uint64_t time);
12486 + int (*fm_rtc_set_fiper)(struct fm *fm_dev, uint32_t id,
12487 + uint64_t fiper);
12488 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
12489 + int (*fm_rtc_enable_interrupt)(struct fm *fm_dev, uint32_t events);
12490 + int (*fm_rtc_disable_interrupt)(struct fm *fm_dev, uint32_t events);
12491 +#endif
12492 + int (*set_wol)(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
12493 + bool en);
12494 + int (*dump_mac_regs)(struct mac_device *h_mac, char *buf, int nn);
12495 + int (*dump_mac_rx_stats)(struct mac_device *h_mac, char *buf, int nn);
12496 + int (*dump_mac_tx_stats)(struct mac_device *h_mac, char *buf, int nn);
12497 +};
12498 +
12499 +struct mac_address {
12500 + uint8_t addr[ETH_ALEN];
12501 + struct list_head list;
12502 +};
12503 +
12504 +#define get_fm_handle(net_dev) \
12505 + (((struct dpa_priv_s *)netdev_priv(net_dev))->mac_dev->fm_dev)
12506 +
12507 +#define for_each_port_device(i, port_dev) \
12508 + for (i = 0; i < ARRAY_SIZE(port_dev); i++)
12509 +
12510 +static inline __attribute((nonnull)) void *macdev_priv(
12511 + const struct mac_device *mac_dev)
12512 +{
12513 + return (void *)mac_dev + sizeof(*mac_dev);
12514 +}
12515 +
12516 +extern const char *mac_driver_description;
12517 +extern const size_t mac_sizeof_priv[];
12518 +extern void (*const mac_setup[])(struct mac_device *mac_dev);
12519 +
12520 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx);
12521 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause);
12522 +
12523 +#endif /* __MAC_H */
12524 --- /dev/null
12525 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
12526 @@ -0,0 +1,848 @@
12527 +/* Copyright 2011-2012 Freescale Semiconductor Inc.
12528 + *
12529 + * Redistribution and use in source and binary forms, with or without
12530 + * modification, are permitted provided that the following conditions are met:
12531 + * * Redistributions of source code must retain the above copyright
12532 + * notice, this list of conditions and the following disclaimer.
12533 + * * Redistributions in binary form must reproduce the above copyright
12534 + * notice, this list of conditions and the following disclaimer in the
12535 + * documentation and/or other materials provided with the distribution.
12536 + * * Neither the name of Freescale Semiconductor nor the
12537 + * names of its contributors may be used to endorse or promote products
12538 + * derived from this software without specific prior written permission.
12539 + *
12540 + *
12541 + * ALTERNATIVELY, this software may be distributed under the terms of the
12542 + * GNU General Public License ("GPL") as published by the Free Software
12543 + * Foundation, either version 2 of that License or (at your option) any
12544 + * later version.
12545 + *
12546 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12547 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12548 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12549 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12550 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12551 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12552 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12553 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12554 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12555 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12556 + */
12557 +
12558 +/* Offline Parsing / Host Command port driver for FSL QorIQ FMan.
12559 + * Validates device-tree configuration and sets up the offline ports.
12560 + */
12561 +
12562 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
12563 +#define pr_fmt(fmt) \
12564 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
12565 + KBUILD_BASENAME".c", __LINE__, __func__
12566 +#else
12567 +#define pr_fmt(fmt) \
12568 + KBUILD_MODNAME ": " fmt
12569 +#endif
12570 +
12571 +
12572 +#include <linux/init.h>
12573 +#include <linux/module.h>
12574 +#include <linux/of_platform.h>
12575 +#include <linux/fsl_qman.h>
12576 +
12577 +#include "offline_port.h"
12578 +#include "dpaa_eth.h"
12579 +#include "dpaa_eth_common.h"
12580 +
12581 +#define OH_MOD_DESCRIPTION "FSL FMan Offline Parsing port driver"
12582 +/* Manip extra space and data alignment for fragmentation */
12583 +#define FRAG_MANIP_SPACE 128
12584 +#define FRAG_DATA_ALIGN 64
12585 +
12586 +
12587 +MODULE_LICENSE("Dual BSD/GPL");
12588 +MODULE_AUTHOR("Bogdan Hamciuc <bogdan.hamciuc@freescale.com>");
12589 +MODULE_DESCRIPTION(OH_MOD_DESCRIPTION);
12590 +
12591 +
12592 +static const struct of_device_id oh_port_match_table[] = {
12593 + {
12594 + .compatible = "fsl,dpa-oh"
12595 + },
12596 + {
12597 + .compatible = "fsl,dpa-oh-shared"
12598 + },
12599 + {}
12600 +};
12601 +MODULE_DEVICE_TABLE(of, oh_port_match_table);
12602 +
12603 +#ifdef CONFIG_PM
12604 +
12605 +static int oh_suspend(struct device *dev)
12606 +{
12607 + struct dpa_oh_config_s *oh_config;
12608 +
12609 + oh_config = dev_get_drvdata(dev);
12610 + return fm_port_suspend(oh_config->oh_port);
12611 +}
12612 +
12613 +static int oh_resume(struct device *dev)
12614 +{
12615 + struct dpa_oh_config_s *oh_config;
12616 +
12617 + oh_config = dev_get_drvdata(dev);
12618 + return fm_port_resume(oh_config->oh_port);
12619 +}
12620 +
12621 +static const struct dev_pm_ops oh_pm_ops = {
12622 + .suspend = oh_suspend,
12623 + .resume = oh_resume,
12624 +};
12625 +
12626 +#define OH_PM_OPS (&oh_pm_ops)
12627 +
12628 +#else /* CONFIG_PM */
12629 +
12630 +#define OH_PM_OPS NULL
12631 +
12632 +#endif /* CONFIG_PM */
12633 +
12634 +/* Creates Frame Queues */
12635 +static uint32_t oh_fq_create(struct qman_fq *fq,
12636 + uint32_t fq_id, uint16_t channel,
12637 + uint16_t wq_id)
12638 +{
12639 + struct qm_mcc_initfq fq_opts;
12640 + uint32_t create_flags, init_flags;
12641 + uint32_t ret = 0;
12642 +
12643 + if (fq == NULL)
12644 + return 1;
12645 +
12646 + /* Set flags for FQ create */
12647 + create_flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_TO_DCPORTAL;
12648 +
12649 + /* Create frame queue */
12650 + ret = qman_create_fq(fq_id, create_flags, fq);
12651 + if (ret != 0)
12652 + return 1;
12653 +
12654 + /* Set flags for FQ init */
12655 + init_flags = QMAN_INITFQ_FLAG_SCHED;
12656 +
12657 + /* Set FQ init options. Specify destination WQ ID and channel */
12658 + fq_opts.we_mask = QM_INITFQ_WE_DESTWQ;
12659 + fq_opts.fqd.dest.wq = wq_id;
12660 + fq_opts.fqd.dest.channel = channel;
12661 +
12662 + /* Initialize frame queue */
12663 + ret = qman_init_fq(fq, init_flags, &fq_opts);
12664 + if (ret != 0) {
12665 + qman_destroy_fq(fq, 0);
12666 + return 1;
12667 + }
12668 +
12669 + return 0;
12670 +}
12671 +
12672 +static void dump_fq(struct device *dev, int fqid, uint16_t channel)
12673 +{
12674 + if (channel) {
12675 + /* display fqs with a valid (!= 0) destination channel */
12676 + dev_info(dev, "FQ ID:%d Channel ID:%d\n", fqid, channel);
12677 + }
12678 +}
12679 +
12680 +static void dump_fq_duple(struct device *dev, struct qman_fq *fqs,
12681 + int fqs_count, uint16_t channel_id)
12682 +{
12683 + int i;
12684 + for (i = 0; i < fqs_count; i++)
12685 + dump_fq(dev, (fqs + i)->fqid, channel_id);
12686 +}
12687 +
12688 +static void dump_oh_config(struct device *dev, struct dpa_oh_config_s *conf)
12689 +{
12690 + struct list_head *fq_list;
12691 + struct fq_duple *fqd;
12692 + int i;
12693 +
12694 + dev_info(dev, "Default egress frame queue: %d\n", conf->default_fqid);
12695 + dev_info(dev, "Default error frame queue: %d\n", conf->error_fqid);
12696 +
12697 + /* TX queues (old initialization) */
12698 + dev_info(dev, "Initialized queues:");
12699 + for (i = 0; i < conf->egress_cnt; i++)
12700 + dump_fq_duple(dev, conf->egress_fqs, conf->egress_cnt,
12701 + conf->channel);
12702 +
12703 + /* initialized ingress queues */
12704 + list_for_each(fq_list, &conf->fqs_ingress_list) {
12705 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12706 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12707 + }
12708 +
12709 + /* initialized egress queues */
12710 + list_for_each(fq_list, &conf->fqs_egress_list) {
12711 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12712 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12713 + }
12714 +}
12715 +
12716 +/* Destroys Frame Queues */
12717 +static void oh_fq_destroy(struct qman_fq *fq)
12718 +{
12719 + int _errno = 0;
12720 +
12721 + _errno = qman_retire_fq(fq, NULL);
12722 + if (unlikely(_errno < 0))
12723 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_retire_fq(%u)=%d\n",
12724 + KBUILD_BASENAME".c", __LINE__, __func__,
12725 + qman_fq_fqid(fq), _errno);
12726 +
12727 + _errno = qman_oos_fq(fq);
12728 + if (unlikely(_errno < 0)) {
12729 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_oos_fq(%u)=%d\n",
12730 + KBUILD_BASENAME".c", __LINE__, __func__,
12731 + qman_fq_fqid(fq), _errno);
12732 + }
12733 +
12734 + qman_destroy_fq(fq, 0);
12735 +}
12736 +
12737 +/* Allocation code for the OH port's PCD frame queues */
12738 +static int __cold oh_alloc_pcd_fqids(struct device *dev,
12739 + uint32_t num,
12740 + uint8_t alignment,
12741 + uint32_t *base_fqid)
12742 +{
12743 + dev_crit(dev, "callback not implemented!\n");
12744 + BUG();
12745 +
12746 + return 0;
12747 +}
12748 +
12749 +static int __cold oh_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
12750 +{
12751 + dev_crit(dev, "callback not implemented!\n");
12752 + BUG();
12753 +
12754 + return 0;
12755 +}
12756 +
12757 +static void oh_set_buffer_layout(struct fm_port *port,
12758 + struct dpa_buffer_layout_s *layout)
12759 +{
12760 + struct fm_port_params params;
12761 +
12762 + layout->priv_data_size = DPA_TX_PRIV_DATA_SIZE;
12763 + layout->parse_results = true;
12764 + layout->hash_results = true;
12765 + layout->time_stamp = false;
12766 +
12767 + fm_port_get_buff_layout_ext_params(port, &params);
12768 + layout->manip_extra_space = params.manip_extra_space;
12769 + layout->data_align = params.data_align;
12770 +}
12771 +
12772 +static int
12773 +oh_port_probe(struct platform_device *_of_dev)
12774 +{
12775 + struct device *dpa_oh_dev;
12776 + struct device_node *dpa_oh_node;
12777 + int lenp, _errno = 0, fq_idx, duple_idx;
12778 + int n_size, i, j, ret, duples_count;
12779 + struct platform_device *oh_of_dev;
12780 + struct device_node *oh_node, *bpool_node = NULL, *root_node;
12781 + struct device *oh_dev;
12782 + struct dpa_oh_config_s *oh_config = NULL;
12783 + const __be32 *oh_all_queues;
12784 + const __be32 *channel_ids;
12785 + const __be32 *oh_tx_queues;
12786 + uint32_t queues_count;
12787 + uint32_t crt_fqid_base;
12788 + uint32_t crt_fq_count;
12789 + bool frag_enabled = false;
12790 + struct fm_port_params oh_port_tx_params;
12791 + struct fm_port_pcd_param oh_port_pcd_params;
12792 + struct dpa_buffer_layout_s buf_layout;
12793 +
12794 + /* True if the current partition owns the OH port. */
12795 + bool init_oh_port;
12796 +
12797 + const struct of_device_id *match;
12798 + int crt_ext_pools_count;
12799 + u32 ext_pool_size;
12800 + u32 port_id;
12801 + u32 channel_id;
12802 +
12803 + int channel_ids_count;
12804 + int channel_idx;
12805 + struct fq_duple *fqd;
12806 + struct list_head *fq_list, *fq_list_tmp;
12807 +
12808 + const __be32 *bpool_cfg;
12809 + uint32_t bpid;
12810 +
12811 + memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params));
12812 + dpa_oh_dev = &_of_dev->dev;
12813 + dpa_oh_node = dpa_oh_dev->of_node;
12814 + BUG_ON(dpa_oh_node == NULL);
12815 +
12816 + match = of_match_device(oh_port_match_table, dpa_oh_dev);
12817 + if (!match)
12818 + return -EINVAL;
12819 +
12820 + dev_dbg(dpa_oh_dev, "Probing OH port...\n");
12821 +
12822 + /* Find the referenced OH node */
12823 + oh_node = of_parse_phandle(dpa_oh_node, "fsl,fman-oh-port", 0);
12824 + if (oh_node == NULL) {
12825 + dev_err(dpa_oh_dev,
12826 + "Can't find OH node referenced from node %s\n",
12827 + dpa_oh_node->full_name);
12828 + return -EINVAL;
12829 + }
12830 + dev_info(dpa_oh_dev, "Found OH node handle compatible with %s\n",
12831 + match->compatible);
12832 +
12833 + _errno = of_property_read_u32(oh_node, "cell-index", &port_id);
12834 + if (_errno) {
12835 + dev_err(dpa_oh_dev, "No port id found in node %s\n",
12836 + dpa_oh_node->full_name);
12837 + goto return_kfree;
12838 + }
12839 +
12840 + _errno = of_property_read_u32(oh_node, "fsl,qman-channel-id",
12841 + &channel_id);
12842 + if (_errno) {
12843 + dev_err(dpa_oh_dev, "No channel id found in node %s\n",
12844 + dpa_oh_node->full_name);
12845 + goto return_kfree;
12846 + }
12847 +
12848 + oh_of_dev = of_find_device_by_node(oh_node);
12849 + BUG_ON(oh_of_dev == NULL);
12850 + oh_dev = &oh_of_dev->dev;
12851 +
12852 + /* The OH port must be initialized exactly once.
12853 + * The following scenarios are of interest:
12854 + * - the node is Linux-private (will always initialize it);
12855 + * - the node is shared between two Linux partitions
12856 + * (only one of them will initialize it);
12857 + * - the node is shared between a Linux and a LWE partition
12858 + * (Linux will initialize it) - "fsl,dpa-oh-shared"
12859 + */
12860 +
12861 + /* Check if the current partition owns the OH port
12862 + * and ought to initialize it. It may be the case that we leave this
12863 + * to another (also Linux) partition.
12864 + */
12865 + init_oh_port = strcmp(match->compatible, "fsl,dpa-oh-shared");
12866 +
12867 + /* If we aren't the "owner" of the OH node, we're done here. */
12868 + if (!init_oh_port) {
12869 + dev_dbg(dpa_oh_dev,
12870 + "Not owning the shared OH port %s, will not initialize it.\n",
12871 + oh_node->full_name);
12872 + of_node_put(oh_node);
12873 + return 0;
12874 + }
12875 +
12876 + /* Allocate OH dev private data */
12877 + oh_config = devm_kzalloc(dpa_oh_dev, sizeof(*oh_config), GFP_KERNEL);
12878 + if (oh_config == NULL) {
12879 + dev_err(dpa_oh_dev,
12880 + "Can't allocate private data for OH node %s referenced from node %s!\n",
12881 + oh_node->full_name, dpa_oh_node->full_name);
12882 + _errno = -ENOMEM;
12883 + goto return_kfree;
12884 + }
12885 +
12886 + INIT_LIST_HEAD(&oh_config->fqs_ingress_list);
12887 + INIT_LIST_HEAD(&oh_config->fqs_egress_list);
12888 +
12889 + /* FQs that enter OH port */
12890 + lenp = 0;
12891 + oh_all_queues = of_get_property(dpa_oh_node,
12892 + "fsl,qman-frame-queues-ingress", &lenp);
12893 + if (lenp % (2 * sizeof(*oh_all_queues))) {
12894 + dev_warn(dpa_oh_dev,
12895 + "Wrong ingress queues format for OH node %s referenced from node %s!\n",
12896 + oh_node->full_name, dpa_oh_node->full_name);
12897 + /* just ignore the last unpaired value */
12898 + }
12899 +
12900 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
12901 + dev_err(dpa_oh_dev, "Allocating %d ingress frame queues duples\n",
12902 + duples_count);
12903 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
12904 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
12905 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
12906 +
12907 + fqd = devm_kzalloc(dpa_oh_dev,
12908 + sizeof(struct fq_duple), GFP_KERNEL);
12909 + if (!fqd) {
12910 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
12911 + oh_node->full_name,
12912 + dpa_oh_node->full_name);
12913 + _errno = -ENOMEM;
12914 + goto return_kfree;
12915 + }
12916 +
12917 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
12918 + crt_fq_count * sizeof(struct qman_fq),
12919 + GFP_KERNEL);
12920 + if (!fqd->fqs) {
12921 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
12922 + oh_node->full_name,
12923 + dpa_oh_node->full_name);
12924 + _errno = -ENOMEM;
12925 + goto return_kfree;
12926 + }
12927 +
12928 + for (j = 0; j < crt_fq_count; j++)
12929 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
12930 + fqd->fqs_count = crt_fq_count;
12931 + fqd->channel_id = (uint16_t)channel_id;
12932 + list_add(&fqd->fq_list, &oh_config->fqs_ingress_list);
12933 + }
12934 +
12935 + /* create the ingress queues */
12936 + list_for_each(fq_list, &oh_config->fqs_ingress_list) {
12937 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12938 +
12939 + for (j = 0; j < fqd->fqs_count; j++) {
12940 + ret = oh_fq_create(fqd->fqs + j,
12941 + (fqd->fqs + j)->fqid,
12942 + fqd->channel_id, 3);
12943 + if (ret != 0) {
12944 + dev_err(dpa_oh_dev, "Unable to create ingress frame queue %d for OH node %s referenced from node %s!\n",
12945 + (fqd->fqs + j)->fqid,
12946 + oh_node->full_name,
12947 + dpa_oh_node->full_name);
12948 + _errno = -EINVAL;
12949 + goto return_kfree;
12950 + }
12951 + }
12952 + }
12953 +
12954 + /* FQs that exit OH port */
12955 + lenp = 0;
12956 + oh_all_queues = of_get_property(dpa_oh_node,
12957 + "fsl,qman-frame-queues-egress", &lenp);
12958 + if (lenp % (2 * sizeof(*oh_all_queues))) {
12959 + dev_warn(dpa_oh_dev,
12960 + "Wrong egress queues format for OH node %s referenced from node %s!\n",
12961 + oh_node->full_name, dpa_oh_node->full_name);
12962 + /* just ignore the last unpaired value */
12963 + }
12964 +
12965 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
12966 + dev_dbg(dpa_oh_dev, "Allocating %d egress frame queues duples\n",
12967 + duples_count);
12968 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
12969 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
12970 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
12971 +
12972 + fqd = devm_kzalloc(dpa_oh_dev,
12973 + sizeof(struct fq_duple), GFP_KERNEL);
12974 + if (!fqd) {
12975 + dev_err(dpa_oh_dev, "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
12976 + oh_node->full_name,
12977 + dpa_oh_node->full_name);
12978 + _errno = -ENOMEM;
12979 + goto return_kfree;
12980 + }
12981 +
12982 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
12983 + crt_fq_count * sizeof(struct qman_fq),
12984 + GFP_KERNEL);
12985 + if (!fqd->fqs) {
12986 + dev_err(dpa_oh_dev,
12987 + "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
12988 + oh_node->full_name,
12989 + dpa_oh_node->full_name);
12990 + _errno = -ENOMEM;
12991 + goto return_kfree;
12992 + }
12993 +
12994 + for (j = 0; j < crt_fq_count; j++)
12995 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
12996 + fqd->fqs_count = crt_fq_count;
12997 + /* channel ID is specified in another attribute */
12998 + fqd->channel_id = 0;
12999 + list_add_tail(&fqd->fq_list, &oh_config->fqs_egress_list);
13000 +
13001 + /* allocate the queue */
13002 +
13003 + }
13004 +
13005 + /* channel_ids for FQs that exit OH port */
13006 + lenp = 0;
13007 + channel_ids = of_get_property(dpa_oh_node,
13008 + "fsl,qman-channel-ids-egress", &lenp);
13009 +
13010 + channel_ids_count = lenp / (sizeof(*channel_ids));
13011 + if (channel_ids_count != duples_count) {
13012 + dev_warn(dpa_oh_dev,
13013 + "Not all egress queues have a channel id for OH node %s referenced from node %s!\n",
13014 + oh_node->full_name, dpa_oh_node->full_name);
13015 + /* just ignore the queues that do not have a Channel ID */
13016 + }
13017 +
13018 + channel_idx = 0;
13019 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13020 + if (channel_idx + 1 > channel_ids_count)
13021 + break;
13022 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13023 + fqd->channel_id =
13024 + (uint16_t)be32_to_cpu(channel_ids[channel_idx++]);
13025 + }
13026 +
13027 + /* create egress queues */
13028 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13029 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13030 +
13031 + if (fqd->channel_id == 0) {
13032 + /* missing channel id in dts */
13033 + continue;
13034 + }
13035 +
13036 + for (j = 0; j < fqd->fqs_count; j++) {
13037 + ret = oh_fq_create(fqd->fqs + j,
13038 + (fqd->fqs + j)->fqid,
13039 + fqd->channel_id, 3);
13040 + if (ret != 0) {
13041 + dev_err(dpa_oh_dev, "Unable to create egress frame queue %d for OH node %s referenced from node %s!\n",
13042 + (fqd->fqs + j)->fqid,
13043 + oh_node->full_name,
13044 + dpa_oh_node->full_name);
13045 + _errno = -EINVAL;
13046 + goto return_kfree;
13047 + }
13048 + }
13049 + }
13050 +
13051 + /* Read FQ ids/nums for the DPA OH node */
13052 + oh_all_queues = of_get_property(dpa_oh_node,
13053 + "fsl,qman-frame-queues-oh", &lenp);
13054 + if (oh_all_queues == NULL) {
13055 + dev_err(dpa_oh_dev,
13056 + "No frame queues have been defined for OH node %s referenced from node %s\n",
13057 + oh_node->full_name, dpa_oh_node->full_name);
13058 + _errno = -EINVAL;
13059 + goto return_kfree;
13060 + }
13061 +
13062 + /* Check that the OH error and default FQs are there */
13063 + BUG_ON(lenp % (2 * sizeof(*oh_all_queues)));
13064 + queues_count = lenp / (2 * sizeof(*oh_all_queues));
13065 + if (queues_count != 2) {
13066 + dev_err(dpa_oh_dev,
13067 + "Error and Default queues must be defined for OH node %s referenced from node %s\n",
13068 + oh_node->full_name, dpa_oh_node->full_name);
13069 + _errno = -EINVAL;
13070 + goto return_kfree;
13071 + }
13072 +
13073 + /* Read the FQIDs defined for this OH port */
13074 + dev_dbg(dpa_oh_dev, "Reading %d queues...\n", queues_count);
13075 + fq_idx = 0;
13076 +
13077 + /* Error FQID - must be present */
13078 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13079 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13080 + if (crt_fq_count != 1) {
13081 + dev_err(dpa_oh_dev,
13082 + "Only 1 Error FQ allowed in OH node %s referenced from node %s (read: %d FQIDs).\n",
13083 + oh_node->full_name, dpa_oh_node->full_name,
13084 + crt_fq_count);
13085 + _errno = -EINVAL;
13086 + goto return_kfree;
13087 + }
13088 + oh_config->error_fqid = crt_fqid_base;
13089 + dev_dbg(dpa_oh_dev, "Read Error FQID 0x%x for OH port %s.\n",
13090 + oh_config->error_fqid, oh_node->full_name);
13091 +
13092 + /* Default FQID - must be present */
13093 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13094 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13095 + if (crt_fq_count != 1) {
13096 + dev_err(dpa_oh_dev,
13097 + "Only 1 Default FQ allowed in OH node %s referenced from %s (read: %d FQIDs).\n",
13098 + oh_node->full_name, dpa_oh_node->full_name,
13099 + crt_fq_count);
13100 + _errno = -EINVAL;
13101 + goto return_kfree;
13102 + }
13103 + oh_config->default_fqid = crt_fqid_base;
13104 + dev_dbg(dpa_oh_dev, "Read Default FQID 0x%x for OH port %s.\n",
13105 + oh_config->default_fqid, oh_node->full_name);
13106 +
13107 + /* TX FQID - presence is optional */
13108 + oh_tx_queues = of_get_property(dpa_oh_node, "fsl,qman-frame-queues-tx",
13109 + &lenp);
13110 + if (oh_tx_queues == NULL) {
13111 + dev_dbg(dpa_oh_dev,
13112 + "No tx queues have been defined for OH node %s referenced from node %s\n",
13113 + oh_node->full_name, dpa_oh_node->full_name);
13114 + goto config_port;
13115 + }
13116 +
13117 + /* Check that queues-tx has only a base and a count defined */
13118 + BUG_ON(lenp % (2 * sizeof(*oh_tx_queues)));
13119 + queues_count = lenp / (2 * sizeof(*oh_tx_queues));
13120 + if (queues_count != 1) {
13121 + dev_err(dpa_oh_dev,
13122 + "TX queues must be defined in only one <base count> tuple for OH node %s referenced from node %s\n",
13123 + oh_node->full_name, dpa_oh_node->full_name);
13124 + _errno = -EINVAL;
13125 + goto return_kfree;
13126 + }
13127 +
13128 + fq_idx = 0;
13129 + crt_fqid_base = be32_to_cpu(oh_tx_queues[fq_idx++]);
13130 + crt_fq_count = be32_to_cpu(oh_tx_queues[fq_idx++]);
13131 + oh_config->egress_cnt = crt_fq_count;
13132 +
13133 + /* Allocate TX queues */
13134 + dev_dbg(dpa_oh_dev, "Allocating %d queues for TX...\n", crt_fq_count);
13135 + oh_config->egress_fqs = devm_kzalloc(dpa_oh_dev,
13136 + crt_fq_count * sizeof(struct qman_fq), GFP_KERNEL);
13137 + if (oh_config->egress_fqs == NULL) {
13138 + dev_err(dpa_oh_dev,
13139 + "Can't allocate private data for TX queues for OH node %s referenced from node %s!\n",
13140 + oh_node->full_name, dpa_oh_node->full_name);
13141 + _errno = -ENOMEM;
13142 + goto return_kfree;
13143 + }
13144 +
13145 + /* Create TX queues */
13146 + for (i = 0; i < crt_fq_count; i++) {
13147 + ret = oh_fq_create(oh_config->egress_fqs + i,
13148 + crt_fqid_base + i, (uint16_t)channel_id, 3);
13149 + if (ret != 0) {
13150 + dev_err(dpa_oh_dev,
13151 + "Unable to create TX frame queue %d for OH node %s referenced from node %s!\n",
13152 + crt_fqid_base + i, oh_node->full_name,
13153 + dpa_oh_node->full_name);
13154 + _errno = -EINVAL;
13155 + goto return_kfree;
13156 + }
13157 + }
13158 +
13159 +config_port:
13160 + /* Get a handle to the fm_port so we can set
13161 + * its configuration params
13162 + */
13163 + oh_config->oh_port = fm_port_bind(oh_dev);
13164 + if (oh_config->oh_port == NULL) {
13165 + dev_err(dpa_oh_dev, "NULL drvdata from fm port dev %s!\n",
13166 + oh_node->full_name);
13167 + _errno = -EINVAL;
13168 + goto return_kfree;
13169 + }
13170 +
13171 + oh_set_buffer_layout(oh_config->oh_port, &buf_layout);
13172 +
13173 + /* read the pool handlers */
13174 + crt_ext_pools_count = of_count_phandle_with_args(dpa_oh_node,
13175 + "fsl,bman-buffer-pools", NULL);
13176 + if (crt_ext_pools_count <= 0) {
13177 + dev_info(dpa_oh_dev,
13178 + "OH port %s has no buffer pool. Fragmentation will not be enabled\n",
13179 + oh_node->full_name);
13180 + goto init_port;
13181 + }
13182 +
13183 + /* used for reading ext_pool_size*/
13184 + root_node = of_find_node_by_path("/");
13185 + if (root_node == NULL) {
13186 + dev_err(dpa_oh_dev, "of_find_node_by_path(/) failed\n");
13187 + _errno = -EINVAL;
13188 + goto return_kfree;
13189 + }
13190 +
13191 + n_size = of_n_size_cells(root_node);
13192 + of_node_put(root_node);
13193 +
13194 + dev_dbg(dpa_oh_dev, "OH port number of pools = %d\n",
13195 + crt_ext_pools_count);
13196 +
13197 + oh_port_tx_params.num_pools = (uint8_t)crt_ext_pools_count;
13198 +
13199 + for (i = 0; i < crt_ext_pools_count; i++) {
13200 + bpool_node = of_parse_phandle(dpa_oh_node,
13201 + "fsl,bman-buffer-pools", i);
13202 + if (bpool_node == NULL) {
13203 + dev_err(dpa_oh_dev, "Invalid Buffer pool node\n");
13204 + _errno = -EINVAL;
13205 + goto return_kfree;
13206 + }
13207 +
13208 + _errno = of_property_read_u32(bpool_node, "fsl,bpid", &bpid);
13209 + if (_errno) {
13210 + dev_err(dpa_oh_dev, "Invalid Buffer Pool ID\n");
13211 + _errno = -EINVAL;
13212 + goto return_kfree;
13213 + }
13214 +
13215 + oh_port_tx_params.pool_param[i].id = (uint8_t)bpid;
13216 + dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", bpid);
13217 +
13218 + bpool_cfg = of_get_property(bpool_node,
13219 + "fsl,bpool-ethernet-cfg", &lenp);
13220 + if (bpool_cfg == NULL) {
13221 + dev_err(dpa_oh_dev, "Invalid Buffer pool config params\n");
13222 + _errno = -EINVAL;
13223 + goto return_kfree;
13224 + }
13225 +
13226 + ext_pool_size = of_read_number(bpool_cfg + n_size, n_size);
13227 + oh_port_tx_params.pool_param[i].size = (uint16_t)ext_pool_size;
13228 + dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n",
13229 + ext_pool_size);
13230 + of_node_put(bpool_node);
13231 +
13232 + }
13233 +
13234 + if (buf_layout.data_align != FRAG_DATA_ALIGN ||
13235 + buf_layout.manip_extra_space != FRAG_MANIP_SPACE)
13236 + goto init_port;
13237 +
13238 + frag_enabled = true;
13239 + dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d",
13240 + port_id);
13241 +
13242 +init_port:
13243 + of_node_put(oh_node);
13244 + /* Set Tx params */
13245 + dpaa_eth_init_port(tx, oh_config->oh_port, oh_port_tx_params,
13246 + oh_config->error_fqid, oh_config->default_fqid, (&buf_layout),
13247 + frag_enabled);
13248 + /* Set PCD params */
13249 + oh_port_pcd_params.cba = oh_alloc_pcd_fqids;
13250 + oh_port_pcd_params.cbf = oh_free_pcd_fqids;
13251 + oh_port_pcd_params.dev = dpa_oh_dev;
13252 + fm_port_pcd_bind(oh_config->oh_port, &oh_port_pcd_params);
13253 +
13254 + dev_set_drvdata(dpa_oh_dev, oh_config);
13255 +
13256 + /* Enable the OH port */
13257 + _errno = fm_port_enable(oh_config->oh_port);
13258 + if (_errno)
13259 + goto return_kfree;
13260 +
13261 + dev_info(dpa_oh_dev, "OH port %s enabled.\n", oh_node->full_name);
13262 +
13263 + /* print of all referenced & created queues */
13264 + dump_oh_config(dpa_oh_dev, oh_config);
13265 +
13266 + return 0;
13267 +
13268 +return_kfree:
13269 + if (bpool_node)
13270 + of_node_put(bpool_node);
13271 + if (oh_node)
13272 + of_node_put(oh_node);
13273 + if (oh_config && oh_config->egress_fqs)
13274 + devm_kfree(dpa_oh_dev, oh_config->egress_fqs);
13275 +
13276 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_ingress_list) {
13277 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13278 + list_del(fq_list);
13279 + devm_kfree(dpa_oh_dev, fqd->fqs);
13280 + devm_kfree(dpa_oh_dev, fqd);
13281 + }
13282 +
13283 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_egress_list) {
13284 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13285 + list_del(fq_list);
13286 + devm_kfree(dpa_oh_dev, fqd->fqs);
13287 + devm_kfree(dpa_oh_dev, fqd);
13288 + }
13289 +
13290 + devm_kfree(dpa_oh_dev, oh_config);
13291 + return _errno;
13292 +}
13293 +
13294 +static int __cold oh_port_remove(struct platform_device *_of_dev)
13295 +{
13296 + int _errno = 0, i;
13297 + struct dpa_oh_config_s *oh_config;
13298 +
13299 + pr_info("Removing OH port...\n");
13300 +
13301 + oh_config = dev_get_drvdata(&_of_dev->dev);
13302 + if (oh_config == NULL) {
13303 + pr_err(KBUILD_MODNAME
13304 + ": %s:%hu:%s(): No OH config in device private data!\n",
13305 + KBUILD_BASENAME".c", __LINE__, __func__);
13306 + _errno = -ENODEV;
13307 + goto return_error;
13308 + }
13309 +
13310 + if (oh_config->egress_fqs)
13311 + for (i = 0; i < oh_config->egress_cnt; i++)
13312 + oh_fq_destroy(oh_config->egress_fqs + i);
13313 +
13314 + if (oh_config->oh_port == NULL) {
13315 + pr_err(KBUILD_MODNAME
13316 + ": %s:%hu:%s(): No fm port in device private data!\n",
13317 + KBUILD_BASENAME".c", __LINE__, __func__);
13318 + _errno = -EINVAL;
13319 + goto free_egress_fqs;
13320 + }
13321 +
13322 + _errno = fm_port_disable(oh_config->oh_port);
13323 +
13324 +free_egress_fqs:
13325 + if (oh_config->egress_fqs)
13326 + devm_kfree(&_of_dev->dev, oh_config->egress_fqs);
13327 + devm_kfree(&_of_dev->dev, oh_config);
13328 + dev_set_drvdata(&_of_dev->dev, NULL);
13329 +
13330 +return_error:
13331 + return _errno;
13332 +}
13333 +
13334 +static struct platform_driver oh_port_driver = {
13335 + .driver = {
13336 + .name = KBUILD_MODNAME,
13337 + .of_match_table = oh_port_match_table,
13338 + .owner = THIS_MODULE,
13339 + .pm = OH_PM_OPS,
13340 + },
13341 + .probe = oh_port_probe,
13342 + .remove = oh_port_remove
13343 +};
13344 +
13345 +static int __init __cold oh_port_load(void)
13346 +{
13347 + int _errno;
13348 +
13349 + pr_info(OH_MOD_DESCRIPTION "\n");
13350 +
13351 + _errno = platform_driver_register(&oh_port_driver);
13352 + if (_errno < 0) {
13353 + pr_err(KBUILD_MODNAME
13354 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
13355 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
13356 + }
13357 +
13358 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13359 + KBUILD_BASENAME".c", __func__);
13360 + return _errno;
13361 +}
13362 +module_init(oh_port_load);
13363 +
13364 +static void __exit __cold oh_port_unload(void)
13365 +{
13366 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
13367 + KBUILD_BASENAME".c", __func__);
13368 +
13369 + platform_driver_unregister(&oh_port_driver);
13370 +
13371 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13372 + KBUILD_BASENAME".c", __func__);
13373 +}
13374 +module_exit(oh_port_unload);
13375 --- /dev/null
13376 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
13377 @@ -0,0 +1,59 @@
13378 +/* Copyright 2011 Freescale Semiconductor Inc.
13379 + *
13380 + * Redistribution and use in source and binary forms, with or without
13381 + * modification, are permitted provided that the following conditions are met:
13382 + * * Redistributions of source code must retain the above copyright
13383 + * notice, this list of conditions and the following disclaimer.
13384 + * * Redistributions in binary form must reproduce the above copyright
13385 + * notice, this list of conditions and the following disclaimer in the
13386 + * documentation and/or other materials provided with the distribution.
13387 + * * Neither the name of Freescale Semiconductor nor the
13388 + * names of its contributors may be used to endorse or promote products
13389 + * derived from this software without specific prior written permission.
13390 + *
13391 + *
13392 + * ALTERNATIVELY, this software may be distributed under the terms of the
13393 + * GNU General Public License ("GPL") as published by the Free Software
13394 + * Foundation, either version 2 of that License or (at your option) any
13395 + * later version.
13396 + *
13397 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13398 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13399 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13400 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13401 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13402 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13403 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13404 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13405 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13406 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13407 + */
13408 +
13409 +#ifndef __OFFLINE_PORT_H
13410 +#define __OFFLINE_PORT_H
13411 +
13412 +struct fm_port;
13413 +struct qman_fq;
13414 +
13415 +/* fqs are defined in duples (base_fq, fq_count) */
13416 +struct fq_duple {
13417 + struct qman_fq *fqs;
13418 + int fqs_count;
13419 + uint16_t channel_id;
13420 + struct list_head fq_list;
13421 +};
13422 +
13423 +/* OH port configuration */
13424 +struct dpa_oh_config_s {
13425 + uint32_t error_fqid;
13426 + uint32_t default_fqid;
13427 + struct fm_port *oh_port;
13428 + uint32_t egress_cnt;
13429 + struct qman_fq *egress_fqs;
13430 + uint16_t channel;
13431 +
13432 + struct list_head fqs_ingress_list;
13433 + struct list_head fqs_egress_list;
13434 +};
13435 +
13436 +#endif /* __OFFLINE_PORT_H */
13437 --- /dev/null
13438 +++ b/drivers/net/ethernet/freescale/sdk_fman/Kconfig
13439 @@ -0,0 +1,153 @@
13440 +menu "Frame Manager support"
13441 +
13442 +menuconfig FSL_SDK_FMAN
13443 + bool "Freescale Frame Manager (datapath) support - SDK driver"
13444 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && !FSL_FMAN
13445 + default y
13446 + ---help---
13447 + If unsure, say Y.
13448 +
13449 +if FSL_SDK_FMAN
13450 +
13451 +config FSL_SDK_FMAN_TEST
13452 + bool "FMan test module"
13453 + default n
13454 + select FSL_DPAA_HOOKS
13455 + ---help---
13456 + This option compiles test code for FMan.
13457 +
13458 +menu "FMAN Processor support"
13459 +choice
13460 + depends on FSL_SDK_FMAN
13461 + prompt "Processor Type"
13462 +
13463 +config FMAN_ARM
13464 + bool "LS1043"
13465 + depends on ARM64 || ARM
13466 + ---help---
13467 + Choose "LS1043" for the ARM platforms:
13468 + LS1043
13469 +
13470 +config FMAN_P3040_P4080_P5020
13471 + bool "P3040 P4080 5020"
13472 +
13473 +config FMAN_P1023
13474 + bool "P1023"
13475 +
13476 +config FMAN_V3H
13477 + bool "FmanV3H"
13478 + ---help---
13479 + Choose "FmanV3H" for Fman rev3H:
13480 + B4860, T4240, T4160, etc
13481 +
13482 +config FMAN_V3L
13483 + bool "FmanV3L"
13484 + ---help---
13485 + Choose "FmanV3L" for Fman rev3L:
13486 + T1040, T1042, T1020, T1022, T1023, T1024, etc
13487 +
13488 +endchoice
13489 +endmenu
13490 +
13491 +config FMAN_MIB_CNT_OVF_IRQ_EN
13492 + bool "Enable the dTSEC MIB counters overflow interrupt"
13493 + default n
13494 + ---help---
13495 + Enable the dTSEC MIB counters overflow interrupt to get
13496 + accurate MIB counters values. Enabled it compensates
13497 + for the counters overflow but reduces performance and
13498 + triggers error messages in HV setups.
13499 +
13500 +config FSL_FM_MAX_FRAME_SIZE
13501 + int "Maximum L2 frame size"
13502 + depends on FSL_SDK_FMAN
13503 + range 64 9600
13504 + default "1522"
13505 + help
13506 + Configure this in relation to the maximum possible MTU of your
13507 + network configuration. In particular, one would need to
13508 + increase this value in order to use jumbo frames.
13509 + FSL_FM_MAX_FRAME_SIZE must accommodate the Ethernet FCS (4 bytes)
13510 + and one ETH+VLAN header (18 bytes), to a total of 22 bytes in
13511 + excess of the desired L3 MTU.
13512 +
13513 + Note that having too large a FSL_FM_MAX_FRAME_SIZE (much larger
13514 + than the actual MTU) may lead to buffer exhaustion, especially
13515 + in the case of badly fragmented datagrams on the Rx path.
13516 + Conversely, having a FSL_FM_MAX_FRAME_SIZE smaller than the actual
13517 + MTU will lead to frames being dropped.
13518 +
13519 + This can be overridden by specifying "fsl_fm_max_frm" in
13520 + the kernel bootargs:
13521 + * in Hypervisor-based scenarios, by adding a "chosen" node
13522 + with the "bootargs" property specifying
13523 + "fsl_fm_max_frm=<YourValue>";
13524 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13525 + modifying the "bootargs" env variable.
13526 +
13527 +config FSL_FM_RX_EXTRA_HEADROOM
13528 + int "Add extra headroom at beginning of data buffers"
13529 + depends on FSL_SDK_FMAN
13530 + range 16 384
13531 + default "64"
13532 + help
13533 + Configure this to tell the Frame Manager to reserve some extra
13534 + space at the beginning of a data buffer on the receive path,
13535 + before Internal Context fields are copied. This is in addition
13536 + to the private data area already reserved for driver internal
13537 + use. The provided value must be a multiple of 16.
13538 +
13539 + This setting can be overridden by specifying
13540 + "fsl_fm_rx_extra_headroom" in the kernel bootargs:
13541 + * in Hypervisor-based scenarios, by adding a "chosen" node
13542 + with the "bootargs" property specifying
13543 + "fsl_fm_rx_extra_headroom=<YourValue>";
13544 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13545 + modifying the "bootargs" env variable.
13546 +
13547 +config FMAN_PFC
13548 + bool "FMan PFC support (EXPERIMENTAL)"
13549 + depends on ( FMAN_V3H || FMAN_V3L || FMAN_ARM) && FSL_SDK_FMAN
13550 + default n
13551 + help
13552 + This option enables PFC support on FMan v3 ports.
13553 + Data Center Bridging defines Classes of Service that are
13554 + flow-controlled using PFC pause frames.
13555 +
13556 +if FMAN_PFC
13557 +config FMAN_PFC_COS_COUNT
13558 + int "Number of PFC Classes of Service"
13559 + depends on FMAN_PFC && FSL_SDK_FMAN
13560 + range 1 4
13561 + default "3"
13562 + help
13563 + The number of Classes of Service controlled by PFC.
13564 +
13565 +config FMAN_PFC_QUANTA_0
13566 + int "The pause quanta for PFC CoS 0"
13567 + depends on FMAN_PFC && FSL_SDK_FMAN
13568 + range 0 65535
13569 + default "65535"
13570 +
13571 +config FMAN_PFC_QUANTA_1
13572 + int "The pause quanta for PFC CoS 1"
13573 + depends on FMAN_PFC && FSL_SDK_FMAN
13574 + range 0 65535
13575 + default "65535"
13576 +
13577 +config FMAN_PFC_QUANTA_2
13578 + int "The pause quanta for PFC CoS 2"
13579 + depends on FMAN_PFC && FSL_SDK_FMAN
13580 + range 0 65535
13581 + default "65535"
13582 +
13583 +config FMAN_PFC_QUANTA_3
13584 + int "The pause quanta for PFC CoS 3"
13585 + depends on FMAN_PFC && FSL_SDK_FMAN
13586 + range 0 65535
13587 + default "65535"
13588 +endif
13589 +
13590 +endif # FSL_SDK_FMAN
13591 +
13592 +endmenu
13593 --- /dev/null
13594 +++ b/drivers/net/ethernet/freescale/sdk_fman/Makefile
13595 @@ -0,0 +1,11 @@
13596 +#
13597 +# Makefile for the Freescale Ethernet controllers
13598 +#
13599 +ccflags-y += -DVERSION=\"\"
13600 +#
13601 +#Include netcomm SW specific definitions
13602 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13603 +#
13604 +obj-y += etc/
13605 +obj-y += Peripherals/FM/
13606 +obj-y += src/
13607 --- /dev/null
13608 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
13609 @@ -0,0 +1,15 @@
13610 +#
13611 +# Makefile for the Freescale Ethernet controllers
13612 +#
13613 +ccflags-y += -DVERSION=\"\"
13614 +#
13615 +#Include netcomm SW specific definitions
13616 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13617 +
13618 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
13619 +
13620 +ccflags-y += -I$(NCSW_FM_INC)
13621 +
13622 +obj-y += fsl-ncsw-Hc.o
13623 +
13624 +fsl-ncsw-Hc-objs := hc.o
13625 --- /dev/null
13626 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
13627 @@ -0,0 +1,1232 @@
13628 +/*
13629 + * Copyright 2008-2012 Freescale Semiconductor Inc.
13630 + *
13631 + * Redistribution and use in source and binary forms, with or without
13632 + * modification, are permitted provided that the following conditions are met:
13633 + * * Redistributions of source code must retain the above copyright
13634 + * notice, this list of conditions and the following disclaimer.
13635 + * * Redistributions in binary form must reproduce the above copyright
13636 + * notice, this list of conditions and the following disclaimer in the
13637 + * documentation and/or other materials provided with the distribution.
13638 + * * Neither the name of Freescale Semiconductor nor the
13639 + * names of its contributors may be used to endorse or promote products
13640 + * derived from this software without specific prior written permission.
13641 + *
13642 + *
13643 + * ALTERNATIVELY, this software may be distributed under the terms of the
13644 + * GNU General Public License ("GPL") as published by the Free Software
13645 + * Foundation, either version 2 of that License or (at your option) any
13646 + * later version.
13647 + *
13648 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13649 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13650 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13651 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13652 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13653 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13654 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13655 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13656 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13657 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13658 + */
13659 +
13660 +
13661 +#include "std_ext.h"
13662 +#include "error_ext.h"
13663 +#include "sprint_ext.h"
13664 +#include "string_ext.h"
13665 +
13666 +#include "fm_common.h"
13667 +#include "fm_hc.h"
13668 +
13669 +
13670 +/**************************************************************************//**
13671 + @Description defaults
13672 +*//***************************************************************************/
13673 +#define DEFAULT_dataMemId 0
13674 +
13675 +#define HC_HCOR_OPCODE_PLCR_PRFL 0x0
13676 +#define HC_HCOR_OPCODE_KG_SCM 0x1
13677 +#define HC_HCOR_OPCODE_SYNC 0x2
13678 +#define HC_HCOR_OPCODE_CC 0x3
13679 +#define HC_HCOR_OPCODE_CC_AGE_MASK 0x4
13680 +#define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5
13681 +#define HC_HCOR_OPCODE_CC_REASSM_TIMEOUT 0x10
13682 +#define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11
13683 +#define HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING 0x13
13684 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24
13685 +#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24
13686 +#define HC_HCOR_EXTRA_REG_CC_AGING_ADD 0x80000000
13687 +#define HC_HCOR_EXTRA_REG_CC_AGING_REMOVE 0x40000000
13688 +#define HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK 0xC0000000
13689 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT 24
13690 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK 0x1F000000
13691 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16
13692 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF
13693 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24
13694 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16
13695 +
13696 +#define HC_HCOR_GBL 0x20000000
13697 +
13698 +#define HC_HCOR_KG_SCHEME_COUNTER 0x00000400
13699 +
13700 +#if (DPAA_VERSION == 10)
13701 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFF800
13702 +#else
13703 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFFE00
13704 +#endif /* (DPAA_VERSION == 10) */
13705 +
13706 +#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdKgPortRegs))
13707 +#define SIZE_OF_HC_FRAME_SCHEME_REGS sizeof(t_HcFrame)
13708 +#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdPlcrProfileRegs))
13709 +#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrProfileRegs)+sizeof(uint32_t))
13710 +#define SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC 16
13711 +
13712 +#define HC_CMD_POOL_SIZE (INTG_MAX_NUM_OF_CORES)
13713 +
13714 +#define BUILD_FD(len) \
13715 +do { \
13716 + memset(&fmFd, 0, sizeof(t_DpaaFD)); \
13717 + DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \
13718 + DPAA_FD_SET_OFFSET(&fmFd, 0); \
13719 + DPAA_FD_SET_LENGTH(&fmFd, len); \
13720 +} while (0)
13721 +
13722 +
13723 +#if defined(__MWERKS__) && !defined(__GNUC__)
13724 +#pragma pack(push,1)
13725 +#endif /* defined(__MWERKS__) && ... */
13726 +
13727 +typedef struct t_FmPcdKgPortRegs {
13728 + volatile uint32_t spReg;
13729 + volatile uint32_t cppReg;
13730 +} t_FmPcdKgPortRegs;
13731 +
13732 +typedef struct t_HcFrame {
13733 + volatile uint32_t opcode;
13734 + volatile uint32_t actionReg;
13735 + volatile uint32_t extraReg;
13736 + volatile uint32_t commandSequence;
13737 + union {
13738 + struct fman_kg_scheme_regs schemeRegs;
13739 + struct fman_kg_scheme_regs schemeRegsWithoutCounter;
13740 + t_FmPcdPlcrProfileRegs profileRegs;
13741 + volatile uint32_t singleRegForWrite; /* for writing SP, CPP, profile counter */
13742 + t_FmPcdKgPortRegs portRegsForRead;
13743 + volatile uint32_t clsPlanEntries[CLS_PLAN_NUM_PER_GRP];
13744 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout;
13745 + t_FmPcdCcReassmTimeoutParams ccReassmTimeout;
13746 + } hcSpecificData;
13747 +} t_HcFrame;
13748 +
13749 +#if defined(__MWERKS__) && !defined(__GNUC__)
13750 +#pragma pack(pop)
13751 +#endif /* defined(__MWERKS__) && ... */
13752 +
13753 +
13754 +typedef struct t_FmHc {
13755 + t_Handle h_FmPcd;
13756 + t_Handle h_HcPortDev;
13757 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< A callback for enqueuing frames to the QM */
13758 + t_Handle h_QmArg; /**< A handle to the QM module */
13759 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
13760 +
13761 + uint32_t seqNum[HC_CMD_POOL_SIZE]; /* FIFO of seqNum to use when
13762 + taking buffer */
13763 + uint32_t nextSeqNumLocation; /* seqNum location in seqNum[] for next buffer */
13764 + volatile bool enqueued[HC_CMD_POOL_SIZE]; /* HC is active - frame is enqueued
13765 + and not confirmed yet */
13766 + t_HcFrame *p_Frm[HC_CMD_POOL_SIZE];
13767 +} t_FmHc;
13768 +
13769 +
13770 +static t_Error FillBufPool(t_FmHc *p_FmHc)
13771 +{
13772 + uint32_t i;
13773 +
13774 + ASSERT_COND(p_FmHc);
13775 +
13776 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13777 + {
13778 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
13779 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + (16 - (sizeof(t_FmHc) % 16))),
13780 + p_FmHc->dataMemId,
13781 + 16);
13782 +#else
13783 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart(sizeof(t_HcFrame),
13784 + p_FmHc->dataMemId,
13785 + 16);
13786 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
13787 + if (!p_FmHc->p_Frm[i])
13788 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM HC frames!"));
13789 + }
13790 +
13791 + /* Initialize FIFO of seqNum to use during GetBuf */
13792 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13793 + {
13794 + p_FmHc->seqNum[i] = i;
13795 + }
13796 + p_FmHc->nextSeqNumLocation = 0;
13797 +
13798 + return E_OK;
13799 +}
13800 +
13801 +static __inline__ t_HcFrame * GetBuf(t_FmHc *p_FmHc, uint32_t *p_SeqNum)
13802 +{
13803 + uint32_t intFlags;
13804 +
13805 + ASSERT_COND(p_FmHc);
13806 +
13807 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13808 +
13809 + if (p_FmHc->nextSeqNumLocation == HC_CMD_POOL_SIZE)
13810 + {
13811 + /* No more buffers */
13812 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13813 + return NULL;
13814 + }
13815 +
13816 + *p_SeqNum = p_FmHc->seqNum[p_FmHc->nextSeqNumLocation];
13817 + p_FmHc->nextSeqNumLocation++;
13818 +
13819 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13820 + return p_FmHc->p_Frm[*p_SeqNum];
13821 +}
13822 +
13823 +static __inline__ void PutBuf(t_FmHc *p_FmHc, t_HcFrame *p_Buf, uint32_t seqNum)
13824 +{
13825 + uint32_t intFlags;
13826 +
13827 + UNUSED(p_Buf);
13828 +
13829 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13830 + ASSERT_COND(p_FmHc->nextSeqNumLocation);
13831 + p_FmHc->nextSeqNumLocation--;
13832 + p_FmHc->seqNum[p_FmHc->nextSeqNumLocation] = seqNum;
13833 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13834 +}
13835 +
13836 +static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, uint32_t seqNum)
13837 +{
13838 + t_Error err = E_OK;
13839 + uint32_t intFlags;
13840 + uint32_t timeout=100;
13841 +
13842 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13843 + ASSERT_COND(!p_FmHc->enqueued[seqNum]);
13844 + p_FmHc->enqueued[seqNum] = TRUE;
13845 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13846 + DBG(TRACE, ("Send Hc, SeqNum %d, buff@0x%x, fd offset 0x%x",
13847 + seqNum,
13848 + DPAA_FD_GET_ADDR(p_FmFd),
13849 + DPAA_FD_GET_OFFSET(p_FmFd)));
13850 + err = p_FmHc->f_QmEnqueue(p_FmHc->h_QmArg, (void *)p_FmFd);
13851 + if (err)
13852 + RETURN_ERROR(MINOR, err, ("HC enqueue failed"));
13853 +
13854 + while (p_FmHc->enqueued[seqNum] && --timeout)
13855 + XX_UDelay(100);
13856 +
13857 + if (!timeout)
13858 + RETURN_ERROR(MINOR, E_TIMEOUT, ("HC Callback, timeout exceeded"));
13859 +
13860 + return err;
13861 +}
13862 +
13863 +
13864 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams)
13865 +{
13866 + t_FmHc *p_FmHc;
13867 + t_FmPortParams fmPortParam;
13868 + t_Error err;
13869 +
13870 + p_FmHc = (t_FmHc *)XX_Malloc(sizeof(t_FmHc));
13871 + if (!p_FmHc)
13872 + {
13873 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC obj"));
13874 + return NULL;
13875 + }
13876 + memset(p_FmHc,0,sizeof(t_FmHc));
13877 +
13878 + p_FmHc->h_FmPcd = p_FmHcParams->h_FmPcd;
13879 + p_FmHc->f_QmEnqueue = p_FmHcParams->params.f_QmEnqueue;
13880 + p_FmHc->h_QmArg = p_FmHcParams->params.h_QmArg;
13881 + p_FmHc->dataMemId = DEFAULT_dataMemId;
13882 +
13883 + err = FillBufPool(p_FmHc);
13884 + if (err != E_OK)
13885 + {
13886 + REPORT_ERROR(MAJOR, err, NO_MSG);
13887 + FmHcFree(p_FmHc);
13888 + return NULL;
13889 + }
13890 +
13891 + if (!FmIsMaster(p_FmHcParams->h_Fm))
13892 + return (t_Handle)p_FmHc;
13893 +
13894 + memset(&fmPortParam, 0, sizeof(fmPortParam));
13895 + fmPortParam.baseAddr = p_FmHcParams->params.portBaseAddr;
13896 + fmPortParam.portType = e_FM_PORT_TYPE_OH_HOST_COMMAND;
13897 + fmPortParam.portId = p_FmHcParams->params.portId;
13898 + fmPortParam.liodnBase = p_FmHcParams->params.liodnBase;
13899 + fmPortParam.h_Fm = p_FmHcParams->h_Fm;
13900 +
13901 + fmPortParam.specificParams.nonRxParams.errFqid = p_FmHcParams->params.errFqid;
13902 + fmPortParam.specificParams.nonRxParams.dfltFqid = p_FmHcParams->params.confFqid;
13903 + fmPortParam.specificParams.nonRxParams.qmChannel = p_FmHcParams->params.qmChannel;
13904 +
13905 + p_FmHc->h_HcPortDev = FM_PORT_Config(&fmPortParam);
13906 + if (!p_FmHc->h_HcPortDev)
13907 + {
13908 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM HC port!"));
13909 + XX_Free(p_FmHc);
13910 + return NULL;
13911 + }
13912 +
13913 + err = FM_PORT_ConfigMaxFrameLength(p_FmHc->h_HcPortDev,
13914 + (uint16_t)sizeof(t_HcFrame));
13915 +
13916 + if (err != E_OK)
13917 + {
13918 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
13919 + FmHcFree(p_FmHc);
13920 + return NULL;
13921 + }
13922 +
13923 + /* final init */
13924 + err = FM_PORT_Init(p_FmHc->h_HcPortDev);
13925 + if (err != E_OK)
13926 + {
13927 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
13928 + FmHcFree(p_FmHc);
13929 + return NULL;
13930 + }
13931 +
13932 + err = FM_PORT_Enable(p_FmHc->h_HcPortDev);
13933 + if (err != E_OK)
13934 + {
13935 + REPORT_ERROR(MAJOR, err, ("FM HC port enable!"));
13936 + FmHcFree(p_FmHc);
13937 + return NULL;
13938 + }
13939 +
13940 + return (t_Handle)p_FmHc;
13941 +}
13942 +
13943 +void FmHcFree(t_Handle h_FmHc)
13944 +{
13945 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
13946 + int i;
13947 +
13948 + if (!p_FmHc)
13949 + return;
13950 +
13951 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
13952 + if (p_FmHc->p_Frm[i])
13953 + XX_FreeSmart(p_FmHc->p_Frm[i]);
13954 + else
13955 + break;
13956 +
13957 + if (p_FmHc->h_HcPortDev)
13958 + FM_PORT_Free(p_FmHc->h_HcPortDev);
13959 +
13960 + XX_Free(p_FmHc);
13961 +}
13962 +
13963 +/*****************************************************************************/
13964 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
13965 + uint8_t memId)
13966 +{
13967 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
13968 + int i;
13969 +
13970 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
13971 +
13972 + p_FmHc->dataMemId = memId;
13973 +
13974 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
13975 + if (p_FmHc->p_Frm[i])
13976 + XX_FreeSmart(p_FmHc->p_Frm[i]);
13977 +
13978 + return FillBufPool(p_FmHc);
13979 +}
13980 +
13981 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd)
13982 +{
13983 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
13984 + t_HcFrame *p_HcFrame;
13985 + uint32_t intFlags;
13986 +
13987 + ASSERT_COND(p_FmHc);
13988 +
13989 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13990 + p_HcFrame = (t_HcFrame *)PTR_MOVE(DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd));
13991 +
13992 + DBG(TRACE, ("Hc Conf, SeqNum %d, FD@0x%x, fd offset 0x%x",
13993 + p_HcFrame->commandSequence, DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd)));
13994 +
13995 + if (!(p_FmHc->enqueued[p_HcFrame->commandSequence]))
13996 + REPORT_ERROR(MINOR, E_INVALID_FRAME, ("Not an Host-Command frame received!"));
13997 + else
13998 + p_FmHc->enqueued[p_HcFrame->commandSequence] = FALSE;
13999 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
14000 +}
14001 +
14002 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
14003 + t_Handle h_Scheme,
14004 + struct fman_kg_scheme_regs *p_SchemeRegs,
14005 + bool updateCounter)
14006 +{
14007 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14008 + t_Error err = E_OK;
14009 + t_HcFrame *p_HcFrame;
14010 + t_DpaaFD fmFd;
14011 + uint8_t physicalSchemeId;
14012 + uint32_t seqNum;
14013 +
14014 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14015 + if (!p_HcFrame)
14016 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14017 +
14018 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14019 +
14020 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14021 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14022 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, updateCounter);
14023 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14024 + memcpy(&p_HcFrame->hcSpecificData.schemeRegs, p_SchemeRegs, sizeof(struct fman_kg_scheme_regs));
14025 + if (!updateCounter)
14026 + {
14027 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = p_SchemeRegs->kgse_dv0;
14028 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = p_SchemeRegs->kgse_dv1;
14029 + p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = p_SchemeRegs->kgse_ccbs;
14030 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = p_SchemeRegs->kgse_mv;
14031 + }
14032 + p_HcFrame->commandSequence = seqNum;
14033 +
14034 + BUILD_FD(sizeof(t_HcFrame));
14035 +
14036 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14037 +
14038 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14039 +
14040 + if (err != E_OK)
14041 + RETURN_ERROR(MINOR, err, NO_MSG);
14042 +
14043 + return E_OK;
14044 +}
14045 +
14046 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme)
14047 +{
14048 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14049 + t_Error err = E_OK;
14050 + t_HcFrame *p_HcFrame;
14051 + t_DpaaFD fmFd;
14052 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14053 + uint32_t seqNum;
14054 +
14055 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14056 + if (!p_HcFrame)
14057 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14058 +
14059 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14060 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14061 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14062 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14063 + memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
14064 + p_HcFrame->commandSequence = seqNum;
14065 +
14066 + BUILD_FD(sizeof(t_HcFrame));
14067 +
14068 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14069 +
14070 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14071 +
14072 + if (err != E_OK)
14073 + RETURN_ERROR(MINOR, err, NO_MSG);
14074 +
14075 + return E_OK;
14076 +}
14077 +
14078 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
14079 +{
14080 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14081 + t_Error err = E_OK;
14082 + t_HcFrame *p_HcFrame;
14083 + t_DpaaFD fmFd;
14084 + uint8_t relativeSchemeId;
14085 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14086 + uint32_t tmpReg32 = 0;
14087 + uint32_t seqNum;
14088 +
14089 + /* Scheme is locked by calling routine */
14090 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14091 + * "kgse_mode" or "kgse_om" without locking scheme !
14092 + */
14093 +
14094 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14095 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14096 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14097 +
14098 + if (!FmPcdKgGetRequiredActionFlag(p_FmHc->h_FmPcd, relativeSchemeId) ||
14099 + !(FmPcdKgGetRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId) & requiredAction))
14100 + {
14101 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14102 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR))
14103 + {
14104 + if ((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) ||
14105 + (FmPcdKgIsDistrOnPlcrProfile(p_FmHc->h_FmPcd, relativeSchemeId) == TRUE))
14106 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
14107 + err = FmPcdPlcrCcGetSetParams(p_FmHc->h_FmPcd, FmPcdKgGetRelativeProfileId(p_FmHc->h_FmPcd, relativeSchemeId), requiredAction);
14108 + if (err)
14109 + RETURN_ERROR(MAJOR, err, NO_MSG);
14110 + }
14111 + else /* From here we deal with KG-Schemes only */
14112 + {
14113 + /* Pre change general code */
14114 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14115 + if (!p_HcFrame)
14116 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14117 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14118 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14119 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14120 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14121 + p_HcFrame->commandSequence = seqNum;
14122 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14123 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14124 + {
14125 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14126 + RETURN_ERROR(MINOR, err, NO_MSG);
14127 + }
14128 +
14129 + /* specific change */
14130 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14131 + ((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) &&
14132 + (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME)))
14133 + {
14134 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14135 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
14136 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14137 + }
14138 +
14139 + if ((requiredAction & UPDATE_KG_NIA_CC_WA) &&
14140 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_CC))
14141 + {
14142 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14143 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
14144 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
14145 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_FM_CTL_AC_PRE_CC;
14146 + }
14147 +
14148 + if (requiredAction & UPDATE_KG_OPT_MODE)
14149 + p_HcFrame->hcSpecificData.schemeRegs.kgse_om = value;
14150 +
14151 + if (requiredAction & UPDATE_KG_NIA)
14152 + {
14153 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14154 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
14155 + tmpReg32 |= value;
14156 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32;
14157 + }
14158 +
14159 + /* Post change general code */
14160 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14161 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
14162 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14163 +
14164 + BUILD_FD(sizeof(t_HcFrame));
14165 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14166 +
14167 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14168 +
14169 + if (err != E_OK)
14170 + RETURN_ERROR(MINOR, err, NO_MSG);
14171 + }
14172 + }
14173 +
14174 + return E_OK;
14175 +}
14176 +
14177 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme)
14178 +{
14179 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14180 + t_Error err;
14181 + t_HcFrame *p_HcFrame;
14182 + t_DpaaFD fmFd;
14183 + uint32_t retVal;
14184 + uint8_t relativeSchemeId;
14185 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14186 + uint32_t seqNum;
14187 +
14188 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14189 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14190 + {
14191 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14192 + return 0;
14193 + }
14194 +
14195 + /* first read scheme and check that it is valid */
14196 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14197 + if (!p_HcFrame)
14198 + {
14199 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14200 + return 0;
14201 + }
14202 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14203 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14204 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14205 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14206 + p_HcFrame->commandSequence = seqNum;
14207 +
14208 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14209 +
14210 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14211 + if (err != E_OK)
14212 + {
14213 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14214 + REPORT_ERROR(MINOR, err, NO_MSG);
14215 + return 0;
14216 + }
14217 +
14218 + if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
14219 + {
14220 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14221 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid"));
14222 + return 0;
14223 + }
14224 +
14225 + retVal = p_HcFrame->hcSpecificData.schemeRegs.kgse_spc;
14226 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14227 +
14228 + return retVal;
14229 +}
14230 +
14231 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value)
14232 +{
14233 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14234 + t_Error err = E_OK;
14235 + t_HcFrame *p_HcFrame;
14236 + t_DpaaFD fmFd;
14237 + uint8_t relativeSchemeId, physicalSchemeId;
14238 + uint32_t seqNum;
14239 +
14240 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14241 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14242 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14243 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14244 +
14245 + /* first read scheme and check that it is valid */
14246 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14247 + if (!p_HcFrame)
14248 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14249 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14250 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14251 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14252 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_COUNTER;
14253 + /* write counter */
14254 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14255 + p_HcFrame->commandSequence = seqNum;
14256 +
14257 + BUILD_FD(sizeof(t_HcFrame));
14258 +
14259 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14260 +
14261 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14262 + return err;
14263 +}
14264 +
14265 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set)
14266 +{
14267 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14268 + t_HcFrame *p_HcFrame;
14269 + t_DpaaFD fmFd;
14270 + uint8_t i, idx;
14271 + uint32_t seqNum;
14272 + t_Error err = E_OK;
14273 +
14274 + ASSERT_COND(p_FmHc);
14275 +
14276 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14277 + if (!p_HcFrame)
14278 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14279 +
14280 + for (i = p_Set->baseEntry; i < (p_Set->baseEntry+p_Set->numOfClsPlanEntries); i+=8)
14281 + {
14282 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14283 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14284 + p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
14285 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14286 +
14287 + idx = (uint8_t)(i - p_Set->baseEntry);
14288 + ASSERT_COND(idx < FM_PCD_MAX_NUM_OF_CLS_PLANS);
14289 + memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t));
14290 + p_HcFrame->commandSequence = seqNum;
14291 +
14292 + BUILD_FD(sizeof(t_HcFrame));
14293 +
14294 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14295 + {
14296 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14297 + RETURN_ERROR(MINOR, err, NO_MSG);
14298 + }
14299 + }
14300 +
14301 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14302 + return err;
14303 +}
14304 +
14305 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId)
14306 +{
14307 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14308 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
14309 +
14310 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
14311 + if (!p_ClsPlanSet)
14312 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
14313 +
14314 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
14315 +
14316 + p_ClsPlanSet->baseEntry = FmPcdKgGetClsPlanGrpBase(p_FmHc->h_FmPcd, grpId);
14317 + p_ClsPlanSet->numOfClsPlanEntries = FmPcdKgGetClsPlanGrpSize(p_FmHc->h_FmPcd, grpId);
14318 + ASSERT_COND(p_ClsPlanSet->numOfClsPlanEntries <= FM_PCD_MAX_NUM_OF_CLS_PLANS);
14319 +
14320 + if (FmHcPcdKgSetClsPlan(p_FmHc, p_ClsPlanSet) != E_OK)
14321 + {
14322 + XX_Free(p_ClsPlanSet);
14323 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
14324 + }
14325 +
14326 + XX_Free(p_ClsPlanSet);
14327 + FmPcdKgDestroyClsPlanGrp(p_FmHc->h_FmPcd, grpId);
14328 +
14329 + return E_OK;
14330 +}
14331 +
14332 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams )
14333 +{
14334 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14335 + t_HcFrame *p_HcFrame;
14336 + t_DpaaFD fmFd;
14337 + t_Error err;
14338 + uint32_t seqNum;
14339 +
14340 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14341 +
14342 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14343 + if (!p_HcFrame)
14344 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14345 +
14346 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14347 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT);
14348 + memcpy(&p_HcFrame->hcSpecificData.ccCapwapReassmTimeout, p_CcCapwapReassmTimeoutParams, sizeof(t_FmPcdCcCapwapReassmTimeoutParams));
14349 + p_HcFrame->commandSequence = seqNum;
14350 + BUILD_FD(sizeof(t_HcFrame));
14351 +
14352 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14353 +
14354 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14355 + return err;
14356 +}
14357 +
14358 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams)
14359 +{
14360 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14361 + t_HcFrame *p_HcFrame;
14362 + t_DpaaFD fmFd;
14363 + t_Error err;
14364 + uint32_t seqNum;
14365 +
14366 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14367 +
14368 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14369 + if (!p_HcFrame)
14370 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14371 +
14372 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14373 +
14374 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION);
14375 + p_HcFrame->actionReg = (uint32_t)(((fill == TRUE) ? 0 : 1) << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT);
14376 + p_HcFrame->actionReg |= p_FmPcdCcFragScratchPoolCmdParams->bufferPoolId << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID;
14377 + if (fill == TRUE)
14378 + {
14379 + p_HcFrame->extraReg = p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers;
14380 + }
14381 + p_HcFrame->commandSequence = seqNum;
14382 +
14383 + BUILD_FD(sizeof(t_HcFrame));
14384 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14385 + {
14386 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14387 + RETURN_ERROR(MINOR, err, NO_MSG);
14388 + }
14389 +
14390 + p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers = p_HcFrame->extraReg;
14391 +
14392 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14393 + return E_OK;
14394 +}
14395 +
14396 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result)
14397 +{
14398 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14399 + t_HcFrame *p_HcFrame;
14400 + t_DpaaFD fmFd;
14401 + t_Error err;
14402 + uint32_t seqNum;
14403 +
14404 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14405 +
14406 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14407 + if (!p_HcFrame)
14408 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14409 +
14410 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14411 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_REASSM_TIMEOUT);
14412 + p_HcFrame->actionReg = (uint32_t)((p_CcReassmTimeoutParams->activate ? 0 : 1) << HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT);
14413 + p_HcFrame->extraReg = (p_CcReassmTimeoutParams->tsbs << HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT) | p_CcReassmTimeoutParams->iprcpt;
14414 + p_HcFrame->commandSequence = seqNum;
14415 +
14416 + BUILD_FD(sizeof(t_HcFrame));
14417 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14418 + {
14419 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14420 + RETURN_ERROR(MINOR, err, NO_MSG);
14421 + }
14422 +
14423 + *p_Result = (uint8_t)
14424 + ((p_HcFrame->actionReg >> HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT) & HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK);
14425 +
14426 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14427 + return E_OK;
14428 +}
14429 +
14430 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction)
14431 +{
14432 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14433 + t_HcFrame *p_HcFrame;
14434 + t_DpaaFD fmFd;
14435 + t_Error err;
14436 + uint32_t tmpReg32 = 0;
14437 + uint32_t requiredActionTmp, requiredActionFlag;
14438 + uint32_t seqNum;
14439 +
14440 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14441 +
14442 + /* Profile is locked by calling routine */
14443 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14444 + * "fmpl_pegnia" "fmpl_peynia" or "fmpl_pernia" without locking Profile !
14445 + */
14446 +
14447 + requiredActionTmp = FmPcdPlcrGetRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId);
14448 + requiredActionFlag = FmPcdPlcrGetRequiredActionFlag(p_FmHc->h_FmPcd, absoluteProfileId);
14449 +
14450 + if (!requiredActionFlag || !(requiredActionTmp & requiredAction))
14451 + {
14452 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
14453 + {
14454 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14455 + if (!p_HcFrame)
14456 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14457 + /* first read scheme and check that it is valid */
14458 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14459 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14460 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14461 + p_HcFrame->extraReg = 0x00008000;
14462 + p_HcFrame->commandSequence = seqNum;
14463 +
14464 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14465 +
14466 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14467 + {
14468 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14469 + RETURN_ERROR(MINOR, err, NO_MSG);
14470 + }
14471 +
14472 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia;
14473 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14474 + {
14475 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14476 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
14477 + ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14478 + }
14479 +
14480 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14481 +
14482 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14483 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14484 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(TRUE, FALSE, FALSE);
14485 + p_HcFrame->extraReg = 0x00008000;
14486 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14487 +
14488 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14489 +
14490 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14491 + {
14492 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14493 + RETURN_ERROR(MINOR, err, NO_MSG);
14494 + }
14495 +
14496 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_peynia;
14497 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14498 + {
14499 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14500 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14501 + }
14502 +
14503 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14504 +
14505 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14506 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14507 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, TRUE, FALSE);
14508 + p_HcFrame->extraReg = 0x00008000;
14509 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14510 +
14511 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14512 +
14513 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14514 + {
14515 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14516 + RETURN_ERROR(MINOR, err, NO_MSG);
14517 + }
14518 +
14519 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pernia;
14520 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14521 + {
14522 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14523 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14524 + }
14525 +
14526 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14527 +
14528 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14529 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14530 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, FALSE, TRUE);
14531 + p_HcFrame->extraReg = 0x00008000;
14532 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14533 +
14534 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14535 +
14536 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14537 + {
14538 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14539 + RETURN_ERROR(MINOR, err, NO_MSG);
14540 + }
14541 +
14542 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14543 + }
14544 + }
14545 +
14546 + return E_OK;
14547 +}
14548 +
14549 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs)
14550 +{
14551 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14552 + t_Error err = E_OK;
14553 + uint16_t profileIndx;
14554 + t_HcFrame *p_HcFrame;
14555 + t_DpaaFD fmFd;
14556 + uint32_t seqNum;
14557 +
14558 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14559 + if (!p_HcFrame)
14560 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14561 +
14562 + profileIndx = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14563 +
14564 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14565 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14566 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
14567 + p_HcFrame->extraReg = 0x00008000;
14568 + memcpy(&p_HcFrame->hcSpecificData.profileRegs, p_PlcrRegs, sizeof(t_FmPcdPlcrProfileRegs));
14569 + p_HcFrame->commandSequence = seqNum;
14570 +
14571 + BUILD_FD(sizeof(t_HcFrame));
14572 +
14573 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14574 +
14575 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14576 +
14577 + if (err != E_OK)
14578 + RETURN_ERROR(MINOR, err, NO_MSG);
14579 +
14580 + return E_OK;
14581 +}
14582 +
14583 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile)
14584 +{
14585 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14586 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14587 + t_Error err = E_OK;
14588 + t_HcFrame *p_HcFrame;
14589 + t_DpaaFD fmFd;
14590 + uint32_t seqNum;
14591 +
14592 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14593 + if (!p_HcFrame)
14594 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14595 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14596 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14597 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14598 + p_HcFrame->actionReg |= 0x00008000;
14599 + p_HcFrame->extraReg = 0x00008000;
14600 + memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrProfileRegs));
14601 + p_HcFrame->commandSequence = seqNum;
14602 +
14603 + BUILD_FD(sizeof(t_HcFrame));
14604 +
14605 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14606 +
14607 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14608 +
14609 + if (err != E_OK)
14610 + RETURN_ERROR(MINOR, err, NO_MSG);
14611 +
14612 + return E_OK;
14613 +}
14614 +
14615 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
14616 +{
14617 +
14618 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14619 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14620 + t_Error err = E_OK;
14621 + t_HcFrame *p_HcFrame;
14622 + t_DpaaFD fmFd;
14623 + uint32_t seqNum;
14624 +
14625 + /* first read scheme and check that it is valid */
14626 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14627 + if (!p_HcFrame)
14628 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14629 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14630 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14631 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14632 + p_HcFrame->actionReg |= FmPcdPlcrBuildCounterProfileReg(counter);
14633 + p_HcFrame->extraReg = 0x00008000;
14634 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14635 + p_HcFrame->commandSequence = seqNum;
14636 +
14637 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14638 +
14639 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14640 +
14641 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14642 +
14643 + if (err != E_OK)
14644 + RETURN_ERROR(MINOR, err, NO_MSG);
14645 +
14646 + return E_OK;
14647 +}
14648 +
14649 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
14650 +{
14651 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14652 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14653 + t_Error err;
14654 + t_HcFrame *p_HcFrame;
14655 + t_DpaaFD fmFd;
14656 + uint32_t retVal = 0;
14657 + uint32_t seqNum;
14658 +
14659 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14660 +
14661 + /* first read scheme and check that it is valid */
14662 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14663 + if (!p_HcFrame)
14664 + {
14665 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14666 + return 0;
14667 + }
14668 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14669 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14670 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14671 + p_HcFrame->extraReg = 0x00008000;
14672 + p_HcFrame->commandSequence = seqNum;
14673 +
14674 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14675 +
14676 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14677 + if (err != E_OK)
14678 + {
14679 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14680 + REPORT_ERROR(MINOR, err, NO_MSG);
14681 + return 0;
14682 + }
14683 +
14684 + switch (counter)
14685 + {
14686 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
14687 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegpc;
14688 + break;
14689 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
14690 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_peypc;
14691 + break;
14692 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
14693 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perpc;
14694 + break;
14695 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
14696 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perypc;
14697 + break;
14698 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
14699 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perrpc;
14700 + break;
14701 + default:
14702 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
14703 + }
14704 +
14705 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14706 + return retVal;
14707 +}
14708 +
14709 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add)
14710 +{
14711 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14712 + t_HcFrame *p_HcFrame;
14713 + t_DpaaFD fmFd;
14714 + t_Error err = E_OK;
14715 + uint32_t seqNum;
14716 +
14717 + ASSERT_COND(p_FmHc);
14718 +
14719 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14720 + if (!p_HcFrame)
14721 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14722 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14723 + /* first read SP register */
14724 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14725 + p_HcFrame->actionReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
14726 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14727 + p_HcFrame->commandSequence = seqNum;
14728 +
14729 + BUILD_FD(SIZE_OF_HC_FRAME_PORT_REGS);
14730 +
14731 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14732 + {
14733 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14734 + RETURN_ERROR(MINOR, err, NO_MSG);
14735 + }
14736 +
14737 + /* spReg is the first reg, so we can use it both for read and for write */
14738 + if (add)
14739 + p_HcFrame->hcSpecificData.portRegsForRead.spReg |= spReg;
14740 + else
14741 + p_HcFrame->hcSpecificData.portRegsForRead.spReg &= ~spReg;
14742 +
14743 + p_HcFrame->actionReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
14744 +
14745 + BUILD_FD(sizeof(t_HcFrame));
14746 +
14747 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14748 +
14749 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14750 +
14751 + if (err != E_OK)
14752 + RETURN_ERROR(MINOR, err, NO_MSG);
14753 +
14754 + return E_OK;
14755 +}
14756 +
14757 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg)
14758 +{
14759 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14760 + t_HcFrame *p_HcFrame;
14761 + t_DpaaFD fmFd;
14762 + t_Error err = E_OK;
14763 + uint32_t seqNum;
14764 +
14765 + ASSERT_COND(p_FmHc);
14766 +
14767 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14768 + if (!p_HcFrame)
14769 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14770 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14771 + /* first read SP register */
14772 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14773 + p_HcFrame->actionReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
14774 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14775 + p_HcFrame->hcSpecificData.singleRegForWrite = cppReg;
14776 + p_HcFrame->commandSequence = seqNum;
14777 +
14778 + BUILD_FD(sizeof(t_HcFrame));
14779 +
14780 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14781 +
14782 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14783 +
14784 + if (err != E_OK)
14785 + RETURN_ERROR(MINOR, err, NO_MSG);
14786 +
14787 + return E_OK;
14788 +}
14789 +
14790 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset)
14791 +{
14792 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14793 + t_HcFrame *p_HcFrame;
14794 + t_DpaaFD fmFd;
14795 + t_Error err = E_OK;
14796 + uint32_t seqNum;
14797 +
14798 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
14799 +
14800 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14801 + if (!p_HcFrame)
14802 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14803 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14804 +
14805 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC);
14806 + p_HcFrame->actionReg = newAdAddrOffset;
14807 + p_HcFrame->actionReg |= 0xc0000000;
14808 + p_HcFrame->extraReg = oldAdAddrOffset;
14809 + p_HcFrame->commandSequence = seqNum;
14810 +
14811 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14812 +
14813 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14814 +
14815 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14816 +
14817 + if (err != E_OK)
14818 + RETURN_ERROR(MAJOR, err, NO_MSG);
14819 +
14820 + return E_OK;
14821 +}
14822 +
14823 +t_Error FmHcPcdSync(t_Handle h_FmHc)
14824 +{
14825 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14826 + t_HcFrame *p_HcFrame;
14827 + t_DpaaFD fmFd;
14828 + t_Error err = E_OK;
14829 + uint32_t seqNum;
14830 +
14831 + ASSERT_COND(p_FmHc);
14832 +
14833 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14834 + if (!p_HcFrame)
14835 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14836 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14837 + /* first read SP register */
14838 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_SYNC);
14839 + p_HcFrame->actionReg = 0;
14840 + p_HcFrame->extraReg = 0;
14841 + p_HcFrame->commandSequence = seqNum;
14842 +
14843 + BUILD_FD(sizeof(t_HcFrame));
14844 +
14845 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14846 +
14847 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14848 +
14849 + if (err != E_OK)
14850 + RETURN_ERROR(MINOR, err, NO_MSG);
14851 +
14852 + return E_OK;
14853 +}
14854 +
14855 +t_Handle FmHcGetPort(t_Handle h_FmHc)
14856 +{
14857 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14858 + return p_FmHc->h_HcPortDev;
14859 +}
14860 --- /dev/null
14861 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
14862 @@ -0,0 +1,28 @@
14863 +#
14864 +# Makefile for the Freescale Ethernet controllers
14865 +#
14866 +ccflags-y += -DVERSION=\"\"
14867 +#
14868 +#Include netcomm SW specific definitions
14869 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
14870 +
14871 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
14872 +
14873 +ccflags-y += -I$(NCSW_FM_INC)
14874 +
14875 +obj-y += fsl-ncsw-MAC.o
14876 +
14877 +fsl-ncsw-MAC-objs := dtsec.o dtsec_mii_acc.o fm_mac.o tgec.o tgec_mii_acc.o \
14878 + fman_dtsec.o fman_dtsec_mii_acc.o fman_memac.o \
14879 + fman_tgec.o fman_crc32.o
14880 +
14881 +ifeq ($(CONFIG_FMAN_V3H),y)
14882 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14883 +endif
14884 +ifeq ($(CONFIG_FMAN_V3L),y)
14885 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14886 +endif
14887 +ifeq ($(CONFIG_FMAN_ARM),y)
14888 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14889 +endif
14890 +
14891 --- /dev/null
14892 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
14893 @@ -0,0 +1,1465 @@
14894 +/*
14895 + * Copyright 2008-2013 Freescale Semiconductor Inc.
14896 + *
14897 + * Redistribution and use in source and binary forms, with or without
14898 + * modification, are permitted provided that the following conditions are met:
14899 + * * Redistributions of source code must retain the above copyright
14900 + * notice, this list of conditions and the following disclaimer.
14901 + * * Redistributions in binary form must reproduce the above copyright
14902 + * notice, this list of conditions and the following disclaimer in the
14903 + * documentation and/or other materials provided with the distribution.
14904 + * * Neither the name of Freescale Semiconductor nor the
14905 + * names of its contributors may be used to endorse or promote products
14906 + * derived from this software without specific prior written permission.
14907 + *
14908 + *
14909 + * ALTERNATIVELY, this software may be distributed under the terms of the
14910 + * GNU General Public License ("GPL") as published by the Free Software
14911 + * Foundation, either version 2 of that License or (at your option) any
14912 + * later version.
14913 + *
14914 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
14915 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14916 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14917 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
14918 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14919 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14920 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14921 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14922 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14923 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14924 + */
14925 +
14926 +/******************************************************************************
14927 + @File dtsec.c
14928 +
14929 + @Description FMan dTSEC driver
14930 +*//***************************************************************************/
14931 +
14932 +#include "std_ext.h"
14933 +#include "error_ext.h"
14934 +#include "string_ext.h"
14935 +#include "xx_ext.h"
14936 +#include "endian_ext.h"
14937 +#include "debug_ext.h"
14938 +#include "crc_mac_addr_ext.h"
14939 +
14940 +#include "fm_common.h"
14941 +#include "dtsec.h"
14942 +#include "fsl_fman_dtsec.h"
14943 +#include "fsl_fman_dtsec_mii_acc.h"
14944 +
14945 +/*****************************************************************************/
14946 +/* Internal routines */
14947 +/*****************************************************************************/
14948 +
14949 +static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
14950 +{
14951 + if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
14952 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
14953 + if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
14954 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
14955 + if (p_Dtsec->addr == 0)
14956 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
14957 + if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) &&
14958 + p_Dtsec->p_DtsecDriverParam->halfdup_on)
14959 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
14960 + if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback)
14961 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
14962 +#ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001
14963 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */
14964 + if (p_Dtsec->p_DtsecDriverParam->rx_preamble)
14965 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
14966 +#endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */
14967 + if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7))
14968 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
14969 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on &&
14970 + (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en))
14971 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
14972 + if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc )
14973 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
14974 + if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend > MAX_PACKET_ALIGNMENT)
14975 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
14976 + if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1 > MAX_INTER_PACKET_GAP) ||
14977 + ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) ||
14978 + ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP))
14979 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
14980 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB)
14981 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
14982 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION)
14983 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
14984 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW)
14985 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
14986 +
14987 + /* If Auto negotiation process is disabled, need to */
14988 + /* Set up the PHY using the MII Management Interface */
14989 + if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS)
14990 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
14991 + if (!p_Dtsec->f_Exception)
14992 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
14993 + if (!p_Dtsec->f_Event)
14994 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
14995 +
14996 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
14997 + if (p_Dtsec->p_DtsecDriverParam->rx_len_check)
14998 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
14999 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
15000 +
15001 + return E_OK;
15002 +}
15003 +
15004 +/* ......................................................................... */
15005 +
15006 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
15007 +{
15008 + uint32_t crc;
15009 +
15010 + /* CRC calculation */
15011 + GET_MAC_ADDR_CRC(ethAddr, crc);
15012 +
15013 + crc = GetMirror32(crc);
15014 +
15015 + return crc;
15016 +}
15017 +
15018 +/* ......................................................................... */
15019 +
15020 +static void UpdateStatistics(t_Dtsec *p_Dtsec)
15021 +{
15022 + uint32_t car1, car2;
15023 +
15024 + fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2);
15025 +
15026 + if (car1)
15027 + {
15028 + if (car1 & CAR1_TR64)
15029 + p_Dtsec->internalStatistics.tr64 += VAL22BIT;
15030 + if (car1 & CAR1_TR127)
15031 + p_Dtsec->internalStatistics.tr127 += VAL22BIT;
15032 + if (car1 & CAR1_TR255)
15033 + p_Dtsec->internalStatistics.tr255 += VAL22BIT;
15034 + if (car1 & CAR1_TR511)
15035 + p_Dtsec->internalStatistics.tr511 += VAL22BIT;
15036 + if (car1 & CAR1_TRK1)
15037 + p_Dtsec->internalStatistics.tr1k += VAL22BIT;
15038 + if (car1 & CAR1_TRMAX)
15039 + p_Dtsec->internalStatistics.trmax += VAL22BIT;
15040 + if (car1 & CAR1_TRMGV)
15041 + p_Dtsec->internalStatistics.trmgv += VAL22BIT;
15042 + if (car1 & CAR1_RBYT)
15043 + p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
15044 + if (car1 & CAR1_RPKT)
15045 + p_Dtsec->internalStatistics.rpkt += VAL22BIT;
15046 + if (car1 & CAR1_RMCA)
15047 + p_Dtsec->internalStatistics.rmca += VAL22BIT;
15048 + if (car1 & CAR1_RBCA)
15049 + p_Dtsec->internalStatistics.rbca += VAL22BIT;
15050 + if (car1 & CAR1_RXPF)
15051 + p_Dtsec->internalStatistics.rxpf += VAL16BIT;
15052 + if (car1 & CAR1_RALN)
15053 + p_Dtsec->internalStatistics.raln += VAL16BIT;
15054 + if (car1 & CAR1_RFLR)
15055 + p_Dtsec->internalStatistics.rflr += VAL16BIT;
15056 + if (car1 & CAR1_RCDE)
15057 + p_Dtsec->internalStatistics.rcde += VAL16BIT;
15058 + if (car1 & CAR1_RCSE)
15059 + p_Dtsec->internalStatistics.rcse += VAL16BIT;
15060 + if (car1 & CAR1_RUND)
15061 + p_Dtsec->internalStatistics.rund += VAL16BIT;
15062 + if (car1 & CAR1_ROVR)
15063 + p_Dtsec->internalStatistics.rovr += VAL16BIT;
15064 + if (car1 & CAR1_RFRG)
15065 + p_Dtsec->internalStatistics.rfrg += VAL16BIT;
15066 + if (car1 & CAR1_RJBR)
15067 + p_Dtsec->internalStatistics.rjbr += VAL16BIT;
15068 + if (car1 & CAR1_RDRP)
15069 + p_Dtsec->internalStatistics.rdrp += VAL16BIT;
15070 + }
15071 + if (car2)
15072 + {
15073 + if (car2 & CAR2_TFCS)
15074 + p_Dtsec->internalStatistics.tfcs += VAL12BIT;
15075 + if (car2 & CAR2_TBYT)
15076 + p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
15077 + if (car2 & CAR2_TPKT)
15078 + p_Dtsec->internalStatistics.tpkt += VAL22BIT;
15079 + if (car2 & CAR2_TMCA)
15080 + p_Dtsec->internalStatistics.tmca += VAL22BIT;
15081 + if (car2 & CAR2_TBCA)
15082 + p_Dtsec->internalStatistics.tbca += VAL22BIT;
15083 + if (car2 & CAR2_TXPF)
15084 + p_Dtsec->internalStatistics.txpf += VAL16BIT;
15085 + if (car2 & CAR2_TDRP)
15086 + p_Dtsec->internalStatistics.tdrp += VAL16BIT;
15087 + }
15088 +}
15089 +
15090 +/* .............................................................................. */
15091 +
15092 +static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
15093 +{
15094 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15095 +
15096 + SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
15097 + SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0);
15098 +
15099 + return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
15100 +}
15101 +
15102 +/* .............................................................................. */
15103 +
15104 +static void DtsecIsr(t_Handle h_Dtsec)
15105 +{
15106 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15107 + uint32_t event;
15108 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15109 +
15110 + /* do not handle MDIO events */
15111 + event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN)));
15112 +
15113 + event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap);
15114 +
15115 + fman_dtsec_ack_event(p_DtsecMemMap, event);
15116 +
15117 + if (event & DTSEC_IMASK_BREN)
15118 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
15119 + if (event & DTSEC_IMASK_RXCEN)
15120 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
15121 + if (event & DTSEC_IMASK_MSROEN)
15122 + UpdateStatistics(p_Dtsec);
15123 + if (event & DTSEC_IMASK_GTSCEN)
15124 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
15125 + if (event & DTSEC_IMASK_BTEN)
15126 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
15127 + if (event & DTSEC_IMASK_TXCEN)
15128 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
15129 + if (event & DTSEC_IMASK_TXEEN)
15130 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
15131 + if (event & DTSEC_IMASK_LCEN)
15132 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
15133 + if (event & DTSEC_IMASK_CRLEN)
15134 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
15135 + if (event & DTSEC_IMASK_XFUNEN)
15136 + {
15137 +#ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
15138 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15139 + {
15140 + uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i;
15141 + /* a. Write 0x00E0_0C00 to DTSEC_ID */
15142 + /* This is a read only regidter */
15143 +
15144 + /* b. Read and save the value of TPKT */
15145 + tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
15146 +
15147 + /* c. Read the register at dTSEC address offset 0x32C */
15148 + tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15149 +
15150 + /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
15151 + if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
15152 + {
15153 + /* If they are not equal, save the value of this register and wait for at least
15154 + * MAXFRM*16 ns */
15155 + XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
15156 + }
15157 +
15158 + /* e. Read and save TPKT again and read the register at dTSEC address offset
15159 + 0x32C again*/
15160 + tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
15161 + tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15162 +
15163 + /* f. Compare the value of TPKT saved in step b to value read in step e. Also
15164 + compare bits [9:15] of the register at offset 0x32C saved in step d to the value
15165 + of bits [9:15] saved in step e. If the two registers values are unchanged, then
15166 + the transmit portion of the dTSEC controller is locked up and the user should
15167 + proceed to the recover sequence. */
15168 + if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
15169 + {
15170 + /* recover sequence */
15171 +
15172 + /* a.Write a 1 to RCTRL[GRS]*/
15173 +
15174 + WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
15175 +
15176 + /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
15177 + for (i = 0 ; i < 100 ; i++ )
15178 + {
15179 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15180 + break;
15181 + XX_UDelay(1);
15182 + }
15183 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15184 + WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN);
15185 + else
15186 + DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
15187 +
15188 + /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
15189 + FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
15190 +
15191 + /* d.Wait 4 Tx clocks (32 ns) */
15192 + XX_UDelay(1);
15193 +
15194 + /* e.Write a 0 to bit n of FM_RSTC. */
15195 + /* cleared by FMAN */
15196 + }
15197 + }
15198 +#endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
15199 +
15200 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
15201 + }
15202 + if (event & DTSEC_IMASK_MAGEN)
15203 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
15204 + if (event & DTSEC_IMASK_GRSCEN)
15205 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
15206 + if (event & DTSEC_IMASK_TDPEEN)
15207 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
15208 + if (event & DTSEC_IMASK_RDPEEN)
15209 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
15210 +
15211 + /* - masked interrupts */
15212 + ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN));
15213 + ASSERT_COND(!(event & DTSEC_IMASK_IFERREN));
15214 +}
15215 +
15216 +static void DtsecMdioIsr(t_Handle h_Dtsec)
15217 +{
15218 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15219 + uint32_t event;
15220 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15221 +
15222 + event = GET_UINT32(p_DtsecMemMap->ievent);
15223 + /* handle only MDIO events */
15224 + event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN);
15225 + if (event)
15226 + {
15227 + event &= GET_UINT32(p_DtsecMemMap->imask);
15228 +
15229 + WRITE_UINT32(p_DtsecMemMap->ievent, event);
15230 +
15231 + if (event & DTSEC_IMASK_MMRDEN)
15232 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
15233 + if (event & DTSEC_IMASK_MMWREN)
15234 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
15235 + }
15236 +}
15237 +
15238 +static void Dtsec1588Isr(t_Handle h_Dtsec)
15239 +{
15240 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15241 + uint32_t event;
15242 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15243 +
15244 + if (p_Dtsec->ptpTsuEnabled)
15245 + {
15246 + event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap);
15247 +
15248 + if (event)
15249 + {
15250 + ASSERT_COND(event & TMR_PEVENT_TSRE);
15251 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
15252 + }
15253 + }
15254 +}
15255 +
15256 +/* ........................................................................... */
15257 +
15258 +static void FreeInitResources(t_Dtsec *p_Dtsec)
15259 +{
15260 + if (p_Dtsec->mdioIrq != NO_IRQ)
15261 + {
15262 + XX_DisableIntr(p_Dtsec->mdioIrq);
15263 + XX_FreeIntr(p_Dtsec->mdioIrq);
15264 + }
15265 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
15266 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
15267 +
15268 + /* release the driver's group hash table */
15269 + FreeHashTable(p_Dtsec->p_MulticastAddrHash);
15270 + p_Dtsec->p_MulticastAddrHash = NULL;
15271 +
15272 + /* release the driver's individual hash table */
15273 + FreeHashTable(p_Dtsec->p_UnicastAddrHash);
15274 + p_Dtsec->p_UnicastAddrHash = NULL;
15275 +}
15276 +
15277 +/* ........................................................................... */
15278 +
15279 +static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
15280 +{
15281 + struct dtsec_regs *p_MemMap;
15282 +
15283 + ASSERT_COND(p_Dtsec);
15284 +
15285 + p_MemMap = p_Dtsec->p_MemMap;
15286 + ASSERT_COND(p_MemMap);
15287 +
15288 + /* Assert the graceful transmit stop bit */
15289 + if (mode & e_COMM_MODE_RX)
15290 + {
15291 + fman_dtsec_stop_rx(p_MemMap);
15292 +
15293 +#ifdef FM_GRS_ERRATA_DTSEC_A002
15294 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15295 + XX_UDelay(100);
15296 +#else /* FM_GRS_ERRATA_DTSEC_A002 */
15297 +#ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
15298 + XX_UDelay(10);
15299 +#endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */
15300 +#endif /* FM_GRS_ERRATA_DTSEC_A002 */
15301 + }
15302 +
15303 + if (mode & e_COMM_MODE_TX)
15304 +#if defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012)
15305 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15306 + DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
15307 +#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
15308 +#ifdef FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
15309 + DBG(INFO, ("GTS not supported due to DTSEC_A0014 errata."));
15310 +#else /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
15311 + fman_dtsec_stop_tx(p_MemMap);
15312 +#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
15313 +#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
15314 +
15315 + return E_OK;
15316 +}
15317 +
15318 +/* .............................................................................. */
15319 +
15320 +static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
15321 +{
15322 + struct dtsec_regs *p_MemMap;
15323 +
15324 + ASSERT_COND(p_Dtsec);
15325 + p_MemMap = p_Dtsec->p_MemMap;
15326 + ASSERT_COND(p_MemMap);
15327 +
15328 + /* clear the graceful receive stop bit */
15329 + if (mode & e_COMM_MODE_TX)
15330 + fman_dtsec_start_tx(p_MemMap);
15331 +
15332 + if (mode & e_COMM_MODE_RX)
15333 + fman_dtsec_start_rx(p_MemMap);
15334 +
15335 + return E_OK;
15336 +}
15337 +
15338 +
15339 +/*****************************************************************************/
15340 +/* dTSEC Configs modification functions */
15341 +/*****************************************************************************/
15342 +
15343 +/* .............................................................................. */
15344 +
15345 +static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
15346 +{
15347 +
15348 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15349 +
15350 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15351 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15352 +
15353 + p_Dtsec->p_DtsecDriverParam->loopback = newVal;
15354 +
15355 + return E_OK;
15356 +}
15357 +
15358 +/* .............................................................................. */
15359 +
15360 +static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
15361 +{
15362 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15363 +
15364 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15365 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15366 +
15367 + p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal;
15368 +
15369 + return E_OK;
15370 +}
15371 +
15372 +/* .............................................................................. */
15373 +
15374 +static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
15375 +{
15376 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15377 +
15378 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15379 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15380 +
15381 + p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal;
15382 +
15383 + return E_OK;
15384 +}
15385 +
15386 +/* .............................................................................. */
15387 +
15388 +static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
15389 +{
15390 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15391 +
15392 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15393 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15394 +
15395 + p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal;
15396 +
15397 + return E_OK;
15398 +}
15399 +
15400 +/* .............................................................................. */
15401 +
15402 +static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal)
15403 +{
15404 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15405 +
15406 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15407 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15408 +
15409 + p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal;
15410 +
15411 + return E_OK;
15412 +}
15413 +
15414 +/* .............................................................................. */
15415 +
15416 +static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
15417 +{
15418 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15419 +
15420 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15421 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15422 +
15423 + p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal;
15424 +
15425 + return E_OK;
15426 +}
15427 +
15428 +/* .............................................................................. */
15429 +
15430 +static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
15431 +{
15432 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15433 + uint32_t bitMask = 0;
15434 +
15435 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15436 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15437 +
15438 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
15439 + {
15440 + GET_EXCEPTION_FLAG(bitMask, exception);
15441 + if (bitMask)
15442 + {
15443 + if (enable)
15444 + p_Dtsec->exceptions |= bitMask;
15445 + else
15446 + p_Dtsec->exceptions &= ~bitMask;
15447 + }
15448 + else
15449 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
15450 + }
15451 + else
15452 + {
15453 + if (!p_Dtsec->ptpTsuEnabled)
15454 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
15455 +
15456 + if (enable)
15457 + p_Dtsec->enTsuErrExeption = TRUE;
15458 + else
15459 + p_Dtsec->enTsuErrExeption = FALSE;
15460 + }
15461 +
15462 + return E_OK;
15463 +}
15464 +
15465 +
15466 +/*****************************************************************************/
15467 +/* dTSEC Run Time API functions */
15468 +/*****************************************************************************/
15469 +
15470 +/* .............................................................................. */
15471 +
15472 +static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode)
15473 +{
15474 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15475 +
15476 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15477 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15478 +
15479 + fman_dtsec_enable(p_Dtsec->p_MemMap,
15480 + (bool)!!(mode & e_COMM_MODE_RX),
15481 + (bool)!!(mode & e_COMM_MODE_TX));
15482 +
15483 + GracefulRestart(p_Dtsec, mode);
15484 +
15485 + return E_OK;
15486 +}
15487 +
15488 +/* .............................................................................. */
15489 +
15490 +static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
15491 +{
15492 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15493 +
15494 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15495 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15496 +
15497 + GracefulStop(p_Dtsec, mode);
15498 +
15499 + fman_dtsec_disable(p_Dtsec->p_MemMap,
15500 + (bool)!!(mode & e_COMM_MODE_RX),
15501 + (bool)!!(mode & e_COMM_MODE_TX));
15502 +
15503 + return E_OK;
15504 +}
15505 +
15506 +/* .............................................................................. */
15507 +
15508 +static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec,
15509 + uint8_t priority,
15510 + uint16_t pauseTime,
15511 + uint16_t threshTime)
15512 +{
15513 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15514 +
15515 + UNUSED(priority);UNUSED(threshTime);
15516 +
15517 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15518 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15519 +
15520 +#ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
15521 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15522 + if (0 < pauseTime && pauseTime <= 320)
15523 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
15524 + ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
15525 + " value should be greater than 320."));
15526 +#endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
15527 +
15528 + fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime);
15529 + return E_OK;
15530 +}
15531 +
15532 +/* .............................................................................. */
15533 +/* backward compatibility. will be removed in the future. */
15534 +static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
15535 +{
15536 + return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0);
15537 +}
15538 +
15539 +/* .............................................................................. */
15540 +
15541 +static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
15542 +{
15543 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15544 + bool accept_pause = !en;
15545 +
15546 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15547 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15548 +
15549 + fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause);
15550 +
15551 + return E_OK;
15552 +}
15553 +
15554 +/* .............................................................................. */
15555 +
15556 +static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
15557 +{
15558 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15559 +
15560 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15561 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15562 +
15563 + p_Dtsec->ptpTsuEnabled = TRUE;
15564 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE);
15565 +
15566 + return E_OK;
15567 +}
15568 +
15569 +/* .............................................................................. */
15570 +
15571 +static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
15572 +{
15573 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15574 +
15575 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15576 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15577 +
15578 + p_Dtsec->ptpTsuEnabled = FALSE;
15579 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE);
15580 +
15581 + return E_OK;
15582 +}
15583 +
15584 +/* .............................................................................. */
15585 +
15586 +static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
15587 +{
15588 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15589 + struct dtsec_regs *p_DtsecMemMap;
15590 +
15591 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15592 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15593 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
15594 +
15595 + p_DtsecMemMap = p_Dtsec->p_MemMap;
15596 +
15597 + if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
15598 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
15599 +
15600 + memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
15601 +
15602 + if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
15603 + {
15604 + p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64)
15605 + + p_Dtsec->internalStatistics.tr64;
15606 + p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127)
15607 + + p_Dtsec->internalStatistics.tr127;
15608 + p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255)
15609 + + p_Dtsec->internalStatistics.tr255;
15610 + p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511)
15611 + + p_Dtsec->internalStatistics.tr511;
15612 + p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K)
15613 + + p_Dtsec->internalStatistics.tr1k;
15614 + p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX)
15615 + + p_Dtsec->internalStatistics.trmax;
15616 + p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV)
15617 + + p_Dtsec->internalStatistics.trmgv;
15618 +
15619 + /* MIB II */
15620 + p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT)
15621 + + p_Dtsec->internalStatistics.rbyt;
15622 + p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT)
15623 + + p_Dtsec->internalStatistics.rpkt;
15624 + p_Statistics->ifInUcastPkts = 0;
15625 + p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA)
15626 + + p_Dtsec->internalStatistics.rmca;
15627 + p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA)
15628 + + p_Dtsec->internalStatistics.rbca;
15629 + p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT)
15630 + + p_Dtsec->internalStatistics.tbyt;
15631 + p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT)
15632 + + p_Dtsec->internalStatistics.tpkt;
15633 + p_Statistics->ifOutUcastPkts = 0;
15634 + p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA)
15635 + + p_Dtsec->internalStatistics.tmca;
15636 + p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA)
15637 + + p_Dtsec->internalStatistics.tbca;
15638 + }
15639 +
15640 + p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG)
15641 + + p_Dtsec->internalStatistics.rfrg;
15642 + p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR)
15643 + + p_Dtsec->internalStatistics.rjbr;
15644 + p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP)
15645 + + p_Dtsec->internalStatistics.rdrp;
15646 + p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN)
15647 + + p_Dtsec->internalStatistics.raln;
15648 + p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND)
15649 + + p_Dtsec->internalStatistics.rund;
15650 + p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR)
15651 + + p_Dtsec->internalStatistics.rovr;
15652 + p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF)
15653 + + p_Dtsec->internalStatistics.rxpf;
15654 + p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF)
15655 + + p_Dtsec->internalStatistics.txpf;
15656 + p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents;
15657 + p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors
15658 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr
15659 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde
15660 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse;
15661 +
15662 + p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP)
15663 + + p_Dtsec->internalStatistics.tdrp;
15664 + p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */
15665 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS)
15666 + + p_Dtsec->internalStatistics.tfcs;
15667 +
15668 + return E_OK;
15669 +}
15670 +
15671 +/* .............................................................................. */
15672 +
15673 +static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
15674 +{
15675 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15676 +
15677 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15678 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15679 +
15680 + /* Initialize MAC Station Address registers (1 & 2) */
15681 + /* Station address have to be swapped (big endian to little endian */
15682 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
15683 + fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr));
15684 +
15685 + return E_OK;
15686 +}
15687 +
15688 +/* .............................................................................. */
15689 +
15690 +static t_Error DtsecResetCounters (t_Handle h_Dtsec)
15691 +{
15692 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15693 +
15694 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15695 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15696 +
15697 + /* clear HW counters */
15698 + fman_dtsec_reset_stat(p_Dtsec->p_MemMap);
15699 +
15700 + /* clear SW counters holding carries */
15701 + memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics));
15702 +
15703 + return E_OK;
15704 +}
15705 +
15706 +/* .............................................................................. */
15707 +
15708 +static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15709 +{
15710 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15711 + uint64_t ethAddr;
15712 + uint8_t paddrNum;
15713 +
15714 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15715 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15716 +
15717 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15718 +
15719 + if (ethAddr & GROUP_ADDRESS)
15720 + /* Multicast address has no effect in PADDR */
15721 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
15722 +
15723 + /* Make sure no PADDR contains this address */
15724 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15725 + if (p_Dtsec->indAddrRegUsed[paddrNum])
15726 + if (p_Dtsec->paddr[paddrNum] == ethAddr)
15727 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
15728 +
15729 + /* Find first unused PADDR */
15730 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15731 + if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
15732 + {
15733 + /* mark this PADDR as used */
15734 + p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
15735 + /* store address */
15736 + p_Dtsec->paddr[paddrNum] = ethAddr;
15737 +
15738 + /* put in hardware */
15739 + fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(&ethAddr), paddrNum);
15740 + p_Dtsec->numOfIndAddrInRegs++;
15741 +
15742 + return E_OK;
15743 + }
15744 +
15745 + /* No free PADDR */
15746 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
15747 +}
15748 +
15749 +/* .............................................................................. */
15750 +
15751 +static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15752 +{
15753 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15754 + uint64_t ethAddr;
15755 + uint8_t paddrNum;
15756 +
15757 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15758 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15759 +
15760 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15761 +
15762 + /* Find used PADDR containing this address */
15763 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15764 + {
15765 + if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
15766 + (p_Dtsec->paddr[paddrNum] == ethAddr))
15767 + {
15768 + /* mark this PADDR as not used */
15769 + p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
15770 + /* clear in hardware */
15771 + fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum);
15772 + p_Dtsec->numOfIndAddrInRegs--;
15773 +
15774 + return E_OK;
15775 + }
15776 + }
15777 +
15778 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
15779 +}
15780 +
15781 +/* .............................................................................. */
15782 +
15783 +static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15784 +{
15785 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15786 + t_EthHashEntry *p_HashEntry;
15787 + uint64_t ethAddr;
15788 + int32_t bucket;
15789 + uint32_t crc;
15790 + bool mcast, ghtx;
15791 +
15792 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15793 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15794 +
15795 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15796 +
15797 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
15798 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
15799 +
15800 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
15801 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
15802 +
15803 + crc = GetMacAddrHashCode(ethAddr);
15804 +
15805 + /* considering the 9 highest order bits in crc H[8:0]:
15806 + * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register
15807 + * and H[5:1] (next 5 bits) identify the hash bit
15808 + * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register
15809 + * and H[4:0] (next 5 bits) identify the hash bit.
15810 + *
15811 + * In bucket index output the low 5 bits identify the hash register bit,
15812 + * while the higher 4 bits identify the hash register
15813 + */
15814 +
15815 + if (ghtx)
15816 + bucket = (int32_t)((crc >> 23) & 0x1ff);
15817 + else {
15818 + bucket = (int32_t)((crc >> 24) & 0xff);
15819 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
15820 + if (mcast)
15821 + bucket += 0x100;
15822 + }
15823 +
15824 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE);
15825 +
15826 + /* Create element to be added to the driver hash table */
15827 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
15828 + p_HashEntry->addr = ethAddr;
15829 + INIT_LIST(&p_HashEntry->node);
15830 +
15831 + if (ethAddr & MAC_GROUP_ADDRESS)
15832 + /* Group Address */
15833 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]));
15834 + else
15835 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]));
15836 +
15837 + return E_OK;
15838 +}
15839 +
15840 +/* .............................................................................. */
15841 +
15842 +static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15843 +{
15844 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15845 + t_List *p_Pos;
15846 + t_EthHashEntry *p_HashEntry = NULL;
15847 + uint64_t ethAddr;
15848 + int32_t bucket;
15849 + uint32_t crc;
15850 + bool mcast, ghtx;
15851 +
15852 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15853 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15854 +
15855 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15856 +
15857 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
15858 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
15859 +
15860 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
15861 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
15862 +
15863 + crc = GetMacAddrHashCode(ethAddr);
15864 +
15865 + if (ghtx)
15866 + bucket = (int32_t)((crc >> 23) & 0x1ff);
15867 + else {
15868 + bucket = (int32_t)((crc >> 24) & 0xff);
15869 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
15870 + if (mcast)
15871 + bucket += 0x100;
15872 + }
15873 +
15874 + if (ethAddr & MAC_GROUP_ADDRESS)
15875 + {
15876 + /* Group Address */
15877 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
15878 + {
15879 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
15880 + if (p_HashEntry->addr == ethAddr)
15881 + {
15882 + LIST_DelAndInit(&p_HashEntry->node);
15883 + XX_Free(p_HashEntry);
15884 + break;
15885 + }
15886 + }
15887 + if (LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
15888 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
15889 + }
15890 + else
15891 + {
15892 + /* Individual Address */
15893 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
15894 + {
15895 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
15896 + if (p_HashEntry->addr == ethAddr)
15897 + {
15898 + LIST_DelAndInit(&p_HashEntry->node);
15899 + XX_Free(p_HashEntry);
15900 + break;
15901 + }
15902 + }
15903 + if (LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
15904 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
15905 + }
15906 +
15907 + /* address does not exist */
15908 + ASSERT_COND(p_HashEntry != NULL);
15909 +
15910 + return E_OK;
15911 +}
15912 +
15913 +/* .............................................................................. */
15914 +
15915 +static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
15916 +{
15917 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15918 +
15919 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15920 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15921 +
15922 + fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal);
15923 + fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal);
15924 +
15925 + return E_OK;
15926 +}
15927 +
15928 +/* .............................................................................. */
15929 +
15930 +static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
15931 +{
15932 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15933 + t_Error err;
15934 +
15935 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15936 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15937 +
15938 + p_Dtsec->statisticsLevel = statisticsLevel;
15939 +
15940 + err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap,
15941 + (enum dtsec_stat_level)statisticsLevel);
15942 + if (err != E_OK)
15943 + return err;
15944 +
15945 + switch (statisticsLevel)
15946 + {
15947 + case (e_FM_MAC_NONE_STATISTICS):
15948 + p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN;
15949 + break;
15950 + case (e_FM_MAC_PARTIAL_STATISTICS):
15951 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
15952 + break;
15953 + case (e_FM_MAC_FULL_STATISTICS):
15954 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
15955 + break;
15956 + default:
15957 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
15958 + }
15959 +
15960 + return E_OK;
15961 +}
15962 +
15963 +/* .............................................................................. */
15964 +
15965 +static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en)
15966 +{
15967 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15968 +
15969 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15970 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15971 +
15972 + fman_dtsec_set_wol(p_Dtsec->p_MemMap, en);
15973 +
15974 + return E_OK;
15975 +}
15976 +
15977 +/* .............................................................................. */
15978 +
15979 +static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
15980 +{
15981 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15982 + int err;
15983 + enum enet_interface enet_interface;
15984 + enum enet_speed enet_speed;
15985 +
15986 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15987 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15988 +
15989 + p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
15990 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
15991 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
15992 + p_Dtsec->halfDuplex = !fullDuplex;
15993 +
15994 + err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex);
15995 +
15996 + if (err == -EINVAL)
15997 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
15998 +
15999 + return (t_Error)err;
16000 +}
16001 +
16002 +/* .............................................................................. */
16003 +
16004 +static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec)
16005 +{
16006 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16007 + uint16_t tmpReg16;
16008 +
16009 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16010 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16011 +
16012 + DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16);
16013 +
16014 + tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 );
16015 + tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16016 +
16017 + DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16);
16018 +
16019 + return E_OK;
16020 +}
16021 +
16022 +/* .............................................................................. */
16023 +
16024 +static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
16025 +{
16026 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
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 + *macId = p_Dtsec->macId;
16032 +
16033 + return E_OK;
16034 +}
16035 +
16036 +/* .............................................................................. */
16037 +
16038 +static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
16039 +{
16040 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16041 +
16042 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16043 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16044 +
16045 + *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap);
16046 +
16047 + return E_OK;
16048 +}
16049 +
16050 +/* .............................................................................. */
16051 +
16052 +static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
16053 +{
16054 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16055 + uint32_t bitMask = 0;
16056 +
16057 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16058 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16059 +
16060 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
16061 + {
16062 + GET_EXCEPTION_FLAG(bitMask, exception);
16063 + if (bitMask)
16064 + {
16065 + if (enable)
16066 + p_Dtsec->exceptions |= bitMask;
16067 + else
16068 + p_Dtsec->exceptions &= ~bitMask;
16069 + }
16070 + else
16071 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
16072 +
16073 + if (enable)
16074 + fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask);
16075 + else
16076 + fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask);
16077 + }
16078 + else
16079 + {
16080 + if (!p_Dtsec->ptpTsuEnabled)
16081 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
16082 +
16083 + if (enable)
16084 + {
16085 + p_Dtsec->enTsuErrExeption = TRUE;
16086 + fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap);
16087 + }
16088 + else
16089 + {
16090 + p_Dtsec->enTsuErrExeption = FALSE;
16091 + fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap);
16092 + }
16093 + }
16094 +
16095 + return E_OK;
16096 +}
16097 +
16098 +
16099 +/*****************************************************************************/
16100 +/* dTSEC Init & Free API */
16101 +/*****************************************************************************/
16102 +
16103 +/* .............................................................................. */
16104 +
16105 +static t_Error DtsecInit(t_Handle h_Dtsec)
16106 +{
16107 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16108 + struct dtsec_cfg *p_DtsecDriverParam;
16109 + t_Error err;
16110 + uint16_t maxFrmLn;
16111 + enum enet_interface enet_interface;
16112 + enum enet_speed enet_speed;
16113 + t_EnetAddr ethAddr;
16114 +
16115 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16116 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16117 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
16118 +
16119 + FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo);
16120 + CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
16121 +
16122 + p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam;
16123 + p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on;
16124 +
16125 + enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
16126 + enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
16127 + MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr);
16128 +
16129 + err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap,
16130 + p_DtsecDriverParam,
16131 + enet_interface,
16132 + enet_speed,
16133 + (uint8_t*)ethAddr,
16134 + p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev,
16135 + p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev,
16136 + p_Dtsec->exceptions);
16137 + if (err)
16138 + {
16139 + FreeInitResources(p_Dtsec);
16140 + RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode"));
16141 + }
16142 +
16143 + if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII)
16144 + {
16145 + uint16_t tmpReg16;
16146 +
16147 + /* Configure the TBI PHY Control Register */
16148 + tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET;
16149 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16150 +
16151 + tmpReg16 = PHY_TBICON_CLK_SEL;
16152 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16153 +
16154 + tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16155 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16156 +
16157 + if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX)
16158 + tmpReg16 = PHY_TBIANA_1000X;
16159 + else
16160 + tmpReg16 = PHY_TBIANA_SGMII;
16161 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16);
16162 +
16163 + tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16164 +
16165 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16166 + }
16167 +
16168 + /* Max Frame Length */
16169 + maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
16170 + err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G,
16171 + p_Dtsec->fmMacControllerDriver.macId, maxFrmLn);
16172 + if (err)
16173 + RETURN_ERROR(MINOR,err, NO_MSG);
16174 +
16175 + p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE);
16176 + if (!p_Dtsec->p_MulticastAddrHash) {
16177 + FreeInitResources(p_Dtsec);
16178 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
16179 + }
16180 +
16181 + p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
16182 + if (!p_Dtsec->p_UnicastAddrHash)
16183 + {
16184 + FreeInitResources(p_Dtsec);
16185 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
16186 + }
16187 +
16188 + /* register err intr handler for dtsec to FPM (err)*/
16189 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16190 + e_FM_MOD_1G_MAC,
16191 + p_Dtsec->macId,
16192 + e_FM_INTR_TYPE_ERR,
16193 + DtsecIsr,
16194 + p_Dtsec);
16195 + /* register 1588 intr handler for TMR to FPM (normal)*/
16196 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16197 + e_FM_MOD_1G_MAC,
16198 + p_Dtsec->macId,
16199 + e_FM_INTR_TYPE_NORMAL,
16200 + Dtsec1588Isr,
16201 + p_Dtsec);
16202 + /* register normal intr handler for dtsec to main interrupt controller. */
16203 + if (p_Dtsec->mdioIrq != NO_IRQ)
16204 + {
16205 + XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec);
16206 + XX_EnableIntr(p_Dtsec->mdioIrq);
16207 + }
16208 +
16209 + XX_Free(p_DtsecDriverParam);
16210 + p_Dtsec->p_DtsecDriverParam = NULL;
16211 +
16212 + err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS);
16213 + if (err)
16214 + {
16215 + FreeInitResources(p_Dtsec);
16216 + RETURN_ERROR(MAJOR, err, ("Undefined statistics level"));
16217 + }
16218 +
16219 + return E_OK;
16220 +}
16221 +
16222 +/* ........................................................................... */
16223 +
16224 +static t_Error DtsecFree(t_Handle h_Dtsec)
16225 +{
16226 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16227 +
16228 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16229 +
16230 + if (p_Dtsec->p_DtsecDriverParam)
16231 + {
16232 + /* Called after config */
16233 + XX_Free(p_Dtsec->p_DtsecDriverParam);
16234 + p_Dtsec->p_DtsecDriverParam = NULL;
16235 + }
16236 + else
16237 + /* Called after init */
16238 + FreeInitResources(p_Dtsec);
16239 +
16240 + XX_Free(p_Dtsec);
16241 +
16242 + return E_OK;
16243 +}
16244 +
16245 +/* .............................................................................. */
16246 +
16247 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
16248 +{
16249 + p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit;
16250 + p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree;
16251 +
16252 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics;
16253 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback;
16254 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength;
16255 +
16256 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */
16257 +
16258 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc;
16259 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex;
16260 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck;
16261 + p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr = DtsecConfigTbiPhyAddr;
16262 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException;
16263 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
16264 +
16265 + p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable;
16266 + p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable;
16267 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
16268 +
16269 + p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException;
16270 +
16271 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous;
16272 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink;
16273 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = DtsecSetWakeOnLan;
16274 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = DtsecRestartAutoneg;
16275 +
16276 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp;
16277 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp;
16278 +
16279 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause;
16280 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = DtsecSetTxPauseFrames;
16281 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause;
16282 +
16283 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters;
16284 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics;
16285 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = NULL;
16286 +
16287 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress;
16288 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress;
16289 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress;
16290 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress;
16291 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress;
16292 + p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId;
16293 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion;
16294 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength;
16295 +
16296 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg;
16297 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg;
16298 +
16299 +}
16300 +
16301 +
16302 +/*****************************************************************************/
16303 +/* dTSEC Config Main Entry */
16304 +/*****************************************************************************/
16305 +
16306 +/* .............................................................................. */
16307 +
16308 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam)
16309 +{
16310 + t_Dtsec *p_Dtsec;
16311 + struct dtsec_cfg *p_DtsecDriverParam;
16312 + uintptr_t baseAddr;
16313 +
16314 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
16315 +
16316 + baseAddr = p_FmMacParam->baseAddr;
16317 +
16318 + /* allocate memory for the UCC GETH data structure. */
16319 + p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec));
16320 + if (!p_Dtsec)
16321 + {
16322 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
16323 + return NULL;
16324 + }
16325 + memset(p_Dtsec, 0, sizeof(t_Dtsec));
16326 + InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
16327 +
16328 + /* allocate memory for the dTSEC driver parameters data structure. */
16329 + p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg));
16330 + if (!p_DtsecDriverParam)
16331 + {
16332 + XX_Free(p_Dtsec);
16333 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
16334 + return NULL;
16335 + }
16336 + memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg));
16337 +
16338 + /* Plant parameter structure pointer */
16339 + p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
16340 +
16341 + fman_dtsec_defconfig(p_DtsecDriverParam);
16342 +
16343 + p_Dtsec->p_MemMap = (struct dtsec_regs *)UINT_TO_PTR(baseAddr);
16344 + p_Dtsec->p_MiiMemMap = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
16345 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
16346 + p_Dtsec->enetMode = p_FmMacParam->enetMode;
16347 + p_Dtsec->macId = p_FmMacParam->macId;
16348 + p_Dtsec->exceptions = DEFAULT_exceptions;
16349 + p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq;
16350 + p_Dtsec->f_Exception = p_FmMacParam->f_Exception;
16351 + p_Dtsec->f_Event = p_FmMacParam->f_Event;
16352 + p_Dtsec->h_App = p_FmMacParam->h_App;
16353 + p_Dtsec->ptpTsuEnabled = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en;
16354 + p_Dtsec->enTsuErrExeption = p_Dtsec->p_DtsecDriverParam->ptp_exception_en;
16355 + p_Dtsec->tbi_phy_addr = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr;
16356 +
16357 + return p_Dtsec;
16358 +}
16359 --- /dev/null
16360 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
16361 @@ -0,0 +1,228 @@
16362 +/*
16363 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16364 + *
16365 + * Redistribution and use in source and binary forms, with or without
16366 + * modification, are permitted provided that the following conditions are met:
16367 + * * Redistributions of source code must retain the above copyright
16368 + * notice, this list of conditions and the following disclaimer.
16369 + * * Redistributions in binary form must reproduce the above copyright
16370 + * notice, this list of conditions and the following disclaimer in the
16371 + * documentation and/or other materials provided with the distribution.
16372 + * * Neither the name of Freescale Semiconductor nor the
16373 + * names of its contributors may be used to endorse or promote products
16374 + * derived from this software without specific prior written permission.
16375 + *
16376 + *
16377 + * ALTERNATIVELY, this software may be distributed under the terms of the
16378 + * GNU General Public License ("GPL") as published by the Free Software
16379 + * Foundation, either version 2 of that License or (at your option) any
16380 + * later version.
16381 + *
16382 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16383 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16384 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16385 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16386 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16387 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16388 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16389 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16390 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16391 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16392 + */
16393 +
16394 +/******************************************************************************
16395 + @File dtsec.h
16396 +
16397 + @Description FM dTSEC ...
16398 +*//***************************************************************************/
16399 +#ifndef __DTSEC_H
16400 +#define __DTSEC_H
16401 +
16402 +#include "std_ext.h"
16403 +#include "error_ext.h"
16404 +#include "list_ext.h"
16405 +#include "enet_ext.h"
16406 +
16407 +#include "dtsec_mii_acc.h"
16408 +#include "fm_mac.h"
16409 +
16410 +
16411 +#define DEFAULT_exceptions \
16412 + ((uint32_t)(DTSEC_IMASK_BREN | \
16413 + DTSEC_IMASK_RXCEN | \
16414 + DTSEC_IMASK_BTEN | \
16415 + DTSEC_IMASK_TXCEN | \
16416 + DTSEC_IMASK_TXEEN | \
16417 + DTSEC_IMASK_ABRTEN | \
16418 + DTSEC_IMASK_LCEN | \
16419 + DTSEC_IMASK_CRLEN | \
16420 + DTSEC_IMASK_XFUNEN | \
16421 + DTSEC_IMASK_IFERREN | \
16422 + DTSEC_IMASK_MAGEN | \
16423 + DTSEC_IMASK_TDPEEN | \
16424 + DTSEC_IMASK_RDPEEN))
16425 +
16426 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
16427 + case e_FM_MAC_EX_1G_BAB_RX: \
16428 + bitMask = DTSEC_IMASK_BREN; break; \
16429 + case e_FM_MAC_EX_1G_RX_CTL: \
16430 + bitMask = DTSEC_IMASK_RXCEN; break; \
16431 + case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \
16432 + bitMask = DTSEC_IMASK_GTSCEN ; break; \
16433 + case e_FM_MAC_EX_1G_BAB_TX: \
16434 + bitMask = DTSEC_IMASK_BTEN ; break; \
16435 + case e_FM_MAC_EX_1G_TX_CTL: \
16436 + bitMask = DTSEC_IMASK_TXCEN ; break; \
16437 + case e_FM_MAC_EX_1G_TX_ERR: \
16438 + bitMask = DTSEC_IMASK_TXEEN ; break; \
16439 + case e_FM_MAC_EX_1G_LATE_COL: \
16440 + bitMask = DTSEC_IMASK_LCEN ; break; \
16441 + case e_FM_MAC_EX_1G_COL_RET_LMT: \
16442 + bitMask = DTSEC_IMASK_CRLEN ; break; \
16443 + case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \
16444 + bitMask = DTSEC_IMASK_XFUNEN ; break; \
16445 + case e_FM_MAC_EX_1G_MAG_PCKT: \
16446 + bitMask = DTSEC_IMASK_MAGEN ; break; \
16447 + case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \
16448 + bitMask = DTSEC_IMASK_MMRDEN; break; \
16449 + case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \
16450 + bitMask = DTSEC_IMASK_MMWREN ; break; \
16451 + case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \
16452 + bitMask = DTSEC_IMASK_GRSCEN; break; \
16453 + case e_FM_MAC_EX_1G_TX_DATA_ERR: \
16454 + bitMask = DTSEC_IMASK_TDPEEN; break; \
16455 + case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \
16456 + bitMask = DTSEC_IMASK_MSROEN ; break; \
16457 + default: bitMask = 0;break;}
16458 +
16459 +
16460 +#define MAX_PACKET_ALIGNMENT 31
16461 +#define MAX_INTER_PACKET_GAP 0x7f
16462 +#define MAX_INTER_PALTERNATE_BEB 0x0f
16463 +#define MAX_RETRANSMISSION 0x0f
16464 +#define MAX_COLLISION_WINDOW 0x03ff
16465 +
16466 +
16467 +/********************* From mac ext ******************************************/
16468 +typedef uint32_t t_ErrorDisable;
16469 +
16470 +#define ERROR_DISABLE_TRANSMIT 0x00400000
16471 +#define ERROR_DISABLE_LATE_COLLISION 0x00040000
16472 +#define ERROR_DISABLE_COLLISION_RETRY_LIMIT 0x00020000
16473 +#define ERROR_DISABLE_TxFIFO_UNDERRUN 0x00010000
16474 +#define ERROR_DISABLE_TxABORT 0x00008000
16475 +#define ERROR_DISABLE_INTERFACE 0x00004000
16476 +#define ERROR_DISABLE_TxDATA_PARITY 0x00000002
16477 +#define ERROR_DISABLE_RxDATA_PARITY 0x00000001
16478 +
16479 +/*****************************************************************************/
16480 +#define DTSEC_NUM_OF_PADDRS 15 /* number of pattern match registers (entries) */
16481 +
16482 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
16483 +
16484 +#define HASH_TABLE_SIZE 256 /* Hash table size (= 32 bits * 8 regs) */
16485 +
16486 +#define HASH_TABLE_SIZE 256 /* Hash table size (32 bits * 8 regs) */
16487 +#define EXTENDED_HASH_TABLE_SIZE 512 /* Extended Hash table size (32 bits * 16 regs) */
16488 +
16489 +#define DTSEC_TO_MII_OFFSET 0x1000 /* number of pattern match registers (entries) */
16490 +
16491 +#define MAX_PHYS 32 /* maximum number of phys */
16492 +
16493 +#define VAL32BIT 0x100000000LL
16494 +#define VAL22BIT 0x00400000
16495 +#define VAL16BIT 0x00010000
16496 +#define VAL12BIT 0x00001000
16497 +
16498 +/* CAR1/2 bits */
16499 +#define CAR1_TR64 0x80000000
16500 +#define CAR1_TR127 0x40000000
16501 +#define CAR1_TR255 0x20000000
16502 +#define CAR1_TR511 0x10000000
16503 +#define CAR1_TRK1 0x08000000
16504 +#define CAR1_TRMAX 0x04000000
16505 +#define CAR1_TRMGV 0x02000000
16506 +
16507 +#define CAR1_RBYT 0x00010000
16508 +#define CAR1_RPKT 0x00008000
16509 +#define CAR1_RMCA 0x00002000
16510 +#define CAR1_RBCA 0x00001000
16511 +#define CAR1_RXPF 0x00000400
16512 +#define CAR1_RALN 0x00000100
16513 +#define CAR1_RFLR 0x00000080
16514 +#define CAR1_RCDE 0x00000040
16515 +#define CAR1_RCSE 0x00000020
16516 +#define CAR1_RUND 0x00000010
16517 +#define CAR1_ROVR 0x00000008
16518 +#define CAR1_RFRG 0x00000004
16519 +#define CAR1_RJBR 0x00000002
16520 +#define CAR1_RDRP 0x00000001
16521 +
16522 +#define CAR2_TFCS 0x00040000
16523 +#define CAR2_TBYT 0x00002000
16524 +#define CAR2_TPKT 0x00001000
16525 +#define CAR2_TMCA 0x00000800
16526 +#define CAR2_TBCA 0x00000400
16527 +#define CAR2_TXPF 0x00000200
16528 +#define CAR2_TDRP 0x00000001
16529 +
16530 +typedef struct t_InternalStatistics
16531 +{
16532 + uint64_t tr64;
16533 + uint64_t tr127;
16534 + uint64_t tr255;
16535 + uint64_t tr511;
16536 + uint64_t tr1k;
16537 + uint64_t trmax;
16538 + uint64_t trmgv;
16539 + uint64_t rfrg;
16540 + uint64_t rjbr;
16541 + uint64_t rdrp;
16542 + uint64_t raln;
16543 + uint64_t rund;
16544 + uint64_t rovr;
16545 + uint64_t rxpf;
16546 + uint64_t txpf;
16547 + uint64_t rbyt;
16548 + uint64_t rpkt;
16549 + uint64_t rmca;
16550 + uint64_t rbca;
16551 + uint64_t rflr;
16552 + uint64_t rcde;
16553 + uint64_t rcse;
16554 + uint64_t tbyt;
16555 + uint64_t tpkt;
16556 + uint64_t tmca;
16557 + uint64_t tbca;
16558 + uint64_t tdrp;
16559 + uint64_t tfcs;
16560 +} t_InternalStatistics;
16561 +
16562 +typedef struct {
16563 + t_FmMacControllerDriver fmMacControllerDriver;
16564 + t_Handle h_App; /**< Handle to the upper layer application */
16565 + struct dtsec_regs *p_MemMap; /**< pointer to dTSEC memory mapped registers. */
16566 + struct dtsec_mii_reg *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */
16567 + uint64_t addr; /**< MAC address of device; */
16568 + e_EnetMode enetMode; /**< Ethernet physical interface */
16569 + t_FmMacExceptionCallback *f_Exception;
16570 + int mdioIrq;
16571 + t_FmMacExceptionCallback *f_Event;
16572 + bool indAddrRegUsed[DTSEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
16573 + uint64_t paddr[DTSEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
16574 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
16575 + bool halfDuplex;
16576 + t_InternalStatistics internalStatistics;
16577 + t_EthHash *p_MulticastAddrHash; /* pointer to driver's global address hash table */
16578 + t_EthHash *p_UnicastAddrHash; /* pointer to driver's individual address hash table */
16579 + uint8_t macId;
16580 + uint8_t tbi_phy_addr;
16581 + uint32_t exceptions;
16582 + bool ptpTsuEnabled;
16583 + bool enTsuErrExeption;
16584 + e_FmMacStatisticsLevel statisticsLevel;
16585 + struct dtsec_cfg *p_DtsecDriverParam;
16586 +} t_Dtsec;
16587 +
16588 +
16589 +#endif /* __DTSEC_H */
16590 --- /dev/null
16591 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
16592 @@ -0,0 +1,97 @@
16593 +/*
16594 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16595 + *
16596 + * Redistribution and use in source and binary forms, with or without
16597 + * modification, are permitted provided that the following conditions are met:
16598 + * * Redistributions of source code must retain the above copyright
16599 + * notice, this list of conditions and the following disclaimer.
16600 + * * Redistributions in binary form must reproduce the above copyright
16601 + * notice, this list of conditions and the following disclaimer in the
16602 + * documentation and/or other materials provided with the distribution.
16603 + * * Neither the name of Freescale Semiconductor nor the
16604 + * names of its contributors may be used to endorse or promote products
16605 + * derived from this software without specific prior written permission.
16606 + *
16607 + *
16608 + * ALTERNATIVELY, this software may be distributed under the terms of the
16609 + * GNU General Public License ("GPL") as published by the Free Software
16610 + * Foundation, either version 2 of that License or (at your option) any
16611 + * later version.
16612 + *
16613 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16614 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16615 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16616 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16617 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16618 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16619 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16620 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16621 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16622 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16623 + */
16624 +
16625 +
16626 +/******************************************************************************
16627 + @File dtsec_mii_acc.c
16628 +
16629 + @Description FM dtsec MII register access MAC ...
16630 +*//***************************************************************************/
16631 +
16632 +#include "error_ext.h"
16633 +#include "std_ext.h"
16634 +#include "fm_mac.h"
16635 +#include "dtsec.h"
16636 +#include "fsl_fman_dtsec_mii_acc.h"
16637 +
16638 +
16639 +/*****************************************************************************/
16640 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec,
16641 + uint8_t phyAddr,
16642 + uint8_t reg,
16643 + uint16_t data)
16644 +{
16645 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16646 + struct dtsec_mii_reg *miiregs;
16647 + uint16_t dtsec_freq;
16648 + t_Error err;
16649 +
16650 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16651 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16652 +
16653 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16654 + miiregs = p_Dtsec->p_MiiMemMap;
16655 +
16656 + err = (t_Error)fman_dtsec_mii_write_reg(miiregs, phyAddr, reg, data, dtsec_freq);
16657 +
16658 + return err;
16659 +}
16660 +
16661 +/*****************************************************************************/
16662 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec,
16663 + uint8_t phyAddr,
16664 + uint8_t reg,
16665 + uint16_t *p_Data)
16666 +{
16667 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16668 + struct dtsec_mii_reg *miiregs;
16669 + uint16_t dtsec_freq;
16670 + t_Error err;
16671 +
16672 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16673 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16674 +
16675 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16676 + miiregs = p_Dtsec->p_MiiMemMap;
16677 +
16678 + err = fman_dtsec_mii_read_reg(miiregs, phyAddr, reg, p_Data, dtsec_freq);
16679 +
16680 + if (*p_Data == 0xffff)
16681 + RETURN_ERROR(MINOR, E_NO_DEVICE,
16682 + ("Read wrong data (0xffff): phyAddr 0x%x, reg 0x%x",
16683 + phyAddr, reg));
16684 + if (err)
16685 + RETURN_ERROR(MINOR, (t_Error)err, NO_MSG);
16686 +
16687 + return E_OK;
16688 +}
16689 +
16690 --- /dev/null
16691 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
16692 @@ -0,0 +1,42 @@
16693 +/*
16694 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16695 + *
16696 + * Redistribution and use in source and binary forms, with or without
16697 + * modification, are permitted provided that the following conditions are met:
16698 + * * Redistributions of source code must retain the above copyright
16699 + * notice, this list of conditions and the following disclaimer.
16700 + * * Redistributions in binary form must reproduce the above copyright
16701 + * notice, this list of conditions and the following disclaimer in the
16702 + * documentation and/or other materials provided with the distribution.
16703 + * * Neither the name of Freescale Semiconductor nor the
16704 + * names of its contributors may be used to endorse or promote products
16705 + * derived from this software without specific prior written permission.
16706 + *
16707 + *
16708 + * ALTERNATIVELY, this software may be distributed under the terms of the
16709 + * GNU General Public License ("GPL") as published by the Free Software
16710 + * Foundation, either version 2 of that License or (at your option) any
16711 + * later version.
16712 + *
16713 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16714 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16715 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16716 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16717 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16718 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16719 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16720 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16721 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16722 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16723 + */
16724 +
16725 +#ifndef __DTSEC_MII_ACC_H
16726 +#define __DTSEC_MII_ACC_H
16727 +
16728 +#include "std_ext.h"
16729 +
16730 +
16731 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data);
16732 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
16733 +
16734 +#endif /* __DTSEC_MII_ACC_H */
16735 --- /dev/null
16736 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
16737 @@ -0,0 +1,674 @@
16738 +/*
16739 + * Copyright 2008-2012 Freescale Semiconductor Inc.
16740 + *
16741 + * Redistribution and use in source and binary forms, with or without
16742 + * modification, are permitted provided that the following conditions are met:
16743 + * * Redistributions of source code must retain the above copyright
16744 + * notice, this list of conditions and the following disclaimer.
16745 + * * Redistributions in binary form must reproduce the above copyright
16746 + * notice, this list of conditions and the following disclaimer in the
16747 + * documentation and/or other materials provided with the distribution.
16748 + * * Neither the name of Freescale Semiconductor nor the
16749 + * names of its contributors may be used to endorse or promote products
16750 + * derived from this software without specific prior written permission.
16751 + *
16752 + *
16753 + * ALTERNATIVELY, this software may be distributed under the terms of the
16754 + * GNU General Public License ("GPL") as published by the Free Software
16755 + * Foundation, either version 2 of that License or (at your option) any
16756 + * later version.
16757 + *
16758 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16759 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16760 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16761 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16762 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16763 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16764 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16765 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16766 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16767 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16768 + */
16769 +
16770 +
16771 +/******************************************************************************
16772 + @File fm_mac.c
16773 +
16774 + @Description FM MAC ...
16775 +*//***************************************************************************/
16776 +#include "std_ext.h"
16777 +#include "string_ext.h"
16778 +#include "sprint_ext.h"
16779 +#include "error_ext.h"
16780 +#include "fm_ext.h"
16781 +
16782 +#include "fm_common.h"
16783 +#include "fm_mac.h"
16784 +
16785 +
16786 +/* ......................................................................... */
16787 +
16788 +t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam)
16789 +{
16790 + t_FmMacControllerDriver *p_FmMacControllerDriver;
16791 + uint16_t fmClkFreq;
16792 +
16793 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, NULL);
16794 +
16795 + fmClkFreq = FmGetClockFreq(p_FmMacParam->h_Fm);
16796 + if (fmClkFreq == 0)
16797 + {
16798 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!"));
16799 + return NULL;
16800 + }
16801 +
16802 +#if (DPAA_VERSION == 10)
16803 + if (ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000)
16804 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)DTSEC_Config(p_FmMacParam);
16805 + else
16806 +#if FM_MAX_NUM_OF_10G_MACS > 0
16807 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam);
16808 +#else
16809 + p_FmMacControllerDriver = NULL;
16810 +#endif /* FM_MAX_NUM_OF_10G_MACS > 0 */
16811 +#else
16812 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)MEMAC_Config(p_FmMacParam);
16813 +#endif /* (DPAA_VERSION == 10) */
16814 +
16815 + if (!p_FmMacControllerDriver)
16816 + return NULL;
16817 +
16818 + p_FmMacControllerDriver->h_Fm = p_FmMacParam->h_Fm;
16819 + p_FmMacControllerDriver->enetMode = p_FmMacParam->enetMode;
16820 + p_FmMacControllerDriver->macId = p_FmMacParam->macId;
16821 + p_FmMacControllerDriver->resetOnInit = DEFAULT_resetOnInit;
16822 +
16823 + p_FmMacControllerDriver->clkFreq = fmClkFreq;
16824 +
16825 + return (t_Handle)p_FmMacControllerDriver;
16826 +}
16827 +
16828 +/* ......................................................................... */
16829 +
16830 +t_Error FM_MAC_Init (t_Handle h_FmMac)
16831 +{
16832 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16833 +
16834 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16835 +
16836 + if (p_FmMacControllerDriver->resetOnInit &&
16837 + !p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit &&
16838 + (FmResetMac(p_FmMacControllerDriver->h_Fm,
16839 + ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ?
16840 + e_FM_MAC_10G : e_FM_MAC_1G),
16841 + p_FmMacControllerDriver->macId) != E_OK))
16842 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't reset MAC!"));
16843 +
16844 + if (p_FmMacControllerDriver->f_FM_MAC_Init)
16845 + return p_FmMacControllerDriver->f_FM_MAC_Init(h_FmMac);
16846 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16847 +}
16848 +
16849 +/* ......................................................................... */
16850 +
16851 +t_Error FM_MAC_Free (t_Handle h_FmMac)
16852 +{
16853 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16854 +
16855 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16856 +
16857 + if (p_FmMacControllerDriver->f_FM_MAC_Free)
16858 + return p_FmMacControllerDriver->f_FM_MAC_Free(h_FmMac);
16859 +
16860 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16861 +}
16862 +
16863 +/* ......................................................................... */
16864 +
16865 +t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable)
16866 +{
16867 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16868 +
16869 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16870 +
16871 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit)
16872 + return p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit(h_FmMac, enable);
16873 +
16874 + p_FmMacControllerDriver->resetOnInit = enable;
16875 +
16876 + return E_OK;
16877 +}
16878 +
16879 +/* ......................................................................... */
16880 +
16881 +t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal)
16882 +{
16883 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16884 +
16885 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16886 +
16887 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback)
16888 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback(h_FmMac, newVal);
16889 +
16890 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16891 +}
16892 +
16893 +/* ......................................................................... */
16894 +
16895 +t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal)
16896 +{
16897 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16898 +
16899 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16900 +
16901 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength)
16902 + return p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength(h_FmMac, newVal);
16903 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16904 +}
16905 +
16906 +/* ......................................................................... */
16907 +
16908 +t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag)
16909 +{
16910 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16911 +
16912 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16913 +
16914 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigWan)
16915 + return p_FmMacControllerDriver->f_FM_MAC_ConfigWan(h_FmMac, flag);
16916 +
16917 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16918 +}
16919 +
16920 +/* ......................................................................... */
16921 +
16922 +t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal)
16923 +{
16924 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16925 +
16926 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16927 +
16928 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc)
16929 + return p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc(h_FmMac, newVal);
16930 +
16931 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16932 +}
16933 +
16934 +/* ......................................................................... */
16935 +
16936 +t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal)
16937 +{
16938 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16939 +
16940 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16941 +
16942 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex)
16943 + return p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex(h_FmMac,newVal);
16944 +
16945 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16946 +}
16947 +
16948 +/* ......................................................................... */
16949 +
16950 +t_Error FM_MAC_ConfigTbiPhyAddr (t_Handle h_FmMac, uint8_t newVal)
16951 +{
16952 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16953 +
16954 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16955 +
16956 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr)
16957 + return p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr(h_FmMac,newVal);
16958 +
16959 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16960 +}
16961 +
16962 +/* ......................................................................... */
16963 +
16964 +t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool newVal)
16965 +{
16966 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16967 +
16968 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16969 +
16970 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck)
16971 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck(h_FmMac,newVal);
16972 +
16973 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16974 +}
16975 +
16976 +/* ......................................................................... */
16977 +
16978 +t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
16979 +{
16980 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16981 +
16982 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16983 +
16984 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigException)
16985 + return p_FmMacControllerDriver->f_FM_MAC_ConfigException(h_FmMac, ex, enable);
16986 +
16987 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16988 +}
16989 +
16990 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
16991 +/* ......................................................................... */
16992 +
16993 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac)
16994 +{
16995 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16996 +
16997 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16998 +
16999 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround)
17000 + return p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround(h_FmMac);
17001 +
17002 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17003 +}
17004 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17005 +
17006 +
17007 +/*****************************************************************************/
17008 +/* Run Time Control */
17009 +/*****************************************************************************/
17010 +
17011 +/* ......................................................................... */
17012 +
17013 +t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode)
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_Enable)
17020 + return p_FmMacControllerDriver->f_FM_MAC_Enable(h_FmMac, mode);
17021 +
17022 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17023 +}
17024 +
17025 +/* ......................................................................... */
17026 +
17027 +t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode)
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_Disable)
17034 + return p_FmMacControllerDriver->f_FM_MAC_Disable(h_FmMac, mode);
17035 +
17036 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17037 +}
17038 +
17039 +t_Error FM_MAC_Resume (t_Handle h_FmMac)
17040 +{
17041 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17042 +
17043 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17044 +
17045 + if (p_FmMacControllerDriver->f_FM_MAC_Resume)
17046 + return p_FmMacControllerDriver->f_FM_MAC_Resume(h_FmMac);
17047 +
17048 + return E_OK;
17049 +}
17050 +
17051 +/* ......................................................................... */
17052 +
17053 +t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac)
17054 +{
17055 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17056 +
17057 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17058 +
17059 + if (p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp)
17060 + return p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp(h_FmMac);
17061 +
17062 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17063 +}
17064 +
17065 +/* ......................................................................... */
17066 +
17067 +t_Error FM_MAC_Disable1588TimeStamp (t_Handle h_FmMac)
17068 +{
17069 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17070 +
17071 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17072 +
17073 + if (p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp)
17074 + return p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp(h_FmMac);
17075 +
17076 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17077 +}
17078 +
17079 +/* ......................................................................... */
17080 +
17081 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
17082 + uint16_t pauseTime)
17083 +{
17084 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17085 +
17086 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17087 +
17088 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames)
17089 + return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac,
17090 + pauseTime);
17091 +
17092 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17093 +}
17094 +
17095 +/* ......................................................................... */
17096 +
17097 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
17098 + uint8_t priority,
17099 + uint16_t pauseTime,
17100 + uint16_t threshTime)
17101 +{
17102 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17103 +
17104 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17105 +
17106 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames)
17107 + return p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames(h_FmMac,
17108 + priority,
17109 + pauseTime,
17110 + threshTime);
17111 +
17112 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
17113 +}
17114 +
17115 +/* ......................................................................... */
17116 +
17117 +t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en)
17118 +{
17119 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17120 +
17121 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17122 +
17123 + if (p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames)
17124 + return p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames(h_FmMac, en);
17125 +
17126 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17127 +}
17128 +
17129 +/* ......................................................................... */
17130 +
17131 +t_Error FM_MAC_SetWakeOnLan (t_Handle h_FmMac, bool en)
17132 +{
17133 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17134 +
17135 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17136 +
17137 + if (p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan)
17138 + return p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan(h_FmMac, en);
17139 +
17140 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17141 +}
17142 +
17143 +/* ......................................................................... */
17144 +
17145 +t_Error FM_MAC_ResetCounters (t_Handle h_FmMac)
17146 +{
17147 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17148 +
17149 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17150 +
17151 + if (p_FmMacControllerDriver->f_FM_MAC_ResetCounters)
17152 + return p_FmMacControllerDriver->f_FM_MAC_ResetCounters(h_FmMac);
17153 +
17154 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17155 +}
17156 +
17157 +/* ......................................................................... */
17158 +
17159 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
17160 +{
17161 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17162 +
17163 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17164 +
17165 + if (p_FmMacControllerDriver->f_FM_MAC_SetException)
17166 + return p_FmMacControllerDriver->f_FM_MAC_SetException(h_FmMac, ex, enable);
17167 +
17168 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17169 +}
17170 +
17171 +/* ......................................................................... */
17172 +
17173 +t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel)
17174 +{
17175 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17176 +
17177 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17178 +
17179 + if (p_FmMacControllerDriver->f_FM_MAC_SetStatistics)
17180 + return p_FmMacControllerDriver->f_FM_MAC_SetStatistics(h_FmMac, statisticsLevel);
17181 +
17182 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17183 +}
17184 +
17185 +/* ......................................................................... */
17186 +
17187 +t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics)
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_GetStatistics)
17194 + return p_FmMacControllerDriver->f_FM_MAC_GetStatistics(h_FmMac, p_Statistics);
17195 +
17196 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17197 +}
17198 +
17199 +/* ......................................................................... */
17200 +
17201 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
17202 +{
17203 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17204 +
17205 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17206 +
17207 + memset(p_FrameSizeCounters, 0, sizeof(t_FmMacFrameSizeCounters));
17208 +
17209 + if (p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters)
17210 + return p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters(h_FmMac, p_FrameSizeCounters, type);
17211 +
17212 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17213 +}
17214 +
17215 +/* ......................................................................... */
17216 +
17217 +t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17218 +{
17219 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17220 +
17221 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17222 +
17223 + if (p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr)
17224 + return p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr(h_FmMac, p_EnetAddr);
17225 +
17226 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17227 +}
17228 +
17229 +/* ......................................................................... */
17230 +
17231 +t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17232 +{
17233 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17234 +
17235 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17236 +
17237 + if (p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr)
17238 + return p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr(h_FmMac, p_EnetAddr);
17239 +
17240 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17241 +}
17242 +
17243 +/* ......................................................................... */
17244 +
17245 +t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17246 +{
17247 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17248 +
17249 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17250 +
17251 + if (p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr)
17252 + return p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr(h_FmMac, p_EnetAddr);
17253 +
17254 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17255 +}
17256 +
17257 +/* ......................................................................... */
17258 +
17259 +t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17260 +{
17261 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17262 +
17263 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17264 +
17265 + if (p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr)
17266 + return p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr(h_FmMac, p_EnetAddr);
17267 +
17268 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17269 +}
17270 +
17271 +/* ......................................................................... */
17272 +
17273 +t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17274 +{
17275 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17276 +
17277 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17278 +
17279 + if (p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr)
17280 + return p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr(h_FmMac, p_EnetAddr);
17281 +
17282 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17283 +}
17284 +
17285 +/* ......................................................................... */
17286 +
17287 +t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion)
17288 +{
17289 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17290 +
17291 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17292 +
17293 + if (p_FmMacControllerDriver->f_FM_MAC_GetVersion)
17294 + return p_FmMacControllerDriver->f_FM_MAC_GetVersion(h_FmMac, macVresion);
17295 +
17296 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17297 +
17298 +}
17299 +
17300 +/* ......................................................................... */
17301 +
17302 +t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId)
17303 +{
17304 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17305 +
17306 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17307 +
17308 + if (p_FmMacControllerDriver->f_FM_MAC_GetId)
17309 + return p_FmMacControllerDriver->f_FM_MAC_GetId(h_FmMac, macId);
17310 +
17311 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17312 +}
17313 +
17314 +/* ......................................................................... */
17315 +
17316 +t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal)
17317 +{
17318 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17319 +
17320 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17321 +
17322 + if (p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous)
17323 + return p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous(h_FmMac, newVal);
17324 +
17325 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17326 +}
17327 +
17328 +/* ......................................................................... */
17329 +
17330 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex)
17331 +{
17332 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17333 +
17334 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17335 +
17336 + if (p_FmMacControllerDriver->f_FM_MAC_AdjustLink)
17337 + return p_FmMacControllerDriver->f_FM_MAC_AdjustLink(h_FmMac, speed, fullDuplex);
17338 +
17339 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17340 +}
17341 +
17342 +/* ......................................................................... */
17343 +
17344 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac)
17345 +{
17346 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17347 +
17348 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17349 +
17350 + if (p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg)
17351 + return p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg(h_FmMac);
17352 +
17353 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17354 +}
17355 +
17356 +/* ......................................................................... */
17357 +
17358 +t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data)
17359 +{
17360 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17361 +
17362 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17363 +
17364 + if (p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg)
17365 + return p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg(h_FmMac, phyAddr, reg, data);
17366 +
17367 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17368 +}
17369 +
17370 +/* ......................................................................... */
17371 +
17372 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data)
17373 +{
17374 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17375 +
17376 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17377 +
17378 + if (p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg)
17379 + return p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg(h_FmMac, phyAddr, reg, p_Data);
17380 +
17381 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17382 +}
17383 +
17384 +/* ......................................................................... */
17385 +
17386 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle h_FmMac)
17387 +{
17388 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17389 +
17390 + SANITY_CHECK_RETURN_VALUE(p_FmMacControllerDriver, E_INVALID_HANDLE, 0);
17391 +
17392 + if (p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength)
17393 + return p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength(h_FmMac);
17394 +
17395 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17396 + return 0;
17397 +}
17398 +
17399 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17400 +/*****************************************************************************/
17401 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac)
17402 +{
17403 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17404 +
17405 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17406 +
17407 + if (p_FmMacControllerDriver->f_FM_MAC_DumpRegs)
17408 + return p_FmMacControllerDriver->f_FM_MAC_DumpRegs(h_FmMac);
17409 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17410 +}
17411 +#endif /* (defined(DEBUG_ERRORS) && ... */
17412 --- /dev/null
17413 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
17414 @@ -0,0 +1,226 @@
17415 +/*
17416 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17417 + *
17418 + * Redistribution and use in source and binary forms, with or without
17419 + * modification, are permitted provided that the following conditions are met:
17420 + * * Redistributions of source code must retain the above copyright
17421 + * notice, this list of conditions and the following disclaimer.
17422 + * * Redistributions in binary form must reproduce the above copyright
17423 + * notice, this list of conditions and the following disclaimer in the
17424 + * documentation and/or other materials provided with the distribution.
17425 + * * Neither the name of Freescale Semiconductor nor the
17426 + * names of its contributors may be used to endorse or promote products
17427 + * derived from this software without specific prior written permission.
17428 + *
17429 + *
17430 + * ALTERNATIVELY, this software may be distributed under the terms of the
17431 + * GNU General Public License ("GPL") as published by the Free Software
17432 + * Foundation, either version 2 of that License or (at your option) any
17433 + * later version.
17434 + *
17435 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17436 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17437 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17438 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17439 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17440 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17441 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17442 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17443 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17444 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17445 + */
17446 +
17447 +
17448 +/******************************************************************************
17449 + @File fm_mac.h
17450 +
17451 + @Description FM MAC ...
17452 +*//***************************************************************************/
17453 +#ifndef __FM_MAC_H
17454 +#define __FM_MAC_H
17455 +
17456 +#include "std_ext.h"
17457 +#include "error_ext.h"
17458 +#include "list_ext.h"
17459 +#include "fm_mac_ext.h"
17460 +#include "fm_common.h"
17461 +
17462 +
17463 +#define __ERR_MODULE__ MODULE_FM_MAC
17464 +
17465 +/**************************************************************************//**
17466 + @Description defaults
17467 +*//***************************************************************************/
17468 +
17469 +
17470 +#define DEFAULT_halfDuplex FALSE
17471 +#define DEFAULT_padAndCrcEnable TRUE
17472 +#define DEFAULT_resetOnInit FALSE
17473 +
17474 +
17475 +typedef struct {
17476 + uint64_t addr; /* Ethernet Address */
17477 + t_List node;
17478 +} t_EthHashEntry;
17479 +#define ETH_HASH_ENTRY_OBJ(ptr) LIST_OBJECT(ptr, t_EthHashEntry, node)
17480 +
17481 +typedef struct {
17482 + uint16_t size;
17483 + t_List *p_Lsts;
17484 +} t_EthHash;
17485 +
17486 +typedef struct {
17487 + t_Error (*f_FM_MAC_Init) (t_Handle h_FmMac);
17488 + t_Error (*f_FM_MAC_Free) (t_Handle h_FmMac);
17489 +
17490 + t_Error (*f_FM_MAC_SetStatistics) (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
17491 + t_Error (*f_FM_MAC_ConfigLoopback) (t_Handle h_FmMac, bool newVal);
17492 + t_Error (*f_FM_MAC_ConfigMaxFrameLength) (t_Handle h_FmMac, uint16_t newVal);
17493 + t_Error (*f_FM_MAC_ConfigWan) (t_Handle h_FmMac, bool flag);
17494 + t_Error (*f_FM_MAC_ConfigPadAndCrc) (t_Handle h_FmMac, bool newVal);
17495 + t_Error (*f_FM_MAC_ConfigHalfDuplex) (t_Handle h_FmMac, bool newVal);
17496 + t_Error (*f_FM_MAC_ConfigLengthCheck) (t_Handle h_FmMac, bool newVal);
17497 + t_Error (*f_FM_MAC_ConfigTbiPhyAddr) (t_Handle h_FmMac, uint8_t newVal);
17498 + t_Error (*f_FM_MAC_ConfigException) (t_Handle h_FmMac, e_FmMacExceptions, bool enable);
17499 + t_Error (*f_FM_MAC_ConfigResetOnInit) (t_Handle h_FmMac, bool enable);
17500 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
17501 + t_Error (*f_FM_MAC_ConfigSkipFman11Workaround) (t_Handle h_FmMac);
17502 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17503 +
17504 + t_Error (*f_FM_MAC_SetException) (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
17505 +
17506 + t_Error (*f_FM_MAC_Enable) (t_Handle h_FmMac, e_CommMode mode);
17507 + t_Error (*f_FM_MAC_Disable) (t_Handle h_FmMac, e_CommMode mode);
17508 + t_Error (*f_FM_MAC_Resume) (t_Handle h_FmMac);
17509 + t_Error (*f_FM_MAC_Enable1588TimeStamp) (t_Handle h_FmMac);
17510 + t_Error (*f_FM_MAC_Disable1588TimeStamp) (t_Handle h_FmMac);
17511 + t_Error (*f_FM_MAC_Reset) (t_Handle h_FmMac, bool wait);
17512 +
17513 + t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac,
17514 + uint16_t pauseTime);
17515 + t_Error (*f_FM_MAC_SetTxPauseFrames) (t_Handle h_FmMac,
17516 + uint8_t priority,
17517 + uint16_t pauseTime,
17518 + uint16_t threshTime);
17519 + t_Error (*f_FM_MAC_SetRxIgnorePauseFrames) (t_Handle h_FmMac, bool en);
17520 +
17521 + t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac);
17522 + t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
17523 + t_Error (*f_FM_MAC_GetFrameSizeCounters) (t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
17524 +
17525 + t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17526 + t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17527 + t_Error (*f_FM_MAC_RemoveHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17528 + t_Error (*f_FM_MAC_AddExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17529 + t_Error (*f_FM_MAC_RemovelExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17530 +
17531 + t_Error (*f_FM_MAC_SetPromiscuous) (t_Handle h_FmMac, bool newVal);
17532 + t_Error (*f_FM_MAC_AdjustLink) (t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
17533 + t_Error (*f_FM_MAC_RestartAutoneg) (t_Handle h_FmMac);
17534 +
17535 + t_Error (*f_FM_MAC_SetWakeOnLan) (t_Handle h_FmMac, bool en);
17536 +
17537 + t_Error (*f_FM_MAC_GetId) (t_Handle h_FmMac, uint32_t *macId);
17538 +
17539 + t_Error (*f_FM_MAC_GetVersion) (t_Handle h_FmMac, uint32_t *macVersion);
17540 +
17541 + uint16_t (*f_FM_MAC_GetMaxFrameLength) (t_Handle h_FmMac);
17542 +
17543 + t_Error (*f_FM_MAC_MII_WritePhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
17544 + t_Error (*f_FM_MAC_MII_ReadPhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
17545 +
17546 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17547 + t_Error (*f_FM_MAC_DumpRegs) (t_Handle h_FmMac);
17548 +#endif /* (defined(DEBUG_ERRORS) && ... */
17549 +
17550 + t_Handle h_Fm;
17551 + t_FmRevisionInfo fmRevInfo;
17552 + e_EnetMode enetMode;
17553 + uint8_t macId;
17554 + bool resetOnInit;
17555 + uint16_t clkFreq;
17556 +} t_FmMacControllerDriver;
17557 +
17558 +
17559 +#if (DPAA_VERSION == 10)
17560 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam);
17561 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParams);
17562 +#else
17563 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam);
17564 +#endif /* (DPAA_VERSION == 10) */
17565 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
17566 +
17567 +
17568 +/* ........................................................................... */
17569 +
17570 +static __inline__ t_EthHashEntry *DequeueAddrFromHashEntry(t_List *p_AddrLst)
17571 +{
17572 + t_EthHashEntry *p_HashEntry = NULL;
17573 + if (!LIST_IsEmpty(p_AddrLst))
17574 + {
17575 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_AddrLst->p_Next);
17576 + LIST_DelAndInit(&p_HashEntry->node);
17577 + }
17578 + return p_HashEntry;
17579 +}
17580 +
17581 +/* ........................................................................... */
17582 +
17583 +static __inline__ void FreeHashTable(t_EthHash *p_Hash)
17584 +{
17585 + t_EthHashEntry *p_HashEntry;
17586 + int i = 0;
17587 +
17588 + if (p_Hash)
17589 + {
17590 + if (p_Hash->p_Lsts)
17591 + {
17592 + for (i=0; i<p_Hash->size; i++)
17593 + {
17594 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17595 + while (p_HashEntry)
17596 + {
17597 + XX_Free(p_HashEntry);
17598 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17599 + }
17600 + }
17601 +
17602 + XX_Free(p_Hash->p_Lsts);
17603 + }
17604 +
17605 + XX_Free(p_Hash);
17606 + }
17607 +}
17608 +
17609 +/* ........................................................................... */
17610 +
17611 +static __inline__ t_EthHash * AllocHashTable(uint16_t size)
17612 +{
17613 + uint32_t i;
17614 + t_EthHash *p_Hash;
17615 +
17616 + /* Allocate address hash table */
17617 + p_Hash = (t_EthHash *)XX_Malloc(sizeof(t_EthHash));
17618 + if (!p_Hash)
17619 + {
17620 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17621 + return NULL;
17622 + }
17623 + p_Hash->size = size;
17624 +
17625 + p_Hash->p_Lsts = (t_List *)XX_Malloc(p_Hash->size*sizeof(t_List));
17626 + if (!p_Hash->p_Lsts)
17627 + {
17628 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17629 + XX_Free(p_Hash);
17630 + return NULL;
17631 + }
17632 +
17633 + for (i=0 ; i<p_Hash->size; i++)
17634 + INIT_LIST(&p_Hash->p_Lsts[i]);
17635 +
17636 + return p_Hash;
17637 +}
17638 +
17639 +
17640 +#endif /* __FM_MAC_H */
17641 --- /dev/null
17642 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
17643 @@ -0,0 +1,119 @@
17644 +/*
17645 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17646 + *
17647 + * Redistribution and use in source and binary forms, with or without
17648 + * modification, are permitted provided that the following conditions are met:
17649 + * * Redistributions of source code must retain the above copyright
17650 + * notice, this list of conditions and the following disclaimer.
17651 + * * Redistributions in binary form must reproduce the above copyright
17652 + * notice, this list of conditions and the following disclaimer in the
17653 + * documentation and/or other materials provided with the distribution.
17654 + * * Neither the name of Freescale Semiconductor nor the
17655 + * names of its contributors may be used to endorse or promote products
17656 + * derived from this software without specific prior written permission.
17657 + *
17658 + *
17659 + * ALTERNATIVELY, this software may be distributed under the terms of the
17660 + * GNU General Public License ("GPL") as published by the Free Software
17661 + * Foundation, either version 2 of that License or (at your option) any
17662 + * later version.
17663 + *
17664 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17665 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17666 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17667 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17668 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17669 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17670 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17671 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17672 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17673 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17674 + */
17675 +
17676 +
17677 +#include "fman_crc32.h"
17678 +#include "common/general.h"
17679 +
17680 +
17681 +/* precomputed CRC values for address hashing */
17682 +static const uint32_t crc_tbl[256] = {
17683 + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
17684 + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
17685 + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
17686 + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
17687 + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
17688 + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
17689 + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
17690 + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
17691 + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
17692 + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
17693 + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
17694 + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
17695 + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
17696 + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
17697 + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
17698 + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
17699 + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
17700 + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
17701 + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
17702 + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
17703 + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
17704 + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
17705 + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
17706 + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
17707 + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
17708 + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
17709 + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
17710 + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
17711 + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
17712 + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
17713 + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
17714 + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
17715 + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
17716 + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
17717 + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
17718 + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
17719 + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
17720 + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
17721 + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
17722 + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
17723 + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
17724 + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
17725 + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
17726 +};
17727 +
17728 +/* Get the mirrored value of a byte size number. (0x11010011 --> 0x11001011) */
17729 +static inline uint8_t get_mirror8(uint8_t n)
17730 +{
17731 + uint8_t mirror[16] = {
17732 + 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
17733 + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
17734 + };
17735 + return (uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4])));
17736 +}
17737 +
17738 +static inline uint32_t get_mirror32(uint32_t n)
17739 +{
17740 + return ((uint32_t)get_mirror8((uint8_t)(n))<<24) |
17741 + ((uint32_t)get_mirror8((uint8_t)(n>>8))<<16) |
17742 + ((uint32_t)get_mirror8((uint8_t)(n>>16))<<8) |
17743 + ((uint32_t)get_mirror8((uint8_t)(n>>24)));
17744 +}
17745 +
17746 +uint32_t get_mac_addr_crc(uint64_t _addr)
17747 +{
17748 + uint32_t i;
17749 + uint8_t data;
17750 + uint32_t crc;
17751 +
17752 + /* CRC calculation */
17753 + crc = 0xffffffff;
17754 + for (i = 0; i < 6; i++) {
17755 + data = (uint8_t)(_addr >> ((5-i)*8));
17756 + crc = crc ^ data;
17757 + crc = crc_tbl[crc&0xff] ^ (crc>>8);
17758 + }
17759 +
17760 + crc = get_mirror32(crc);
17761 + return crc;
17762 +}
17763 --- /dev/null
17764 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
17765 @@ -0,0 +1,43 @@
17766 +/*
17767 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17768 + *
17769 + * Redistribution and use in source and binary forms, with or without
17770 + * modification, are permitted provided that the following conditions are met:
17771 + * * Redistributions of source code must retain the above copyright
17772 + * notice, this list of conditions and the following disclaimer.
17773 + * * Redistributions in binary form must reproduce the above copyright
17774 + * notice, this list of conditions and the following disclaimer in the
17775 + * documentation and/or other materials provided with the distribution.
17776 + * * Neither the name of Freescale Semiconductor nor the
17777 + * names of its contributors may be used to endorse or promote products
17778 + * derived from this software without specific prior written permission.
17779 + *
17780 + *
17781 + * ALTERNATIVELY, this software may be distributed under the terms of the
17782 + * GNU General Public License ("GPL") as published by the Free Software
17783 + * Foundation, either version 2 of that License or (at your option) any
17784 + * later version.
17785 + *
17786 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17787 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17788 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17789 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17790 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17791 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17792 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17793 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17794 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17795 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17796 + */
17797 +
17798 +
17799 +#ifndef __FMAN_CRC32_H
17800 +#define __FMAN_CRC32_H
17801 +
17802 +#include "common/general.h"
17803 +
17804 +
17805 +uint32_t get_mac_addr_crc(uint64_t _addr);
17806 +
17807 +
17808 +#endif /* __FMAN_CRC32_H */
17809 --- /dev/null
17810 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
17811 @@ -0,0 +1,845 @@
17812 +/*
17813 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17814 + *
17815 + * Redistribution and use in source and binary forms, with or without
17816 + * modification, are permitted provided that the following conditions are met:
17817 + * * Redistributions of source code must retain the above copyright
17818 + * notice, this list of conditions and the following disclaimer.
17819 + * * Redistributions in binary form must reproduce the above copyright
17820 + * notice, this list of conditions and the following disclaimer in the
17821 + * documentation and/or other materials provided with the distribution.
17822 + * * Neither the name of Freescale Semiconductor nor the
17823 + * names of its contributors may be used to endorse or promote products
17824 + * derived from this software without specific prior written permission.
17825 + *
17826 + *
17827 + * ALTERNATIVELY, this software may be distributed under the terms of the
17828 + * GNU General Public License ("GPL") as published by the Free Software
17829 + * Foundation, either version 2 of that License or (at your option) any
17830 + * later version.
17831 + *
17832 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17833 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17834 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17835 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17836 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17837 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17838 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17839 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17840 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17841 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17842 + */
17843 +
17844 +
17845 +#include "fsl_fman_dtsec.h"
17846 +
17847 +
17848 +void fman_dtsec_stop_rx(struct dtsec_regs *regs)
17849 +{
17850 + /* Assert the graceful stop bit */
17851 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_GRS, &regs->rctrl);
17852 +}
17853 +
17854 +void fman_dtsec_stop_tx(struct dtsec_regs *regs)
17855 +{
17856 + /* Assert the graceful stop bit */
17857 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_GTS, &regs->tctrl);
17858 +}
17859 +
17860 +void fman_dtsec_start_tx(struct dtsec_regs *regs)
17861 +{
17862 + /* clear the graceful stop bit */
17863 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_GTS, &regs->tctrl);
17864 +}
17865 +
17866 +void fman_dtsec_start_rx(struct dtsec_regs *regs)
17867 +{
17868 + /* clear the graceful stop bit */
17869 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_GRS, &regs->rctrl);
17870 +}
17871 +
17872 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg)
17873 +{
17874 + cfg->halfdup_on = DEFAULT_HALFDUP_ON;
17875 + cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT;
17876 + cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW;
17877 + cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER;
17878 + cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF;
17879 + cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF;
17880 + cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL;
17881 + cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN;
17882 + cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST;
17883 + cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM;
17884 + cfg->rx_len_check = DEFAULT_RX_LEN_CHECK;
17885 + cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC;
17886 + cfg->tx_crc = DEFAULT_TX_CRC;
17887 + cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC;
17888 + cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME;
17889 + cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/
17890 + cfg->rx_prepend = DEFAULT_RX_PREPEND;
17891 + cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN;
17892 + cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN;
17893 + cfg->preamble_len = DEFAULT_PREAMBLE_LEN;
17894 + cfg->rx_preamble = DEFAULT_RX_PREAMBLE;
17895 + cfg->tx_preamble = DEFAULT_TX_PREAMBLE;
17896 + cfg->loopback = DEFAULT_LOOPBACK;
17897 + cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN;
17898 + cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN;
17899 + cfg->rx_flow = DEFAULT_RX_FLOW;
17900 + cfg->tx_flow = DEFAULT_TX_FLOW;
17901 + cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD;
17902 + cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD;
17903 + cfg->rx_promisc = DEFAULT_RX_PROMISC;
17904 + cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1;
17905 + cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2;
17906 + cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT;
17907 + cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG;
17908 + cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME;
17909 + cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR;
17910 + cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN;
17911 +}
17912 +
17913 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
17914 + enum enet_interface iface_mode,
17915 + enum enet_speed iface_speed,
17916 + uint8_t *macaddr,
17917 + uint8_t fm_rev_maj,
17918 + uint8_t fm_rev_min,
17919 + uint32_t exception_mask)
17920 +{
17921 + bool is_rgmii = FALSE;
17922 + bool is_sgmii = FALSE;
17923 + bool is_qsgmii = FALSE;
17924 + int i;
17925 + uint32_t tmp;
17926 +
17927 +UNUSED(fm_rev_maj);UNUSED(fm_rev_min);
17928 +
17929 + /* let's start with a soft reset */
17930 + iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
17931 + iowrite32be(0, &regs->maccfg1);
17932 +
17933 + /*************dtsec_id2******************/
17934 + tmp = ioread32be(&regs->tsec_id2);
17935 +
17936 + /* check RGMII support */
17937 + if (iface_mode == E_ENET_IF_RGMII ||
17938 + iface_mode == E_ENET_IF_RMII)
17939 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
17940 + return -EINVAL;
17941 +
17942 + if (iface_mode == E_ENET_IF_SGMII ||
17943 + iface_mode == E_ENET_IF_MII)
17944 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
17945 + return -EINVAL;
17946 +
17947 + /***************ECNTRL************************/
17948 +
17949 + is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE);
17950 + is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE);
17951 + is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE);
17952 +
17953 + tmp = 0;
17954 + if (is_rgmii || iface_mode == E_ENET_IF_GMII)
17955 + tmp |= DTSEC_ECNTRL_GMIIM;
17956 + if (is_sgmii)
17957 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
17958 + if (is_qsgmii)
17959 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
17960 + DTSEC_ECNTRL_QSGMIIM);
17961 + if (is_rgmii)
17962 + tmp |= DTSEC_ECNTRL_RPM;
17963 + if (iface_speed == E_ENET_SPEED_100)
17964 + tmp |= DTSEC_ECNTRL_R100M;
17965 +
17966 + iowrite32be(tmp, &regs->ecntrl);
17967 + /***************ECNTRL************************/
17968 +
17969 + /***************TCTRL************************/
17970 + tmp = 0;
17971 + if (cfg->halfdup_on)
17972 + tmp |= DTSEC_TCTRL_THDF;
17973 + if (cfg->tx_time_stamp_en)
17974 + tmp |= DTSEC_TCTRL_TTSE;
17975 +
17976 + iowrite32be(tmp, &regs->tctrl);
17977 +
17978 + /***************TCTRL************************/
17979 +
17980 + /***************PTV************************/
17981 + tmp = 0;
17982 +
17983 +#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
17984 + if ((fm_rev_maj == 1) && (fm_rev_min == 0))
17985 + cfg->tx_pause_time += 2;
17986 +#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
17987 +
17988 + if (cfg->tx_pause_time)
17989 + tmp |= cfg->tx_pause_time;
17990 + if (cfg->tx_pause_time_extd)
17991 + tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST;
17992 + iowrite32be(tmp, &regs->ptv);
17993 +
17994 + /***************RCTRL************************/
17995 + tmp = 0;
17996 + tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16;
17997 + if (cfg->rx_ctrl_acc)
17998 + tmp |= RCTRL_CFA;
17999 + if (cfg->rx_group_hash_exd)
18000 + tmp |= RCTRL_GHTX;
18001 + if (cfg->rx_time_stamp_en)
18002 + tmp |= RCTRL_RTSE;
18003 + if (cfg->rx_drop_bcast)
18004 + tmp |= RCTRL_BC_REJ;
18005 + if (cfg->rx_short_frm)
18006 + tmp |= RCTRL_RSF;
18007 + if (cfg->rx_promisc)
18008 + tmp |= RCTRL_PROM;
18009 +
18010 + iowrite32be(tmp, &regs->rctrl);
18011 + /***************RCTRL************************/
18012 +
18013 + /*
18014 + * Assign a Phy Address to the TBI (TBIPA).
18015 + * Done also in cases where TBI is not selected to avoid conflict with
18016 + * the external PHY's Physical address
18017 + */
18018 + iowrite32be(cfg->tbipa, &regs->tbipa);
18019 +
18020 + /***************TMR_CTL************************/
18021 + iowrite32be(0, &regs->tmr_ctrl);
18022 +
18023 + if (cfg->ptp_tsu_en) {
18024 + tmp = 0;
18025 + tmp |= TMR_PEVENT_TSRE;
18026 + iowrite32be(tmp, &regs->tmr_pevent);
18027 +
18028 + if (cfg->ptp_exception_en) {
18029 + tmp = 0;
18030 + tmp |= TMR_PEMASK_TSREEN;
18031 + iowrite32be(tmp, &regs->tmr_pemask);
18032 + }
18033 + }
18034 +
18035 + /***************MACCFG1***********************/
18036 + tmp = 0;
18037 + if (cfg->loopback)
18038 + tmp |= MACCFG1_LOOPBACK;
18039 + if (cfg->rx_flow)
18040 + tmp |= MACCFG1_RX_FLOW;
18041 + if (cfg->tx_flow)
18042 + tmp |= MACCFG1_TX_FLOW;
18043 + iowrite32be(tmp, &regs->maccfg1);
18044 +
18045 + /***************MACCFG1***********************/
18046 +
18047 + /***************MACCFG2***********************/
18048 + tmp = 0;
18049 +
18050 + if (iface_speed < E_ENET_SPEED_1000)
18051 + tmp |= MACCFG2_NIBBLE_MODE;
18052 + else if (iface_speed == E_ENET_SPEED_1000)
18053 + tmp |= MACCFG2_BYTE_MODE;
18054 +
18055 + tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f)
18056 + << PREAMBLE_LENGTH_SHIFT;
18057 +
18058 + if (cfg->rx_preamble)
18059 + tmp |= MACCFG2_PRE_AM_Rx_EN;
18060 + if (cfg->tx_preamble)
18061 + tmp |= MACCFG2_PRE_AM_Tx_EN;
18062 + if (cfg->rx_len_check)
18063 + tmp |= MACCFG2_LENGTH_CHECK;
18064 + if (cfg->tx_pad_crc)
18065 + tmp |= MACCFG2_PAD_CRC_EN;
18066 + if (cfg->tx_crc)
18067 + tmp |= MACCFG2_CRC_EN;
18068 + if (!cfg->halfdup_on)
18069 + tmp |= MACCFG2_FULL_DUPLEX;
18070 + iowrite32be(tmp, &regs->maccfg2);
18071 +
18072 + /***************MACCFG2***********************/
18073 +
18074 + /***************IPGIFG************************/
18075 + tmp = (((cfg->non_back_to_back_ipg1 <<
18076 + IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT)
18077 + & IPGIFG_NON_BACK_TO_BACK_IPG_1)
18078 + | ((cfg->non_back_to_back_ipg2 <<
18079 + IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT)
18080 + & IPGIFG_NON_BACK_TO_BACK_IPG_2)
18081 + | ((cfg->min_ifg_enforcement <<
18082 + IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT)
18083 + & IPGIFG_MIN_IFG_ENFORCEMENT)
18084 + | (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG));
18085 + iowrite32be(tmp, &regs->ipgifg);
18086 +
18087 + /***************IPGIFG************************/
18088 +
18089 + /***************HAFDUP************************/
18090 + tmp = 0;
18091 +
18092 + if (cfg->halfdup_alt_backoff_en)
18093 + tmp = (uint32_t)(HAFDUP_ALT_BEB |
18094 + ((cfg->halfdup_alt_backoff_val & 0x0000000f)
18095 + << HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));
18096 + if (cfg->halfdup_bp_no_backoff)
18097 + tmp |= HAFDUP_BP_NO_BACKOFF;
18098 + if (cfg->halfdup_no_backoff)
18099 + tmp |= HAFDUP_NO_BACKOFF;
18100 + if (cfg->halfdup_excess_defer)
18101 + tmp |= HAFDUP_EXCESS_DEFER;
18102 + tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT)
18103 + & HAFDUP_RETRANSMISSION_MAX);
18104 + tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW);
18105 +
18106 + iowrite32be(tmp, &regs->hafdup);
18107 + /***************HAFDUP************************/
18108 +
18109 + /***************MAXFRM************************/
18110 + /* Initialize MAXFRM */
18111 + iowrite32be(cfg->maximum_frame, &regs->maxfrm);
18112 +
18113 + /***************MAXFRM************************/
18114 +
18115 + /***************CAM1************************/
18116 + iowrite32be(0xffffffff, &regs->cam1);
18117 + iowrite32be(0xffffffff, &regs->cam2);
18118 +
18119 + /***************IMASK************************/
18120 + iowrite32be(exception_mask, &regs->imask);
18121 + /***************IMASK************************/
18122 +
18123 + /***************IEVENT************************/
18124 + iowrite32be(0xffffffff, &regs->ievent);
18125 +
18126 + /***************MACSTNADDR1/2*****************/
18127 +
18128 + tmp = (uint32_t)((macaddr[5] << 24) |
18129 + (macaddr[4] << 16) |
18130 + (macaddr[3] << 8) |
18131 + macaddr[2]);
18132 + iowrite32be(tmp, &regs->macstnaddr1);
18133 +
18134 + tmp = (uint32_t)((macaddr[1] << 24) |
18135 + (macaddr[0] << 16));
18136 + iowrite32be(tmp, &regs->macstnaddr2);
18137 +
18138 + /***************MACSTNADDR1/2*****************/
18139 +
18140 + /*****************HASH************************/
18141 + for (i = 0; i < NUM_OF_HASH_REGS ; i++) {
18142 + /* Initialize IADDRx */
18143 + iowrite32be(0, &regs->igaddr[i]);
18144 + /* Initialize GADDRx */
18145 + iowrite32be(0, &regs->gaddr[i]);
18146 + }
18147 +
18148 + fman_dtsec_reset_stat(regs);
18149 +
18150 + return 0;
18151 +}
18152 +
18153 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs)
18154 +{
18155 + return (uint16_t)ioread32be(&regs->maxfrm);
18156 +}
18157 +
18158 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length)
18159 +{
18160 + iowrite32be(length, &regs->maxfrm);
18161 +}
18162 +
18163 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr)
18164 +{
18165 + uint32_t tmp;
18166 +
18167 + tmp = (uint32_t)((adr[5] << 24) |
18168 + (adr[4] << 16) |
18169 + (adr[3] << 8) |
18170 + adr[2]);
18171 + iowrite32be(tmp, &regs->macstnaddr1);
18172 +
18173 + tmp = (uint32_t)((adr[1] << 24) |
18174 + (adr[0] << 16));
18175 + iowrite32be(tmp, &regs->macstnaddr2);
18176 +}
18177 +
18178 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr)
18179 +{
18180 + uint32_t tmp1, tmp2;
18181 +
18182 + tmp1 = ioread32be(&regs->macstnaddr1);
18183 + tmp2 = ioread32be(&regs->macstnaddr2);
18184 +
18185 + macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16);
18186 + macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24);
18187 + macaddr[2] = (uint8_t)(tmp1 & 0x000000ff);
18188 + macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8);
18189 + macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16);
18190 + macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24);
18191 +}
18192 +
18193 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx)
18194 +{
18195 + int32_t bucket;
18196 + if (ghtx)
18197 + bucket = (int32_t)((crc >> 23) & 0x1ff);
18198 + else {
18199 + bucket = (int32_t)((crc >> 24) & 0xff);
18200 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
18201 + if (mcast)
18202 + bucket += 0x100;
18203 + }
18204 + fman_dtsec_set_bucket(regs, bucket, TRUE);
18205 +}
18206 +
18207 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable)
18208 +{
18209 + int reg_idx = (bucket >> 5) & 0xf;
18210 + int bit_idx = bucket & 0x1f;
18211 + uint32_t bit_mask = 0x80000000 >> bit_idx;
18212 + uint32_t *reg;
18213 +
18214 + if (reg_idx > 7)
18215 + reg = &regs->gaddr[reg_idx-8];
18216 + else
18217 + reg = &regs->igaddr[reg_idx];
18218 +
18219 + if (enable)
18220 + iowrite32be(ioread32be(reg) | bit_mask, reg);
18221 + else
18222 + iowrite32be(ioread32be(reg) & (~bit_mask), reg);
18223 +}
18224 +
18225 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast)
18226 +{
18227 + int i;
18228 + bool ghtx;
18229 +
18230 + ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? TRUE : FALSE);
18231 +
18232 + if (ucast || (ghtx && mcast)) {
18233 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18234 + iowrite32be(0, &regs->igaddr[i]);
18235 + }
18236 + if (mcast) {
18237 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18238 + iowrite32be(0, &regs->gaddr[i]);
18239 + }
18240 +}
18241 +
18242 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
18243 + uint8_t addr)
18244 +{
18245 + if (addr > 0 && addr < 32)
18246 + iowrite32be(addr, &regs->tbipa);
18247 + else
18248 + return -EINVAL;
18249 +
18250 + return 0;
18251 +}
18252 +
18253 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en)
18254 +{
18255 + uint32_t tmp;
18256 +
18257 + tmp = ioread32be(&regs->maccfg2);
18258 + if (en)
18259 + tmp |= MACCFG2_MAGIC_PACKET_EN;
18260 + else
18261 + tmp &= ~MACCFG2_MAGIC_PACKET_EN;
18262 + iowrite32be(tmp, &regs->maccfg2);
18263 +}
18264 +
18265 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
18266 + enum enet_interface iface_mode,
18267 + enum enet_speed speed, bool full_dx)
18268 +{
18269 + uint32_t tmp;
18270 +
18271 + UNUSED(iface_mode);
18272 +
18273 + if ((speed == E_ENET_SPEED_1000) && !full_dx)
18274 + return -EINVAL;
18275 +
18276 + tmp = ioread32be(&regs->maccfg2);
18277 + if (!full_dx)
18278 + tmp &= ~MACCFG2_FULL_DUPLEX;
18279 + else
18280 + tmp |= MACCFG2_FULL_DUPLEX;
18281 +
18282 + tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
18283 + if (speed < E_ENET_SPEED_1000)
18284 + tmp |= MACCFG2_NIBBLE_MODE;
18285 + else if (speed == E_ENET_SPEED_1000)
18286 + tmp |= MACCFG2_BYTE_MODE;
18287 + iowrite32be(tmp, &regs->maccfg2);
18288 +
18289 + tmp = ioread32be(&regs->ecntrl);
18290 + if (speed == E_ENET_SPEED_100)
18291 + tmp |= DTSEC_ECNTRL_R100M;
18292 + else
18293 + tmp &= ~DTSEC_ECNTRL_R100M;
18294 + iowrite32be(tmp, &regs->ecntrl);
18295 +
18296 + return 0;
18297 +}
18298 +
18299 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable)
18300 +{
18301 + uint32_t tmp;
18302 +
18303 + tmp = ioread32be(&regs->rctrl);
18304 +
18305 + if (enable)
18306 + tmp |= RCTRL_UPROM;
18307 + else
18308 + tmp &= ~RCTRL_UPROM;
18309 +
18310 + iowrite32be(tmp, &regs->rctrl);
18311 +}
18312 +
18313 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable)
18314 +{
18315 + uint32_t tmp;
18316 +
18317 + tmp = ioread32be(&regs->rctrl);
18318 +
18319 + if (enable)
18320 + tmp |= RCTRL_MPROM;
18321 + else
18322 + tmp &= ~RCTRL_MPROM;
18323 +
18324 + iowrite32be(tmp, &regs->rctrl);
18325 +}
18326 +
18327 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
18328 + uint32_t *car1, uint32_t *car2)
18329 +{
18330 + /* read carry registers */
18331 + *car1 = ioread32be(&regs->car1);
18332 + *car2 = ioread32be(&regs->car2);
18333 + /* clear carry registers */
18334 + if (*car1)
18335 + iowrite32be(*car1, &regs->car1);
18336 + if (*car2)
18337 + iowrite32be(*car2, &regs->car2);
18338 +
18339 + return (bool)((*car1 | *car2) ? TRUE : FALSE);
18340 +}
18341 +
18342 +void fman_dtsec_reset_stat(struct dtsec_regs *regs)
18343 +{
18344 + /* clear HW counters */
18345 + iowrite32be(ioread32be(&regs->ecntrl) |
18346 + DTSEC_ECNTRL_CLRCNT, &regs->ecntrl);
18347 +}
18348 +
18349 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level)
18350 +{
18351 + switch (level) {
18352 + case E_MAC_STAT_NONE:
18353 + iowrite32be(0xffffffff, &regs->cam1);
18354 + iowrite32be(0xffffffff, &regs->cam2);
18355 + iowrite32be(ioread32be(&regs->ecntrl) & ~DTSEC_ECNTRL_STEN,
18356 + &regs->ecntrl);
18357 + iowrite32be(ioread32be(&regs->imask) & ~DTSEC_IMASK_MSROEN,
18358 + &regs->imask);
18359 + break;
18360 + case E_MAC_STAT_PARTIAL:
18361 + iowrite32be(CAM1_ERRORS_ONLY, &regs->cam1);
18362 + iowrite32be(CAM2_ERRORS_ONLY, &regs->cam2);
18363 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18364 + &regs->ecntrl);
18365 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18366 + &regs->imask);
18367 + break;
18368 + case E_MAC_STAT_MIB_GRP1:
18369 + iowrite32be((uint32_t)~CAM1_MIB_GRP_1, &regs->cam1);
18370 + iowrite32be((uint32_t)~CAM2_MIB_GRP_1, &regs->cam2);
18371 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18372 + &regs->ecntrl);
18373 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18374 + &regs->imask);
18375 + break;
18376 + case E_MAC_STAT_FULL:
18377 + iowrite32be(0, &regs->cam1);
18378 + iowrite32be(0, &regs->cam2);
18379 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18380 + &regs->ecntrl);
18381 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18382 + &regs->imask);
18383 + break;
18384 + default:
18385 + return -EINVAL;
18386 + }
18387 +
18388 + return 0;
18389 +}
18390 +
18391 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en)
18392 +{
18393 + if (en) {
18394 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_RTSE,
18395 + &regs->rctrl);
18396 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_TTSE,
18397 + &regs->tctrl);
18398 + } else {
18399 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_RTSE,
18400 + &regs->rctrl);
18401 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_TTSE,
18402 + &regs->tctrl);
18403 + }
18404 +}
18405 +
18406 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18407 +{
18408 + uint32_t tmp;
18409 +
18410 + tmp = ioread32be(&regs->maccfg1);
18411 +
18412 + if (apply_rx)
18413 + tmp |= MACCFG1_RX_EN ;
18414 +
18415 + if (apply_tx)
18416 + tmp |= MACCFG1_TX_EN ;
18417 +
18418 + iowrite32be(tmp, &regs->maccfg1);
18419 +}
18420 +
18421 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num)
18422 +{
18423 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match1);
18424 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match2);
18425 +}
18426 +
18427 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
18428 + uint64_t addr,
18429 + uint8_t paddr_num)
18430 +{
18431 + uint32_t tmp;
18432 +
18433 + tmp = (uint32_t)(addr);
18434 + /* swap */
18435 + tmp = (((tmp & 0x000000FF) << 24) |
18436 + ((tmp & 0x0000FF00) << 8) |
18437 + ((tmp & 0x00FF0000) >> 8) |
18438 + ((tmp & 0xFF000000) >> 24));
18439 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match1);
18440 +
18441 + tmp = (uint32_t)(addr>>32);
18442 + /* swap */
18443 + tmp = (((tmp & 0x000000FF) << 24) |
18444 + ((tmp & 0x0000FF00) << 8) |
18445 + ((tmp & 0x00FF0000) >> 8) |
18446 + ((tmp & 0xFF000000) >> 24));
18447 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match2);
18448 +}
18449 +
18450 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18451 +{
18452 + uint32_t tmp;
18453 +
18454 + tmp = ioread32be(&regs->maccfg1);
18455 +
18456 + if (apply_rx)
18457 + tmp &= ~MACCFG1_RX_EN;
18458 +
18459 + if (apply_tx)
18460 + tmp &= ~MACCFG1_TX_EN;
18461 +
18462 + iowrite32be(tmp, &regs->maccfg1);
18463 +}
18464 +
18465 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time)
18466 +{
18467 + uint32_t ptv = 0;
18468 +
18469 + /* fixme: don't enable tx pause for half-duplex */
18470 +
18471 + if (time) {
18472 + ptv = ioread32be(&regs->ptv);
18473 + ptv &= 0xffff0000;
18474 + ptv |= time & 0x0000ffff;
18475 + iowrite32be(ptv, &regs->ptv);
18476 +
18477 + /* trigger the transmission of a flow-control pause frame */
18478 + iowrite32be(ioread32be(&regs->maccfg1) | MACCFG1_TX_FLOW,
18479 + &regs->maccfg1);
18480 + } else
18481 + iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
18482 + &regs->maccfg1);
18483 +}
18484 +
18485 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en)
18486 +{
18487 + uint32_t tmp;
18488 +
18489 + /* todo: check if mac is set to full-duplex */
18490 +
18491 + tmp = ioread32be(&regs->maccfg1);
18492 + if (en)
18493 + tmp |= MACCFG1_RX_FLOW;
18494 + else
18495 + tmp &= ~MACCFG1_RX_FLOW;
18496 + iowrite32be(tmp, &regs->maccfg1);
18497 +}
18498 +
18499 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs)
18500 +{
18501 + return ioread32be(&regs->rctrl);
18502 +}
18503 +
18504 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs)
18505 +{
18506 + return ioread32be(&regs->tsec_id);
18507 +}
18508 +
18509 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask)
18510 +{
18511 + return ioread32be(&regs->ievent) & ev_mask;
18512 +}
18513 +
18514 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask)
18515 +{
18516 + iowrite32be(ev_mask, &regs->ievent);
18517 +}
18518 +
18519 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs)
18520 +{
18521 + return ioread32be(&regs->imask);
18522 +}
18523 +
18524 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs)
18525 +{
18526 + uint32_t event;
18527 +
18528 + event = ioread32be(&regs->tmr_pevent);
18529 + event &= ioread32be(&regs->tmr_pemask);
18530 +
18531 + if (event)
18532 + iowrite32be(event, &regs->tmr_pevent);
18533 + return event;
18534 +}
18535 +
18536 +void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs)
18537 +{
18538 + iowrite32be(ioread32be(&regs->tmr_pemask) | TMR_PEMASK_TSREEN,
18539 + &regs->tmr_pemask);
18540 +}
18541 +
18542 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs)
18543 +{
18544 + iowrite32be(ioread32be(&regs->tmr_pemask) & ~TMR_PEMASK_TSREEN,
18545 + &regs->tmr_pemask);
18546 +}
18547 +
18548 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18549 +{
18550 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
18551 +}
18552 +
18553 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18554 +{
18555 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
18556 +}
18557 +
18558 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
18559 + enum dtsec_stat_counters reg_name)
18560 +{
18561 + uint32_t ret_val;
18562 +
18563 + switch (reg_name) {
18564 + case E_DTSEC_STAT_TR64:
18565 + ret_val = ioread32be(&regs->tr64);
18566 + break;
18567 + case E_DTSEC_STAT_TR127:
18568 + ret_val = ioread32be(&regs->tr127);
18569 + break;
18570 + case E_DTSEC_STAT_TR255:
18571 + ret_val = ioread32be(&regs->tr255);
18572 + break;
18573 + case E_DTSEC_STAT_TR511:
18574 + ret_val = ioread32be(&regs->tr511);
18575 + break;
18576 + case E_DTSEC_STAT_TR1K:
18577 + ret_val = ioread32be(&regs->tr1k);
18578 + break;
18579 + case E_DTSEC_STAT_TRMAX:
18580 + ret_val = ioread32be(&regs->trmax);
18581 + break;
18582 + case E_DTSEC_STAT_TRMGV:
18583 + ret_val = ioread32be(&regs->trmgv);
18584 + break;
18585 + case E_DTSEC_STAT_RBYT:
18586 + ret_val = ioread32be(&regs->rbyt);
18587 + break;
18588 + case E_DTSEC_STAT_RPKT:
18589 + ret_val = ioread32be(&regs->rpkt);
18590 + break;
18591 + case E_DTSEC_STAT_RMCA:
18592 + ret_val = ioread32be(&regs->rmca);
18593 + break;
18594 + case E_DTSEC_STAT_RBCA:
18595 + ret_val = ioread32be(&regs->rbca);
18596 + break;
18597 + case E_DTSEC_STAT_RXPF:
18598 + ret_val = ioread32be(&regs->rxpf);
18599 + break;
18600 + case E_DTSEC_STAT_RALN:
18601 + ret_val = ioread32be(&regs->raln);
18602 + break;
18603 + case E_DTSEC_STAT_RFLR:
18604 + ret_val = ioread32be(&regs->rflr);
18605 + break;
18606 + case E_DTSEC_STAT_RCDE:
18607 + ret_val = ioread32be(&regs->rcde);
18608 + break;
18609 + case E_DTSEC_STAT_RCSE:
18610 + ret_val = ioread32be(&regs->rcse);
18611 + break;
18612 + case E_DTSEC_STAT_RUND:
18613 + ret_val = ioread32be(&regs->rund);
18614 + break;
18615 + case E_DTSEC_STAT_ROVR:
18616 + ret_val = ioread32be(&regs->rovr);
18617 + break;
18618 + case E_DTSEC_STAT_RFRG:
18619 + ret_val = ioread32be(&regs->rfrg);
18620 + break;
18621 + case E_DTSEC_STAT_RJBR:
18622 + ret_val = ioread32be(&regs->rjbr);
18623 + break;
18624 + case E_DTSEC_STAT_RDRP:
18625 + ret_val = ioread32be(&regs->rdrp);
18626 + break;
18627 + case E_DTSEC_STAT_TFCS:
18628 + ret_val = ioread32be(&regs->tfcs);
18629 + break;
18630 + case E_DTSEC_STAT_TBYT:
18631 + ret_val = ioread32be(&regs->tbyt);
18632 + break;
18633 + case E_DTSEC_STAT_TPKT:
18634 + ret_val = ioread32be(&regs->tpkt);
18635 + break;
18636 + case E_DTSEC_STAT_TMCA:
18637 + ret_val = ioread32be(&regs->tmca);
18638 + break;
18639 + case E_DTSEC_STAT_TBCA:
18640 + ret_val = ioread32be(&regs->tbca);
18641 + break;
18642 + case E_DTSEC_STAT_TXPF:
18643 + ret_val = ioread32be(&regs->txpf);
18644 + break;
18645 + case E_DTSEC_STAT_TNCL:
18646 + ret_val = ioread32be(&regs->tncl);
18647 + break;
18648 + case E_DTSEC_STAT_TDRP:
18649 + ret_val = ioread32be(&regs->tdrp);
18650 + break;
18651 + default:
18652 + ret_val = 0;
18653 + }
18654 +
18655 + return ret_val;
18656 +}
18657 --- /dev/null
18658 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
18659 @@ -0,0 +1,163 @@
18660 +/*
18661 + * Copyright 2008-2013 Freescale Semiconductor Inc.
18662 + *
18663 + * Redistribution and use in source and binary forms, with or without
18664 + * modification, are permitted provided that the following conditions are met:
18665 + * * Redistributions of source code must retain the above copyright
18666 + * notice, this list of conditions and the following disclaimer.
18667 + * * Redistributions in binary form must reproduce the above copyright
18668 + * notice, this list of conditions and the following disclaimer in the
18669 + * documentation and/or other materials provided with the distribution.
18670 + * * Neither the name of Freescale Semiconductor nor the
18671 + * names of its contributors may be used to endorse or promote products
18672 + * derived from this software without specific prior written permission.
18673 + *
18674 + *
18675 + * ALTERNATIVELY, this software may be distributed under the terms of the
18676 + * GNU General Public License ("GPL") as published by the Free Software
18677 + * Foundation, either version 2 of that License or (at your option) any
18678 + * later version.
18679 + *
18680 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18681 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18682 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18683 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18684 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18685 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18686 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18687 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18688 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18689 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18690 + */
18691 +
18692 +
18693 +#include "common/general.h"
18694 +#include "fsl_fman_dtsec_mii_acc.h"
18695 +
18696 +
18697 +/**
18698 + * dtsec_mii_get_div() - calculates the value of the dtsec mii divider
18699 + * @dtsec_freq: dtsec clock frequency (in Mhz)
18700 + *
18701 + * This function calculates the dtsec mii clock divider that determines
18702 + * the MII MDC clock. MII MDC clock will be set to work in the range
18703 + * of 1.5 to 2.5Mhz
18704 + * The output of this function is the value of MIIMCFG[MgmtClk] which
18705 + * implicitly determines the divider value.
18706 + * Note: the dTSEC system clock is equal to 1/2 of the FMan clock.
18707 + *
18708 + * The table below which reflects dtsec_mii_get_div() functionality
18709 + * shows the relations among dtsec_freq, MgmtClk, actual divider
18710 + * and the MII frequency:
18711 + *
18712 + * dtsec freq MgmtClk div MII freq Mhz
18713 + * [0.....80] 1 (1/4)(1/8) [0 to 2.5]
18714 + * [81...120] 2 (1/6)(1/8) [1.6 to 2.5]
18715 + * [121..160] 3 (1/8)(1/8) [1.8 to 2.5]
18716 + * [161..200] 4 (1/10)(1/8) [2.0 to 2.5]
18717 + * [201..280] 5 (1/14)(1/8) [1.8 to 2.5]
18718 + * [281..400] 6 (1/20)(1/8) [1.1 to 2.5]
18719 + * [401..560] 7 (1/28)(1/8) [1.8 to 2.5]
18720 + * [560..frq] 7 (1/28)(1/8) [frq/224]
18721 + *
18722 + * Returns: the MIIMCFG[MgmtClk] appropriate value
18723 + */
18724 +
18725 +static uint8_t dtsec_mii_get_div(uint16_t dtsec_freq)
18726 +{
18727 + uint16_t mgmt_clk;
18728 +
18729 + if (dtsec_freq < 80) mgmt_clk = 1;
18730 + else if (dtsec_freq < 120) mgmt_clk = 2;
18731 + else if (dtsec_freq < 160) mgmt_clk = 3;
18732 + else if (dtsec_freq < 200) mgmt_clk = 4;
18733 + else if (dtsec_freq < 280) mgmt_clk = 5;
18734 + else if (dtsec_freq < 400) mgmt_clk = 6;
18735 + else mgmt_clk = 7;
18736 +
18737 + return (uint8_t)mgmt_clk;
18738 +}
18739 +
18740 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs)
18741 +{
18742 + /* Reset the management interface */
18743 + iowrite32be(ioread32be(&regs->miimcfg) | MIIMCFG_RESET_MGMT,
18744 + &regs->miimcfg);
18745 + iowrite32be(ioread32be(&regs->miimcfg) & ~MIIMCFG_RESET_MGMT,
18746 + &regs->miimcfg);
18747 +}
18748 +
18749 +
18750 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, uint8_t addr,
18751 + uint8_t reg, uint16_t data, uint16_t dtsec_freq)
18752 +{
18753 + uint32_t tmp;
18754 +
18755 + /* Setup the MII Mgmt clock speed */
18756 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
18757 + wmb();
18758 +
18759 + /* Stop the MII management read cycle */
18760 + iowrite32be(0, &regs->miimcom);
18761 + /* Dummy read to make sure MIIMCOM is written */
18762 + tmp = ioread32be(&regs->miimcom);
18763 + wmb();
18764 +
18765 + /* Setting up MII Management Address Register */
18766 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
18767 + iowrite32be(tmp, &regs->miimadd);
18768 + wmb();
18769 +
18770 + /* Setting up MII Management Control Register with data */
18771 + iowrite32be((uint32_t)data, &regs->miimcon);
18772 + /* Dummy read to make sure MIIMCON is written */
18773 + tmp = ioread32be(&regs->miimcon);
18774 + wmb();
18775 +
18776 + /* Wait until MII management write is complete */
18777 + /* todo: a timeout could be useful here */
18778 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
18779 + /* busy wait */;
18780 +
18781 + return 0;
18782 +}
18783 +
18784 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, uint8_t addr,
18785 + uint8_t reg, uint16_t *data, uint16_t dtsec_freq)
18786 +{
18787 + uint32_t tmp;
18788 +
18789 + /* Setup the MII Mgmt clock speed */
18790 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
18791 + wmb();
18792 +
18793 + /* Setting up the MII Management Address Register */
18794 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
18795 + iowrite32be(tmp, &regs->miimadd);
18796 + wmb();
18797 +
18798 + /* Perform an MII management read cycle */
18799 + iowrite32be(MIIMCOM_READ_CYCLE, &regs->miimcom);
18800 + /* Dummy read to make sure MIIMCOM is written */
18801 + tmp = ioread32be(&regs->miimcom);
18802 + wmb();
18803 +
18804 + /* Wait until MII management read is complete */
18805 + /* todo: a timeout could be useful here */
18806 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
18807 + /* busy wait */;
18808 +
18809 + /* Read MII management status */
18810 + *data = (uint16_t)ioread32be(&regs->miimstat);
18811 + wmb();
18812 +
18813 + iowrite32be(0, &regs->miimcom);
18814 + /* Dummy read to make sure MIIMCOM is written */
18815 + tmp = ioread32be(&regs->miimcom);
18816 +
18817 + if (*data == 0xffff)
18818 + return -ENXIO;
18819 +
18820 + return 0;
18821 +}
18822 +
18823 --- /dev/null
18824 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
18825 @@ -0,0 +1,532 @@
18826 +/*
18827 + * Copyright 2008-2012 Freescale Semiconductor Inc.
18828 + *
18829 + * Redistribution and use in source and binary forms, with or without
18830 + * modification, are permitted provided that the following conditions are met:
18831 + * * Redistributions of source code must retain the above copyright
18832 + * notice, this list of conditions and the following disclaimer.
18833 + * * Redistributions in binary form must reproduce the above copyright
18834 + * notice, this list of conditions and the following disclaimer in the
18835 + * documentation and/or other materials provided with the distribution.
18836 + * * Neither the name of Freescale Semiconductor nor the
18837 + * names of its contributors may be used to endorse or promote products
18838 + * derived from this software without specific prior written permission.
18839 + *
18840 + *
18841 + * ALTERNATIVELY, this software may be distributed under the terms of the
18842 + * GNU General Public License ("GPL") as published by the Free Software
18843 + * Foundation, either version 2 of that License or (at your option) any
18844 + * later version.
18845 + *
18846 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18847 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18848 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18849 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18850 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18851 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18852 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18853 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18854 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18855 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18856 + */
18857 +
18858 +
18859 +#include "fsl_fman_memac.h"
18860 +
18861 +
18862 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask)
18863 +{
18864 + return ioread32be(&regs->ievent) & ev_mask;
18865 +}
18866 +
18867 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs)
18868 +{
18869 + return ioread32be(&regs->imask);
18870 +}
18871 +
18872 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask)
18873 +{
18874 + iowrite32be(ev_mask, &regs->ievent);
18875 +}
18876 +
18877 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val)
18878 +{
18879 + uint32_t tmp;
18880 +
18881 + tmp = ioread32be(&regs->command_config);
18882 +
18883 + if (val)
18884 + tmp |= CMD_CFG_PROMIS_EN;
18885 + else
18886 + tmp &= ~CMD_CFG_PROMIS_EN;
18887 +
18888 + iowrite32be(tmp, &regs->command_config);
18889 +}
18890 +
18891 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
18892 + uint8_t paddr_num)
18893 +{
18894 + if (paddr_num == 0) {
18895 + iowrite32be(0, &regs->mac_addr0.mac_addr_l);
18896 + iowrite32be(0, &regs->mac_addr0.mac_addr_u);
18897 + } else {
18898 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_l);
18899 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_u);
18900 + }
18901 +}
18902 +
18903 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
18904 + uint8_t *adr,
18905 + uint8_t paddr_num)
18906 +{
18907 + uint32_t tmp0, tmp1;
18908 +
18909 + tmp0 = (uint32_t)(adr[0] |
18910 + adr[1] << 8 |
18911 + adr[2] << 16 |
18912 + adr[3] << 24);
18913 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
18914 +
18915 + if (paddr_num == 0) {
18916 + iowrite32be(tmp0, &regs->mac_addr0.mac_addr_l);
18917 + iowrite32be(tmp1, &regs->mac_addr0.mac_addr_u);
18918 + } else {
18919 + iowrite32be(tmp0, &regs->mac_addr[paddr_num-1].mac_addr_l);
18920 + iowrite32be(tmp1, &regs->mac_addr[paddr_num-1].mac_addr_u);
18921 + }
18922 +}
18923 +
18924 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
18925 +{
18926 + uint32_t tmp;
18927 +
18928 + tmp = ioread32be(&regs->command_config);
18929 +
18930 + if (apply_rx)
18931 + tmp |= CMD_CFG_RX_EN;
18932 +
18933 + if (apply_tx)
18934 + tmp |= CMD_CFG_TX_EN;
18935 +
18936 + iowrite32be(tmp, &regs->command_config);
18937 +}
18938 +
18939 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
18940 +{
18941 + uint32_t tmp;
18942 +
18943 + tmp = ioread32be(&regs->command_config);
18944 +
18945 + if (apply_rx)
18946 + tmp &= ~CMD_CFG_RX_EN;
18947 +
18948 + if (apply_tx)
18949 + tmp &= ~CMD_CFG_TX_EN;
18950 +
18951 + iowrite32be(tmp, &regs->command_config);
18952 +}
18953 +
18954 +void fman_memac_reset_stat(struct memac_regs *regs)
18955 +{
18956 + uint32_t tmp;
18957 +
18958 + tmp = ioread32be(&regs->statn_config);
18959 +
18960 + tmp |= STATS_CFG_CLR;
18961 +
18962 + iowrite32be(tmp, &regs->statn_config);
18963 +
18964 + while (ioread32be(&regs->statn_config) & STATS_CFG_CLR);
18965 +}
18966 +
18967 +void fman_memac_reset(struct memac_regs *regs)
18968 +{
18969 + uint32_t tmp;
18970 +
18971 + tmp = ioread32be(&regs->command_config);
18972 +
18973 + tmp |= CMD_CFG_SW_RESET;
18974 +
18975 + iowrite32be(tmp, &regs->command_config);
18976 +
18977 + while (ioread32be(&regs->command_config) & CMD_CFG_SW_RESET);
18978 +}
18979 +
18980 +int fman_memac_init(struct memac_regs *regs,
18981 + struct memac_cfg *cfg,
18982 + enum enet_interface enet_interface,
18983 + enum enet_speed enet_speed,
18984 + bool slow_10g_if,
18985 + uint32_t exceptions)
18986 +{
18987 + uint32_t tmp;
18988 +
18989 + /* Config */
18990 + tmp = 0;
18991 + if (cfg->wan_mode_enable)
18992 + tmp |= CMD_CFG_WAN_MODE;
18993 + if (cfg->promiscuous_mode_enable)
18994 + tmp |= CMD_CFG_PROMIS_EN;
18995 + if (cfg->pause_forward_enable)
18996 + tmp |= CMD_CFG_PAUSE_FWD;
18997 + if (cfg->pause_ignore)
18998 + tmp |= CMD_CFG_PAUSE_IGNORE;
18999 + if (cfg->tx_addr_ins_enable)
19000 + tmp |= CMD_CFG_TX_ADDR_INS;
19001 + if (cfg->loopback_enable)
19002 + tmp |= CMD_CFG_LOOPBACK_EN;
19003 + if (cfg->cmd_frame_enable)
19004 + tmp |= CMD_CFG_CNT_FRM_EN;
19005 + if (cfg->send_idle_enable)
19006 + tmp |= CMD_CFG_SEND_IDLE;
19007 + if (cfg->no_length_check_enable)
19008 + tmp |= CMD_CFG_NO_LEN_CHK;
19009 + if (cfg->rx_sfd_any)
19010 + tmp |= CMD_CFG_SFD_ANY;
19011 + if (cfg->pad_enable)
19012 + tmp |= CMD_CFG_TX_PAD_EN;
19013 + if (cfg->wake_on_lan)
19014 + tmp |= CMD_CFG_MG;
19015 +
19016 + tmp |= CMD_CFG_CRC_FWD;
19017 +
19018 + iowrite32be(tmp, &regs->command_config);
19019 +
19020 + /* Max Frame Length */
19021 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
19022 +
19023 + /* Pause Time */
19024 + iowrite32be((uint32_t)cfg->pause_quanta, &regs->pause_quanta[0]);
19025 + iowrite32be((uint32_t)0, &regs->pause_thresh[0]);
19026 +
19027 + /* IF_MODE */
19028 + tmp = 0;
19029 + switch (enet_interface) {
19030 + case E_ENET_IF_XGMII:
19031 + case E_ENET_IF_XFI:
19032 + tmp |= IF_MODE_XGMII;
19033 + break;
19034 + default:
19035 + tmp |= IF_MODE_GMII;
19036 + if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable)
19037 + tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
19038 + }
19039 + iowrite32be(tmp, &regs->if_mode);
19040 +
19041 + /* TX_FIFO_SECTIONS */
19042 + tmp = 0;
19043 + if (enet_interface == E_ENET_IF_XGMII ||
19044 + enet_interface == E_ENET_IF_XFI) {
19045 + if(slow_10g_if) {
19046 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
19047 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19048 + } else {
19049 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
19050 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19051 + }
19052 + } else {
19053 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
19054 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
19055 + }
19056 + iowrite32be(tmp, &regs->tx_fifo_sections);
19057 +
19058 + /* clear all pending events and set-up interrupts */
19059 + fman_memac_ack_event(regs, 0xffffffff);
19060 + fman_memac_set_exception(regs, exceptions, TRUE);
19061 +
19062 + return 0;
19063 +}
19064 +
19065 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable)
19066 +{
19067 + uint32_t tmp;
19068 +
19069 + tmp = ioread32be(&regs->imask);
19070 + if (enable)
19071 + tmp |= val;
19072 + else
19073 + tmp &= ~val;
19074 +
19075 + iowrite32be(tmp, &regs->imask);
19076 +}
19077 +
19078 +void fman_memac_reset_filter_table(struct memac_regs *regs)
19079 +{
19080 + uint32_t i;
19081 + for (i = 0; i < 64; i++)
19082 + iowrite32be(i & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19083 +}
19084 +
19085 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc)
19086 +{
19087 + iowrite32be(crc | HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19088 +}
19089 +
19090 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val)
19091 +{
19092 + iowrite32be(val, &regs->hashtable_ctrl);
19093 +}
19094 +
19095 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs)
19096 +{
19097 + uint32_t tmp;
19098 +
19099 + tmp = ioread32be(&regs->maxfrm);
19100 +
19101 + return(uint16_t)tmp;
19102 +}
19103 +
19104 +
19105 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
19106 + uint8_t priority,
19107 + uint16_t pause_time,
19108 + uint16_t thresh_time)
19109 +{
19110 + uint32_t tmp;
19111 +
19112 + tmp = ioread32be(&regs->tx_fifo_sections);
19113 +
19114 + if (priority == 0xff) {
19115 + GET_TX_EMPTY_DEFAULT_VALUE(tmp);
19116 + iowrite32be(tmp, &regs->tx_fifo_sections);
19117 +
19118 + tmp = ioread32be(&regs->command_config);
19119 + tmp &= ~CMD_CFG_PFC_MODE;
19120 + priority = 0;
19121 + } else {
19122 + GET_TX_EMPTY_PFC_VALUE(tmp);
19123 + iowrite32be(tmp, &regs->tx_fifo_sections);
19124 +
19125 + tmp = ioread32be(&regs->command_config);
19126 + tmp |= CMD_CFG_PFC_MODE;
19127 + }
19128 +
19129 + iowrite32be(tmp, &regs->command_config);
19130 +
19131 + tmp = ioread32be(&regs->pause_quanta[priority / 2]);
19132 + if (priority % 2)
19133 + tmp &= 0x0000FFFF;
19134 + else
19135 + tmp &= 0xFFFF0000;
19136 + tmp |= ((uint32_t)pause_time << (16 * (priority % 2)));
19137 + iowrite32be(tmp, &regs->pause_quanta[priority / 2]);
19138 +
19139 + tmp = ioread32be(&regs->pause_thresh[priority / 2]);
19140 + if (priority % 2)
19141 + tmp &= 0x0000FFFF;
19142 + else
19143 + tmp &= 0xFFFF0000;
19144 + tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2)));
19145 + iowrite32be(tmp, &regs->pause_thresh[priority / 2]);
19146 +}
19147 +
19148 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable)
19149 +{
19150 + uint32_t tmp;
19151 +
19152 + tmp = ioread32be(&regs->command_config);
19153 + if (enable)
19154 + tmp |= CMD_CFG_PAUSE_IGNORE;
19155 + else
19156 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
19157 +
19158 + iowrite32be(tmp, &regs->command_config);
19159 +}
19160 +
19161 +void fman_memac_set_wol(struct memac_regs *regs, bool enable)
19162 +{
19163 + uint32_t tmp;
19164 +
19165 + tmp = ioread32be(&regs->command_config);
19166 +
19167 + if (enable)
19168 + tmp |= CMD_CFG_MG;
19169 + else
19170 + tmp &= ~CMD_CFG_MG;
19171 +
19172 + iowrite32be(tmp, &regs->command_config);
19173 +}
19174 +
19175 +#define GET_MEMAC_CNTR_64(bn) \
19176 + (ioread32be(&regs->bn ## _l) | \
19177 + ((uint64_t)ioread32be(&regs->bn ## _u) << 32))
19178 +
19179 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
19180 + enum memac_counters reg_name)
19181 +{
19182 + uint64_t ret_val;
19183 +
19184 + switch (reg_name) {
19185 + case E_MEMAC_COUNTER_R64:
19186 + ret_val = GET_MEMAC_CNTR_64(r64);
19187 + break;
19188 + case E_MEMAC_COUNTER_T64:
19189 + ret_val = GET_MEMAC_CNTR_64(t64);
19190 + break;
19191 + case E_MEMAC_COUNTER_R127:
19192 + ret_val = GET_MEMAC_CNTR_64(r127);
19193 + break;
19194 + case E_MEMAC_COUNTER_T127:
19195 + ret_val = GET_MEMAC_CNTR_64(t127);
19196 + break;
19197 + case E_MEMAC_COUNTER_R255:
19198 + ret_val = GET_MEMAC_CNTR_64(r255);
19199 + break;
19200 + case E_MEMAC_COUNTER_T255:
19201 + ret_val = GET_MEMAC_CNTR_64(t255);
19202 + break;
19203 + case E_MEMAC_COUNTER_R511:
19204 + ret_val = GET_MEMAC_CNTR_64(r511);
19205 + break;
19206 + case E_MEMAC_COUNTER_T511:
19207 + ret_val = GET_MEMAC_CNTR_64(t511);
19208 + break;
19209 + case E_MEMAC_COUNTER_R1023:
19210 + ret_val = GET_MEMAC_CNTR_64(r1023);
19211 + break;
19212 + case E_MEMAC_COUNTER_T1023:
19213 + ret_val = GET_MEMAC_CNTR_64(t1023);
19214 + break;
19215 + case E_MEMAC_COUNTER_R1518:
19216 + ret_val = GET_MEMAC_CNTR_64(r1518);
19217 + break;
19218 + case E_MEMAC_COUNTER_T1518:
19219 + ret_val = GET_MEMAC_CNTR_64(t1518);
19220 + break;
19221 + case E_MEMAC_COUNTER_R1519X:
19222 + ret_val = GET_MEMAC_CNTR_64(r1519x);
19223 + break;
19224 + case E_MEMAC_COUNTER_T1519X:
19225 + ret_val = GET_MEMAC_CNTR_64(t1519x);
19226 + break;
19227 + case E_MEMAC_COUNTER_RFRG:
19228 + ret_val = GET_MEMAC_CNTR_64(rfrg);
19229 + break;
19230 + case E_MEMAC_COUNTER_RJBR:
19231 + ret_val = GET_MEMAC_CNTR_64(rjbr);
19232 + break;
19233 + case E_MEMAC_COUNTER_RDRP:
19234 + ret_val = GET_MEMAC_CNTR_64(rdrp);
19235 + break;
19236 + case E_MEMAC_COUNTER_RALN:
19237 + ret_val = GET_MEMAC_CNTR_64(raln);
19238 + break;
19239 + case E_MEMAC_COUNTER_TUND:
19240 + ret_val = GET_MEMAC_CNTR_64(tund);
19241 + break;
19242 + case E_MEMAC_COUNTER_ROVR:
19243 + ret_val = GET_MEMAC_CNTR_64(rovr);
19244 + break;
19245 + case E_MEMAC_COUNTER_RXPF:
19246 + ret_val = GET_MEMAC_CNTR_64(rxpf);
19247 + break;
19248 + case E_MEMAC_COUNTER_TXPF:
19249 + ret_val = GET_MEMAC_CNTR_64(txpf);
19250 + break;
19251 + case E_MEMAC_COUNTER_ROCT:
19252 + ret_val = GET_MEMAC_CNTR_64(roct);
19253 + break;
19254 + case E_MEMAC_COUNTER_RMCA:
19255 + ret_val = GET_MEMAC_CNTR_64(rmca);
19256 + break;
19257 + case E_MEMAC_COUNTER_RBCA:
19258 + ret_val = GET_MEMAC_CNTR_64(rbca);
19259 + break;
19260 + case E_MEMAC_COUNTER_RPKT:
19261 + ret_val = GET_MEMAC_CNTR_64(rpkt);
19262 + break;
19263 + case E_MEMAC_COUNTER_RUCA:
19264 + ret_val = GET_MEMAC_CNTR_64(ruca);
19265 + break;
19266 + case E_MEMAC_COUNTER_RERR:
19267 + ret_val = GET_MEMAC_CNTR_64(rerr);
19268 + break;
19269 + case E_MEMAC_COUNTER_TOCT:
19270 + ret_val = GET_MEMAC_CNTR_64(toct);
19271 + break;
19272 + case E_MEMAC_COUNTER_TMCA:
19273 + ret_val = GET_MEMAC_CNTR_64(tmca);
19274 + break;
19275 + case E_MEMAC_COUNTER_TBCA:
19276 + ret_val = GET_MEMAC_CNTR_64(tbca);
19277 + break;
19278 + case E_MEMAC_COUNTER_TUCA:
19279 + ret_val = GET_MEMAC_CNTR_64(tuca);
19280 + break;
19281 + case E_MEMAC_COUNTER_TERR:
19282 + ret_val = GET_MEMAC_CNTR_64(terr);
19283 + break;
19284 + default:
19285 + ret_val = 0;
19286 + }
19287 +
19288 + return ret_val;
19289 +}
19290 +
19291 +void fman_memac_adjust_link(struct memac_regs *regs,
19292 + enum enet_interface iface_mode,
19293 + enum enet_speed speed, bool full_dx)
19294 +{
19295 + uint32_t tmp;
19296 +
19297 + tmp = ioread32be(&regs->if_mode);
19298 +
19299 + if (full_dx)
19300 + tmp &= ~IF_MODE_HD;
19301 + else
19302 + tmp |= IF_MODE_HD;
19303 +
19304 + if (iface_mode == E_ENET_IF_RGMII) {
19305 + /* Configure RGMII in manual mode */
19306 + tmp &= ~IF_MODE_RGMII_AUTO;
19307 + tmp &= ~IF_MODE_RGMII_SP_MASK;
19308 +
19309 + if (full_dx)
19310 + tmp |= IF_MODE_RGMII_FD;
19311 + else
19312 + tmp &= ~IF_MODE_RGMII_FD;
19313 +
19314 + switch (speed) {
19315 + case E_ENET_SPEED_1000:
19316 + tmp |= IF_MODE_RGMII_1000;
19317 + break;
19318 + case E_ENET_SPEED_100:
19319 + tmp |= IF_MODE_RGMII_100;
19320 + break;
19321 + case E_ENET_SPEED_10:
19322 + tmp |= IF_MODE_RGMII_10;
19323 + break;
19324 + default:
19325 + break;
19326 + }
19327 + }
19328 +
19329 + iowrite32be(tmp, &regs->if_mode);
19330 +}
19331 +
19332 +void fman_memac_defconfig(struct memac_cfg *cfg)
19333 +{
19334 + cfg->reset_on_init = FALSE;
19335 + cfg->wan_mode_enable = FALSE;
19336 + cfg->promiscuous_mode_enable = FALSE;
19337 + cfg->pause_forward_enable = FALSE;
19338 + cfg->pause_ignore = FALSE;
19339 + cfg->tx_addr_ins_enable = FALSE;
19340 + cfg->loopback_enable = FALSE;
19341 + cfg->cmd_frame_enable = FALSE;
19342 + cfg->rx_error_discard = FALSE;
19343 + cfg->send_idle_enable = FALSE;
19344 + cfg->no_length_check_enable = TRUE;
19345 + cfg->lgth_check_nostdr = FALSE;
19346 + cfg->time_stamp_enable = FALSE;
19347 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
19348 + cfg->max_frame_length = DEFAULT_FRAME_LENGTH;
19349 + cfg->pause_quanta = DEFAULT_PAUSE_QUANTA;
19350 + cfg->pad_enable = TRUE;
19351 + cfg->phy_tx_ena_on = FALSE;
19352 + cfg->rx_sfd_any = FALSE;
19353 + cfg->rx_pbl_fwd = FALSE;
19354 + cfg->tx_pbl_fwd = FALSE;
19355 + cfg->debug_mode = FALSE;
19356 + cfg->wake_on_lan = FALSE;
19357 +}
19358 --- /dev/null
19359 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
19360 @@ -0,0 +1,213 @@
19361 +/*
19362 + * Copyright 2008-2013 Freescale Semiconductor Inc.
19363 + *
19364 + * Redistribution and use in source and binary forms, with or without
19365 + * modification, are permitted provided that the following conditions are met:
19366 + * * Redistributions of source code must retain the above copyright
19367 + * notice, this list of conditions and the following disclaimer.
19368 + * * Redistributions in binary form must reproduce the above copyright
19369 + * notice, this list of conditions and the following disclaimer in the
19370 + * documentation and/or other materials provided with the distribution.
19371 + * * Neither the name of Freescale Semiconductor nor the
19372 + * names of its contributors may be used to endorse or promote products
19373 + * derived from this software without specific prior written permission.
19374 + *
19375 + *
19376 + * ALTERNATIVELY, this software may be distributed under the terms of the
19377 + * GNU General Public License ("GPL") as published by the Free Software
19378 + * Foundation, either version 2 of that License or (at your option) any
19379 + * later version.
19380 + *
19381 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19382 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19383 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19384 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19385 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19386 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19387 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19388 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19389 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19390 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19391 + */
19392 +
19393 +
19394 +#include "fsl_fman_memac_mii_acc.h"
19395 +
19396 +static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19397 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19398 +{
19399 + uint32_t tmp_reg;
19400 +
19401 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19402 + /* Leave only MDIO_CLK_DIV bits set on */
19403 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19404 + /* Set maximum MDIO_HOLD value to allow phy to see
19405 + change of data signal */
19406 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19407 + /* Add 10G interface mode */
19408 + tmp_reg |= MDIO_CFG_ENC45;
19409 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19410 +
19411 + /* Wait for command completion */
19412 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19413 + udelay(1);
19414 +
19415 + /* Specify phy and register to be accessed */
19416 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19417 + iowrite32be(reg, &mii_regs->mdio_addr);
19418 + wmb();
19419 +
19420 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19421 + udelay(1);
19422 +
19423 + /* Write data */
19424 + iowrite32be(data, &mii_regs->mdio_data);
19425 + wmb();
19426 +
19427 + /* Wait for write transaction end */
19428 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19429 + udelay(1);
19430 +}
19431 +
19432 +static uint32_t read_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19433 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19434 +{
19435 + uint32_t tmp_reg;
19436 +
19437 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19438 + /* Leave only MDIO_CLK_DIV bits set on */
19439 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19440 + /* Set maximum MDIO_HOLD value to allow phy to see
19441 + change of data signal */
19442 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19443 + /* Add 10G interface mode */
19444 + tmp_reg |= MDIO_CFG_ENC45;
19445 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19446 +
19447 + /* Wait for command completion */
19448 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19449 + udelay(1);
19450 +
19451 + /* Specify phy and register to be accessed */
19452 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19453 + iowrite32be(reg, &mii_regs->mdio_addr);
19454 + wmb();
19455 +
19456 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19457 + udelay(1);
19458 +
19459 + /* Read cycle */
19460 + tmp_reg = phy_addr;
19461 + tmp_reg |= MDIO_CTL_READ;
19462 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19463 + wmb();
19464 +
19465 + /* Wait for data to be available */
19466 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19467 + udelay(1);
19468 +
19469 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19470 +
19471 + /* Check if there was an error */
19472 + return ioread32be(&mii_regs->mdio_cfg);
19473 +}
19474 +
19475 +static void write_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19476 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19477 +{
19478 + uint32_t tmp_reg;
19479 +
19480 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19481 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19482 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
19483 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19484 +
19485 + /* Wait for command completion */
19486 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19487 + udelay(1);
19488 +
19489 + /* Write transaction */
19490 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19491 + tmp_reg |= reg;
19492 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19493 +
19494 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19495 + udelay(1);
19496 +
19497 + iowrite32be(data, &mii_regs->mdio_data);
19498 +
19499 + wmb();
19500 +
19501 + /* Wait for write transaction to end */
19502 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19503 + udelay(1);
19504 +}
19505 +
19506 +static uint32_t read_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19507 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19508 +{
19509 + uint32_t tmp_reg;
19510 +
19511 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19512 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19513 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
19514 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19515 +
19516 + /* Wait for command completion */
19517 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19518 + udelay(1);
19519 +
19520 + /* Read transaction */
19521 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19522 + tmp_reg |= reg;
19523 + tmp_reg |= MDIO_CTL_READ;
19524 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19525 +
19526 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19527 + udelay(1);
19528 +
19529 + /* Wait for data to be available */
19530 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19531 + udelay(1);
19532 +
19533 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19534 +
19535 + /* Check error */
19536 + return ioread32be(&mii_regs->mdio_cfg);
19537 +}
19538 +
19539 +/*****************************************************************************/
19540 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19541 + uint8_t phy_addr, uint8_t reg, uint16_t data,
19542 + enum enet_speed enet_speed)
19543 +{
19544 + /* Figure out interface type - 10G vs 1G.
19545 + In 10G interface both phy_addr and devAddr present. */
19546 + if (enet_speed == E_ENET_SPEED_10000)
19547 + write_phy_reg_10g(mii_regs, phy_addr, reg, data);
19548 + else
19549 + write_phy_reg_1g(mii_regs, phy_addr, reg, data);
19550 +
19551 + return 0;
19552 +}
19553 +
19554 +/*****************************************************************************/
19555 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19556 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
19557 + enum enet_speed enet_speed)
19558 +{
19559 + uint32_t ans;
19560 + /* Figure out interface type - 10G vs 1G.
19561 + In 10G interface both phy_addr and devAddr present. */
19562 + if (enet_speed == E_ENET_SPEED_10000)
19563 + ans = read_phy_reg_10g(mii_regs, phy_addr, reg, data);
19564 + else
19565 + ans = read_phy_reg_1g(mii_regs, phy_addr, reg, data);
19566 +
19567 + if (ans & MDIO_CFG_READ_ERR)
19568 + return -EINVAL;
19569 + return 0;
19570 +}
19571 +
19572 +/* ......................................................................... */
19573 +
19574 --- /dev/null
19575 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
19576 @@ -0,0 +1,367 @@
19577 +/*
19578 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19579 + *
19580 + * Redistribution and use in source and binary forms, with or without
19581 + * modification, are permitted provided that the following conditions are met:
19582 + * * Redistributions of source code must retain the above copyright
19583 + * notice, this list of conditions and the following disclaimer.
19584 + * * Redistributions in binary form must reproduce the above copyright
19585 + * notice, this list of conditions and the following disclaimer in the
19586 + * documentation and/or other materials provided with the distribution.
19587 + * * Neither the name of Freescale Semiconductor nor the
19588 + * names of its contributors may be used to endorse or promote products
19589 + * derived from this software without specific prior written permission.
19590 + *
19591 + *
19592 + * ALTERNATIVELY, this software may be distributed under the terms of the
19593 + * GNU General Public License ("GPL") as published by the Free Software
19594 + * Foundation, either version 2 of that License or (at your option) any
19595 + * later version.
19596 + *
19597 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19598 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19599 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19600 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19601 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19602 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19603 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19604 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19605 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19606 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19607 + */
19608 +
19609 +
19610 +#include "fsl_fman_tgec.h"
19611 +
19612 +
19613 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr)
19614 +{
19615 + uint32_t tmp0, tmp1;
19616 +
19617 + tmp0 = (uint32_t)(adr[0] |
19618 + adr[1] << 8 |
19619 + adr[2] << 16 |
19620 + adr[3] << 24);
19621 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19622 + iowrite32be(tmp0, &regs->mac_addr_0);
19623 + iowrite32be(tmp1, &regs->mac_addr_1);
19624 +}
19625 +
19626 +void fman_tgec_reset_stat(struct tgec_regs *regs)
19627 +{
19628 + uint32_t tmp;
19629 +
19630 + tmp = ioread32be(&regs->command_config);
19631 +
19632 + tmp |= CMD_CFG_STAT_CLR;
19633 +
19634 + iowrite32be(tmp, &regs->command_config);
19635 +
19636 + while (ioread32be(&regs->command_config) & CMD_CFG_STAT_CLR) ;
19637 +}
19638 +
19639 +#define GET_TGEC_CNTR_64(bn) \
19640 + (((uint64_t)ioread32be(&regs->bn ## _u) << 32) | \
19641 + ioread32be(&regs->bn ## _l))
19642 +
19643 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name)
19644 +{
19645 + uint64_t ret_val;
19646 +
19647 + switch (reg_name) {
19648 + case E_TGEC_COUNTER_R64:
19649 + ret_val = GET_TGEC_CNTR_64(r64);
19650 + break;
19651 + case E_TGEC_COUNTER_R127:
19652 + ret_val = GET_TGEC_CNTR_64(r127);
19653 + break;
19654 + case E_TGEC_COUNTER_R255:
19655 + ret_val = GET_TGEC_CNTR_64(r255);
19656 + break;
19657 + case E_TGEC_COUNTER_R511:
19658 + ret_val = GET_TGEC_CNTR_64(r511);
19659 + break;
19660 + case E_TGEC_COUNTER_R1023:
19661 + ret_val = GET_TGEC_CNTR_64(r1023);
19662 + break;
19663 + case E_TGEC_COUNTER_R1518:
19664 + ret_val = GET_TGEC_CNTR_64(r1518);
19665 + break;
19666 + case E_TGEC_COUNTER_R1519X:
19667 + ret_val = GET_TGEC_CNTR_64(r1519x);
19668 + break;
19669 + case E_TGEC_COUNTER_TRFRG:
19670 + ret_val = GET_TGEC_CNTR_64(trfrg);
19671 + break;
19672 + case E_TGEC_COUNTER_TRJBR:
19673 + ret_val = GET_TGEC_CNTR_64(trjbr);
19674 + break;
19675 + case E_TGEC_COUNTER_RDRP:
19676 + ret_val = GET_TGEC_CNTR_64(rdrp);
19677 + break;
19678 + case E_TGEC_COUNTER_RALN:
19679 + ret_val = GET_TGEC_CNTR_64(raln);
19680 + break;
19681 + case E_TGEC_COUNTER_TRUND:
19682 + ret_val = GET_TGEC_CNTR_64(trund);
19683 + break;
19684 + case E_TGEC_COUNTER_TROVR:
19685 + ret_val = GET_TGEC_CNTR_64(trovr);
19686 + break;
19687 + case E_TGEC_COUNTER_RXPF:
19688 + ret_val = GET_TGEC_CNTR_64(rxpf);
19689 + break;
19690 + case E_TGEC_COUNTER_TXPF:
19691 + ret_val = GET_TGEC_CNTR_64(txpf);
19692 + break;
19693 + case E_TGEC_COUNTER_ROCT:
19694 + ret_val = GET_TGEC_CNTR_64(roct);
19695 + break;
19696 + case E_TGEC_COUNTER_RMCA:
19697 + ret_val = GET_TGEC_CNTR_64(rmca);
19698 + break;
19699 + case E_TGEC_COUNTER_RBCA:
19700 + ret_val = GET_TGEC_CNTR_64(rbca);
19701 + break;
19702 + case E_TGEC_COUNTER_RPKT:
19703 + ret_val = GET_TGEC_CNTR_64(rpkt);
19704 + break;
19705 + case E_TGEC_COUNTER_RUCA:
19706 + ret_val = GET_TGEC_CNTR_64(ruca);
19707 + break;
19708 + case E_TGEC_COUNTER_RERR:
19709 + ret_val = GET_TGEC_CNTR_64(rerr);
19710 + break;
19711 + case E_TGEC_COUNTER_TOCT:
19712 + ret_val = GET_TGEC_CNTR_64(toct);
19713 + break;
19714 + case E_TGEC_COUNTER_TMCA:
19715 + ret_val = GET_TGEC_CNTR_64(tmca);
19716 + break;
19717 + case E_TGEC_COUNTER_TBCA:
19718 + ret_val = GET_TGEC_CNTR_64(tbca);
19719 + break;
19720 + case E_TGEC_COUNTER_TUCA:
19721 + ret_val = GET_TGEC_CNTR_64(tuca);
19722 + break;
19723 + case E_TGEC_COUNTER_TERR:
19724 + ret_val = GET_TGEC_CNTR_64(terr);
19725 + break;
19726 + default:
19727 + ret_val = 0;
19728 + }
19729 +
19730 + return ret_val;
19731 +}
19732 +
19733 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19734 +{
19735 + uint32_t tmp;
19736 +
19737 + tmp = ioread32be(&regs->command_config);
19738 + if (apply_rx)
19739 + tmp |= CMD_CFG_RX_EN;
19740 + if (apply_tx)
19741 + tmp |= CMD_CFG_TX_EN;
19742 + iowrite32be(tmp, &regs->command_config);
19743 +}
19744 +
19745 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19746 +{
19747 + uint32_t tmp_reg_32;
19748 +
19749 + tmp_reg_32 = ioread32be(&regs->command_config);
19750 + if (apply_rx)
19751 + tmp_reg_32 &= ~CMD_CFG_RX_EN;
19752 + if (apply_tx)
19753 + tmp_reg_32 &= ~CMD_CFG_TX_EN;
19754 + iowrite32be(tmp_reg_32, &regs->command_config);
19755 +}
19756 +
19757 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val)
19758 +{
19759 + uint32_t tmp;
19760 +
19761 + tmp = ioread32be(&regs->command_config);
19762 + if (val)
19763 + tmp |= CMD_CFG_PROMIS_EN;
19764 + else
19765 + tmp &= ~CMD_CFG_PROMIS_EN;
19766 + iowrite32be(tmp, &regs->command_config);
19767 +}
19768 +
19769 +void fman_tgec_reset_filter_table(struct tgec_regs *regs)
19770 +{
19771 + uint32_t i;
19772 + for (i = 0; i < 512; i++)
19773 + iowrite32be(i & ~TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
19774 +}
19775 +
19776 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc)
19777 +{
19778 + uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
19779 + iowrite32be(hash | TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
19780 +}
19781 +
19782 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value)
19783 +{
19784 + iowrite32be(value, &regs->hashtable_ctrl);
19785 +}
19786 +
19787 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time)
19788 +{
19789 + iowrite32be((uint32_t)pause_time, &regs->pause_quant);
19790 +}
19791 +
19792 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en)
19793 +{
19794 + uint32_t tmp;
19795 +
19796 + tmp = ioread32be(&regs->command_config);
19797 + if (en)
19798 + tmp |= CMD_CFG_PAUSE_IGNORE;
19799 + else
19800 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
19801 + iowrite32be(tmp, &regs->command_config);
19802 +}
19803 +
19804 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en)
19805 +{
19806 + uint32_t tmp;
19807 +
19808 + tmp = ioread32be(&regs->command_config);
19809 + if (en)
19810 + tmp |= CMD_CFG_EN_TIMESTAMP;
19811 + else
19812 + tmp &= ~CMD_CFG_EN_TIMESTAMP;
19813 + iowrite32be(tmp, &regs->command_config);
19814 +}
19815 +
19816 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask)
19817 +{
19818 + return ioread32be(&regs->ievent) & ev_mask;
19819 +}
19820 +
19821 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask)
19822 +{
19823 + iowrite32be(ev_mask, &regs->ievent);
19824 +}
19825 +
19826 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs)
19827 +{
19828 + return ioread32be(&regs->imask);
19829 +}
19830 +
19831 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr)
19832 +{
19833 + uint32_t tmp0, tmp1;
19834 +
19835 + tmp0 = (uint32_t)(adr[0] |
19836 + adr[1] << 8 |
19837 + adr[2] << 16 |
19838 + adr[3] << 24);
19839 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19840 + iowrite32be(tmp0, &regs->mac_addr_2);
19841 + iowrite32be(tmp1, &regs->mac_addr_3);
19842 +}
19843 +
19844 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs)
19845 +{
19846 + iowrite32be(0, &regs->mac_addr_2);
19847 + iowrite32be(0, &regs->mac_addr_3);
19848 +}
19849 +
19850 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs)
19851 +{
19852 + return ioread32be(&regs->tgec_id);
19853 +}
19854 +
19855 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
19856 +{
19857 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
19858 +}
19859 +
19860 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
19861 +{
19862 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
19863 +}
19864 +
19865 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs)
19866 +{
19867 + return (uint16_t) ioread32be(&regs->maxfrm);
19868 +}
19869 +
19870 +void fman_tgec_defconfig(struct tgec_cfg *cfg)
19871 +{
19872 + cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE;
19873 + cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE;
19874 + cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE;
19875 + cfg->pause_ignore = DEFAULT_PAUSE_IGNORE;
19876 + cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE;
19877 + cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE;
19878 + cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE;
19879 + cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD;
19880 + cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE;
19881 + cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE;
19882 + cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR;
19883 + cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE;
19884 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
19885 + cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
19886 + cfg->pause_quant = DEFAULT_PAUSE_QUANT;
19887 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
19888 + cfg->skip_fman11_workaround = FALSE;
19889 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
19890 +}
19891 +
19892 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
19893 + uint32_t exception_mask)
19894 +{
19895 + uint32_t tmp;
19896 +
19897 + /* Config */
19898 + tmp = 0x40; /* CRC forward */
19899 + if (cfg->wan_mode_enable)
19900 + tmp |= CMD_CFG_WAN_MODE;
19901 + if (cfg->promiscuous_mode_enable)
19902 + tmp |= CMD_CFG_PROMIS_EN;
19903 + if (cfg->pause_forward_enable)
19904 + tmp |= CMD_CFG_PAUSE_FWD;
19905 + if (cfg->pause_ignore)
19906 + tmp |= CMD_CFG_PAUSE_IGNORE;
19907 + if (cfg->tx_addr_ins_enable)
19908 + tmp |= CMD_CFG_TX_ADDR_INS;
19909 + if (cfg->loopback_enable)
19910 + tmp |= CMD_CFG_LOOPBACK_EN;
19911 + if (cfg->cmd_frame_enable)
19912 + tmp |= CMD_CFG_CMD_FRM_EN;
19913 + if (cfg->rx_error_discard)
19914 + tmp |= CMD_CFG_RX_ER_DISC;
19915 + if (cfg->send_idle_enable)
19916 + tmp |= CMD_CFG_SEND_IDLE;
19917 + if (cfg->no_length_check_enable)
19918 + tmp |= CMD_CFG_NO_LEN_CHK;
19919 + if (cfg->time_stamp_enable)
19920 + tmp |= CMD_CFG_EN_TIMESTAMP;
19921 + iowrite32be(tmp, &regs->command_config);
19922 +
19923 + /* Max Frame Length */
19924 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
19925 + /* Pause Time */
19926 + iowrite32be(cfg->pause_quant, &regs->pause_quant);
19927 +
19928 + /* clear all pending events and set-up interrupts */
19929 + fman_tgec_ack_event(regs, 0xffffffff);
19930 + fman_tgec_enable_interrupt(regs, exception_mask);
19931 +
19932 + return 0;
19933 +}
19934 +
19935 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs)
19936 +{
19937 + uint32_t tmp;
19938 +
19939 + /* restore the default tx ipg Length */
19940 + tmp = (ioread32be(&regs->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12;
19941 +
19942 + iowrite32be(tmp, &regs->tx_ipg_len);
19943 +}
19944 --- /dev/null
19945 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
19946 @@ -0,0 +1,1153 @@
19947 +/*
19948 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19949 + *
19950 + * Redistribution and use in source and binary forms, with or without
19951 + * modification, are permitted provided that the following conditions are met:
19952 + * * Redistributions of source code must retain the above copyright
19953 + * notice, this list of conditions and the following disclaimer.
19954 + * * Redistributions in binary form must reproduce the above copyright
19955 + * notice, this list of conditions and the following disclaimer in the
19956 + * documentation and/or other materials provided with the distribution.
19957 + * * Neither the name of Freescale Semiconductor nor the
19958 + * names of its contributors may be used to endorse or promote products
19959 + * derived from this software without specific prior written permission.
19960 + *
19961 + *
19962 + * ALTERNATIVELY, this software may be distributed under the terms of the
19963 + * GNU General Public License ("GPL") as published by the Free Software
19964 + * Foundation, either version 2 of that License or (at your option) any
19965 + * later version.
19966 + *
19967 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19968 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19969 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19970 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19971 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19972 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19973 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19974 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19975 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19976 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19977 + */
19978 +
19979 +
19980 +/******************************************************************************
19981 + @File memac.c
19982 +
19983 + @Description FM mEMAC driver
19984 +*//***************************************************************************/
19985 +
19986 +#include "std_ext.h"
19987 +#include "string_ext.h"
19988 +#include "error_ext.h"
19989 +#include "xx_ext.h"
19990 +#include "endian_ext.h"
19991 +#include "debug_ext.h"
19992 +
19993 +#include "fm_common.h"
19994 +#include "memac.h"
19995 +
19996 +
19997 +/*****************************************************************************/
19998 +/* Internal routines */
19999 +/*****************************************************************************/
20000 +
20001 +/* ......................................................................... */
20002 +
20003 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
20004 +{
20005 + uint64_t mask1, mask2;
20006 + uint32_t xorVal = 0;
20007 + uint8_t i, j;
20008 +
20009 + for (i=0; i<6; i++)
20010 + {
20011 + mask1 = ethAddr & (uint64_t)0x01;
20012 + ethAddr >>= 1;
20013 +
20014 + for (j=0; j<7; j++)
20015 + {
20016 + mask2 = ethAddr & (uint64_t)0x01;
20017 + mask1 ^= mask2;
20018 + ethAddr >>= 1;
20019 + }
20020 +
20021 + xorVal |= (mask1 << (5-i));
20022 + }
20023 +
20024 + return xorVal;
20025 +}
20026 +
20027 +/* ......................................................................... */
20028 +
20029 +static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr)
20030 +{
20031 + uint16_t tmpReg16;
20032 + e_EnetMode enetMode;
20033 +
20034 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20035 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20036 + to 1G one, so MII functions can work correctly. */
20037 + enetMode = p_Memac->enetMode;
20038 +
20039 + /* SGMII mode + AN enable */
20040 + tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII;
20041 + if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500)
20042 + tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII;
20043 +
20044 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20045 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20046 +
20047 + /* Device ability according to SGMII specification */
20048 + tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII;
20049 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20050 +
20051 + /* Adjust link timer for SGMII -
20052 + According to Cisco SGMII specification the timer should be 1.6 ms.
20053 + The link_timer register is configured in units of the clock.
20054 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20055 + unit = 1 / (125*10^6 Hz) = 8 ns.
20056 + 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40
20057 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20058 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20059 + 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120.
20060 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20061 + we always set up here a value of 2.5 SGMII. */
20062 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007);
20063 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120);
20064 +
20065 + /* Restart AN */
20066 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20067 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20068 +
20069 + /* Restore original enet mode */
20070 + p_Memac->enetMode = enetMode;
20071 +}
20072 +
20073 +/* ......................................................................... */
20074 +
20075 +static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr)
20076 +{
20077 + uint16_t tmpReg16;
20078 + e_EnetMode enetMode;
20079 +
20080 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20081 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20082 + to 1G one, so MII functions can work correctly. */
20083 + enetMode = p_Memac->enetMode;
20084 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20085 +
20086 + /* 1000BaseX mode */
20087 + tmpReg16 = PHY_SGMII_IF_MODE_1000X;
20088 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20089 +
20090 + /* AN Device capability */
20091 + tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X;
20092 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20093 +
20094 + /* Adjust link timer for SGMII -
20095 + For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
20096 + The link_timer register is configured in units of the clock.
20097 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20098 + unit = 1 / (125*10^6 Hz) = 8 ns.
20099 + 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
20100 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20101 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20102 + 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
20103 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20104 + we always set up here a value of 2.5 SGMII. */
20105 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f);
20106 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08);
20107 +
20108 + /* Restart AN */
20109 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20110 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20111 +
20112 + /* Restore original enet mode */
20113 + p_Memac->enetMode = enetMode;
20114 +}
20115 +
20116 +/* ......................................................................... */
20117 +
20118 +static t_Error CheckInitParameters(t_Memac *p_Memac)
20119 +{
20120 + e_FmMacType portType;
20121 +
20122 + portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20123 +
20124 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
20125 + if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS))
20126 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS));
20127 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
20128 +
20129 + if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS))
20130 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS));
20131 + if (p_Memac->addr == 0)
20132 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address"));
20133 + if (!p_Memac->f_Exception)
20134 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception"));
20135 + if (!p_Memac->f_Event)
20136 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event"));
20137 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
20138 + if (!p_Memac->p_MemacDriverParam->no_length_check_enable)
20139 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
20140 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
20141 +
20142 + return E_OK;
20143 +}
20144 +
20145 +/* ........................................................................... */
20146 +
20147 +static void MemacErrException(t_Handle h_Memac)
20148 +{
20149 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20150 + uint32_t event, imask;
20151 +
20152 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20153 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20154 +
20155 + /* Imask include both error and notification/event bits.
20156 + Leaving only error bits enabled by imask.
20157 + The imask error bits are shifted by 16 bits offset from
20158 + their corresponding location in the ievent - hence the >> 16 */
20159 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20160 +
20161 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20162 +
20163 + if (event & MEMAC_IEVNT_TS_ECC_ER)
20164 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR);
20165 + if (event & MEMAC_IEVNT_TX_ECC_ER)
20166 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
20167 + if (event & MEMAC_IEVNT_RX_ECC_ER)
20168 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
20169 +}
20170 +
20171 +static void MemacException(t_Handle h_Memac)
20172 +{
20173 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20174 + uint32_t event, imask;
20175 +
20176 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20177 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20178 +
20179 + /* Imask include both error and notification/event bits.
20180 + Leaving only error bits enabled by imask.
20181 + The imask error bits are shifted by 16 bits offset from
20182 + their corresponding location in the ievent - hence the >> 16 */
20183 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20184 +
20185 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20186 +
20187 + if (event & MEMAC_IEVNT_MGI)
20188 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION);
20189 +}
20190 +
20191 +/* ......................................................................... */
20192 +
20193 +static void FreeInitResources(t_Memac *p_Memac)
20194 +{
20195 + e_FmMacType portType;
20196 +
20197 + portType =
20198 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20199 +
20200 + if (portType == e_FM_MAC_10G)
20201 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20202 + else
20203 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20204 +
20205 + /* release the driver's group hash table */
20206 + FreeHashTable(p_Memac->p_MulticastAddrHash);
20207 + p_Memac->p_MulticastAddrHash = NULL;
20208 +
20209 + /* release the driver's individual hash table */
20210 + FreeHashTable(p_Memac->p_UnicastAddrHash);
20211 + p_Memac->p_UnicastAddrHash = NULL;
20212 +}
20213 +
20214 +
20215 +/*****************************************************************************/
20216 +/* mEMAC API routines */
20217 +/*****************************************************************************/
20218 +
20219 +/* ......................................................................... */
20220 +
20221 +static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode)
20222 +{
20223 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20224 +
20225 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20226 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20227 +
20228 + fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20229 +
20230 + return E_OK;
20231 +}
20232 +
20233 +/* ......................................................................... */
20234 +
20235 +static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode)
20236 +{
20237 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20238 +
20239 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20240 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20241 +
20242 + fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20243 +
20244 + return E_OK;
20245 +}
20246 +
20247 +/* ......................................................................... */
20248 +
20249 +static t_Error MemacSetPromiscuous(t_Handle h_Memac, bool newVal)
20250 +{
20251 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20252 +
20253 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20254 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20255 +
20256 + fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal);
20257 +
20258 + return E_OK;
20259 +}
20260 +
20261 +/* .............................................................................. */
20262 +
20263 +static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex)
20264 +{
20265 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20266 +
20267 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20268 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20269 +
20270 + if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex))
20271 + RETURN_ERROR(MAJOR, E_CONFLICT,
20272 + ("Ethernet MAC 1G or 10G does not support half-duplex"));
20273 +
20274 + fman_memac_adjust_link(p_Memac->p_MemMap,
20275 + (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode),
20276 + (enum enet_speed)speed,
20277 + fullDuplex);
20278 + return E_OK;
20279 +}
20280 +
20281 +
20282 +/*****************************************************************************/
20283 +/* Memac Configs modification functions */
20284 +/*****************************************************************************/
20285 +
20286 +/* ......................................................................... */
20287 +
20288 +static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal)
20289 +{
20290 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20291 +
20292 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20293 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20294 +
20295 + p_Memac->p_MemacDriverParam->loopback_enable = newVal;
20296 +
20297 + return E_OK;
20298 +}
20299 +
20300 +/* ......................................................................... */
20301 +
20302 +static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal)
20303 +{
20304 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20305 +
20306 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20307 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20308 +
20309 + p_Memac->p_MemacDriverParam->wan_mode_enable = newVal;
20310 +
20311 + return E_OK;
20312 +}
20313 +
20314 +/* ......................................................................... */
20315 +
20316 +static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal)
20317 +{
20318 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20319 +
20320 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20321 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20322 +
20323 + p_Memac->p_MemacDriverParam->max_frame_length = newVal;
20324 +
20325 + return E_OK;
20326 +}
20327 +
20328 +/* ......................................................................... */
20329 +
20330 +static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal)
20331 +{
20332 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20333 +
20334 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20335 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20336 +
20337 + p_Memac->p_MemacDriverParam->pad_enable = newVal;
20338 +
20339 + return E_OK;
20340 +}
20341 +
20342 +/* ......................................................................... */
20343 +
20344 +static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal)
20345 +{
20346 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20347 +
20348 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20349 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20350 +
20351 + p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal;
20352 +
20353 + return E_OK;
20354 +}
20355 +
20356 +/* ......................................................................... */
20357 +
20358 +static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
20359 +{
20360 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20361 + uint32_t bitMask = 0;
20362 +
20363 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20364 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20365 +
20366 + GET_EXCEPTION_FLAG(bitMask, exception);
20367 + if (bitMask)
20368 + {
20369 + if (enable)
20370 + p_Memac->exceptions |= bitMask;
20371 + else
20372 + p_Memac->exceptions &= ~bitMask;
20373 + }
20374 + else
20375 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
20376 +
20377 + return E_OK;
20378 +}
20379 +
20380 +/* ......................................................................... */
20381 +
20382 +static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable)
20383 +{
20384 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20385 +
20386 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20387 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20388 +
20389 + p_Memac->p_MemacDriverParam->reset_on_init = enable;
20390 +
20391 + return E_OK;
20392 +}
20393 +
20394 +
20395 +/*****************************************************************************/
20396 +/* Memac Run Time API functions */
20397 +/*****************************************************************************/
20398 +
20399 +/* ......................................................................... */
20400 +
20401 +static t_Error MemacSetTxPauseFrames(t_Handle h_Memac,
20402 + uint8_t priority,
20403 + uint16_t pauseTime,
20404 + uint16_t threshTime)
20405 +{
20406 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20407 +
20408 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20409 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20410 +
20411 + if (priority != 0xFF)
20412 + {
20413 + bool PortConfigured, PreFetchEnabled;
20414 +
20415 + if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0)
20416 + RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled"));
20417 +
20418 + FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm,
20419 + p_Memac->fmMacControllerDriver.macId,
20420 + &PortConfigured,
20421 + &PreFetchEnabled);
20422 +
20423 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured)
20424 + DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20425 +
20426 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled)
20427 + DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20428 + }
20429 +
20430 + fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime);
20431 +
20432 + return E_OK;
20433 +}
20434 +
20435 +/* ......................................................................... */
20436 +
20437 +static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac,
20438 + uint16_t pauseTime)
20439 +{
20440 + return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0);
20441 +}
20442 +
20443 +/* ......................................................................... */
20444 +
20445 +static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en)
20446 +{
20447 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20448 +
20449 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20450 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20451 +
20452 + fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en);
20453 +
20454 + return E_OK;
20455 +}
20456 +
20457 +/* ......................................................................... */
20458 +
20459 +static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en)
20460 +{
20461 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20462 +
20463 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20464 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20465 +
20466 + fman_memac_set_wol(p_Memac->p_MemMap, en);
20467 +
20468 + return E_OK;
20469 +}
20470 +
20471 +/* .............................................................................. */
20472 +
20473 +static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac)
20474 +{
20475 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20476 +
20477 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20478 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20479 +UNUSED(p_Memac);
20480 +DBG(WARNING, ("mEMAC has 1588 always enabled!"));
20481 +
20482 + return E_OK;
20483 +}
20484 +
20485 +/* Counters handling */
20486 +/* ......................................................................... */
20487 +
20488 +static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics)
20489 +{
20490 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20491 +
20492 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20493 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20494 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
20495 +
20496 + p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
20497 + p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
20498 + p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
20499 + p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
20500 + p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
20501 + p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
20502 + p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
20503 +/* */
20504 + p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG);
20505 + p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR);
20506 +
20507 + p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP);
20508 + p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN);
20509 +
20510 + p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND);
20511 + p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR);
20512 +/* Pause */
20513 + p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF);
20514 + p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF);
20515 +
20516 +/* MIB II */
20517 + p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT);
20518 + p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA);
20519 + p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA);
20520 + p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA);
20521 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
20522 + + p_Statistics->ifInMcastPkts
20523 + + p_Statistics->ifInBcastPkts;
20524 + p_Statistics->ifInDiscards = 0;
20525 + p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR);
20526 +
20527 + p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT);
20528 + p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA);
20529 + p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA);
20530 + p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA);
20531 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
20532 + + p_Statistics->ifOutMcastPkts
20533 + + p_Statistics->ifOutBcastPkts;
20534 + p_Statistics->ifOutDiscards = 0;
20535 + p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR);
20536 +
20537 + return E_OK;
20538 +}
20539 +
20540 +/* ......................................................................... */
20541 +
20542 +static t_Error MemacGetFrameSizeCounters(t_Handle h_Memac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
20543 +{
20544 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20545 +
20546 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20547 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20548 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
20549 +
20550 + switch (type)
20551 + {
20552 + case e_COMM_MODE_NONE:
20553 + break;
20554 +
20555 + case e_COMM_MODE_RX:
20556 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
20557 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
20558 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
20559 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
20560 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
20561 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
20562 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
20563 + break;
20564 +
20565 + case e_COMM_MODE_TX:
20566 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
20567 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
20568 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
20569 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
20570 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
20571 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
20572 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
20573 + break;
20574 +
20575 + case e_COMM_MODE_RX_AND_TX:
20576 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64)
20577 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
20578 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127)
20579 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
20580 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255)
20581 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
20582 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511)
20583 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
20584 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023)
20585 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
20586 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518)
20587 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
20588 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X)
20589 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
20590 + break;
20591 + }
20592 +
20593 + return E_OK;
20594 +}
20595 +
20596 +/* ......................................................................... */
20597 +
20598 +static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr)
20599 +{
20600 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20601 +
20602 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20603 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20604 +
20605 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0);
20606 +
20607 + return E_OK;
20608 +}
20609 +
20610 +/* ......................................................................... */
20611 +
20612 +static t_Error MemacResetCounters (t_Handle h_Memac)
20613 +{
20614 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20615 +
20616 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20617 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20618 +
20619 + fman_memac_reset_stat(p_Memac->p_MemMap);
20620 +
20621 + return E_OK;
20622 +}
20623 +
20624 +/* ......................................................................... */
20625 +
20626 +static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20627 +{
20628 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20629 + uint64_t ethAddr;
20630 + uint8_t paddrNum;
20631 +
20632 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20633 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20634 +
20635 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20636 +
20637 + if (ethAddr & GROUP_ADDRESS)
20638 + /* Multicast address has no effect in PADDR */
20639 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
20640 +
20641 + /* Make sure no PADDR contains this address */
20642 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20643 + if (p_Memac->indAddrRegUsed[paddrNum])
20644 + if (p_Memac->paddr[paddrNum] == ethAddr)
20645 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
20646 +
20647 + /* Find first unused PADDR */
20648 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20649 + if (!(p_Memac->indAddrRegUsed[paddrNum]))
20650 + {
20651 + /* mark this PADDR as used */
20652 + p_Memac->indAddrRegUsed[paddrNum] = TRUE;
20653 + /* store address */
20654 + p_Memac->paddr[paddrNum] = ethAddr;
20655 +
20656 + /* put in hardware */
20657 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum);
20658 + p_Memac->numOfIndAddrInRegs++;
20659 +
20660 + return E_OK;
20661 + }
20662 +
20663 + /* No free PADDR */
20664 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
20665 +}
20666 +
20667 +/* ......................................................................... */
20668 +
20669 +static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20670 +{
20671 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20672 + uint64_t ethAddr;
20673 + uint8_t paddrNum;
20674 +
20675 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20676 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20677 +
20678 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20679 +
20680 + /* Find used PADDR containing this address */
20681 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20682 + {
20683 + if ((p_Memac->indAddrRegUsed[paddrNum]) &&
20684 + (p_Memac->paddr[paddrNum] == ethAddr))
20685 + {
20686 + /* mark this PADDR as not used */
20687 + p_Memac->indAddrRegUsed[paddrNum] = FALSE;
20688 + /* clear in hardware */
20689 + fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum);
20690 + p_Memac->numOfIndAddrInRegs--;
20691 +
20692 + return E_OK;
20693 + }
20694 + }
20695 +
20696 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
20697 +}
20698 +
20699 +/* ......................................................................... */
20700 +
20701 +static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId)
20702 +{
20703 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20704 +
20705 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20706 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20707 +
20708 + *macId = p_Memac->macId;
20709 +
20710 + return E_OK;
20711 +}
20712 +
20713 +/* ......................................................................... */
20714 +
20715 +
20716 +static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20717 +{
20718 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20719 + t_EthHashEntry *p_HashEntry;
20720 + uint32_t hash;
20721 + uint64_t ethAddr;
20722 +
20723 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20724 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20725 +
20726 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20727 +
20728 + if (!(ethAddr & GROUP_ADDRESS))
20729 + /* Unicast addresses not supported in hash */
20730 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
20731 +
20732 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20733 +
20734 + /* Create element to be added to the driver hash table */
20735 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
20736 + p_HashEntry->addr = ethAddr;
20737 + INIT_LIST(&p_HashEntry->node);
20738 +
20739 + LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]));
20740 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN));
20741 +
20742 + return E_OK;
20743 +}
20744 +
20745 +/* ......................................................................... */
20746 +
20747 +static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20748 +{
20749 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20750 + t_EthHashEntry *p_HashEntry = NULL;
20751 + t_List *p_Pos;
20752 + uint32_t hash;
20753 + uint64_t ethAddr;
20754 +
20755 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20756 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20757 +
20758 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20759 +
20760 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20761 +
20762 + LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
20763 + {
20764 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
20765 + if (p_HashEntry->addr == ethAddr)
20766 + {
20767 + LIST_DelAndInit(&p_HashEntry->node);
20768 + XX_Free(p_HashEntry);
20769 + break;
20770 + }
20771 + }
20772 + if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
20773 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN));
20774 +
20775 + return E_OK;
20776 +}
20777 +
20778 +
20779 +/* ......................................................................... */
20780 +
20781 +static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
20782 +{
20783 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20784 + uint32_t bitMask = 0;
20785 +
20786 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20787 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20788 +
20789 + GET_EXCEPTION_FLAG(bitMask, exception);
20790 + if (bitMask)
20791 + {
20792 + if (enable)
20793 + p_Memac->exceptions |= bitMask;
20794 + else
20795 + p_Memac->exceptions &= ~bitMask;
20796 + }
20797 + else
20798 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
20799 +
20800 + fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable);
20801 +
20802 + return E_OK;
20803 +}
20804 +
20805 +/* ......................................................................... */
20806 +
20807 +static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac)
20808 +{
20809 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20810 +
20811 + SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0);
20812 + SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0);
20813 +
20814 + return fman_memac_get_max_frame_len(p_Memac->p_MemMap);
20815 +}
20816 +
20817 +static t_Error MemacInitInternalPhy(t_Handle h_Memac)
20818 +{
20819 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20820 + uint8_t i, phyAddr;
20821 +
20822 + if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII)
20823 + {
20824 + /* Configure internal SGMII PHY */
20825 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
20826 + SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR);
20827 + else
20828 + SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR);
20829 + }
20830 + else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII)
20831 + {
20832 + /* Configure 4 internal SGMII PHYs */
20833 + for (i = 0; i < 4; i++)
20834 + {
20835 + /* QSGMII PHY address occupies 3 upper bits of 5-bit
20836 + phyAddress; the lower 2 bits are used to extend
20837 + register address space and access each one of 4
20838 + ports inside QSGMII. */
20839 + phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i);
20840 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
20841 + SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr);
20842 + else
20843 + SetupSgmiiInternalPhy(p_Memac, phyAddr);
20844 + }
20845 + }
20846 + return E_OK;
20847 +}
20848 +
20849 +/*****************************************************************************/
20850 +/* mEMAC Init & Free API */
20851 +/*****************************************************************************/
20852 +
20853 +/* ......................................................................... */
20854 +void *g_MemacRegs;
20855 +static t_Error MemacInit(t_Handle h_Memac)
20856 +{
20857 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20858 + struct memac_cfg *p_MemacDriverParam;
20859 + enum enet_interface enet_interface;
20860 + enum enet_speed enet_speed;
20861 + t_EnetAddr ethAddr;
20862 + e_FmMacType portType;
20863 + t_Error err;
20864 + bool slow_10g_if = FALSE;
20865 + if (p_Memac->macId == 3) /* This is a quick WA */
20866 + g_MemacRegs = p_Memac->p_MemMap;
20867 +
20868 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20869 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20870 + SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
20871 +
20872 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
20873 + if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 &&
20874 + p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4)
20875 + slow_10g_if = TRUE;
20876 +
20877 + CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters);
20878 +
20879 + p_MemacDriverParam = p_Memac->p_MemacDriverParam;
20880 +
20881 + portType =
20882 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20883 +
20884 + /* First, reset the MAC if desired. */
20885 + if (p_MemacDriverParam->reset_on_init)
20886 + fman_memac_reset(p_Memac->p_MemMap);
20887 +
20888 + /* MAC Address */
20889 + MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr);
20890 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0);
20891 +
20892 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode);
20893 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode);
20894 +
20895 + fman_memac_init(p_Memac->p_MemMap,
20896 + p_Memac->p_MemacDriverParam,
20897 + enet_interface,
20898 + enet_speed,
20899 + slow_10g_if,
20900 + p_Memac->exceptions);
20901 +
20902 +#ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
20903 + {
20904 + uint32_t tmpReg = 0;
20905 +
20906 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
20907 + /* check the FMAN version - the bug exists only in rev1 */
20908 + if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) &&
20909 + (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0))
20910 + {
20911 + /* MAC strips CRC from received frames - this workaround should
20912 + decrease the likelihood of bug appearance
20913 + */
20914 + tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config);
20915 + tmpReg &= ~CMD_CFG_CRC_FWD;
20916 + WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg);
20917 + /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/
20918 + }
20919 + }
20920 +#endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */
20921 +
20922 + MemacInitInternalPhy(h_Memac);
20923 +
20924 + /* Max Frame Length */
20925 + err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm,
20926 + portType,
20927 + p_Memac->fmMacControllerDriver.macId,
20928 + p_MemacDriverParam->max_frame_length);
20929 + if (err)
20930 + RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED"));
20931 +
20932 + p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
20933 + if (!p_Memac->p_MulticastAddrHash)
20934 + {
20935 + FreeInitResources(p_Memac);
20936 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
20937 + }
20938 +
20939 + p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
20940 + if (!p_Memac->p_UnicastAddrHash)
20941 + {
20942 + FreeInitResources(p_Memac);
20943 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
20944 + }
20945 +
20946 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
20947 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
20948 + p_Memac->macId,
20949 + e_FM_INTR_TYPE_ERR,
20950 + MemacErrException,
20951 + p_Memac);
20952 +
20953 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
20954 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
20955 + p_Memac->macId,
20956 + e_FM_INTR_TYPE_NORMAL,
20957 + MemacException,
20958 + p_Memac);
20959 +
20960 + XX_Free(p_MemacDriverParam);
20961 + p_Memac->p_MemacDriverParam = NULL;
20962 +
20963 + return E_OK;
20964 +}
20965 +
20966 +/* ......................................................................... */
20967 +
20968 +static t_Error MemacFree(t_Handle h_Memac)
20969 +{
20970 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20971 +
20972 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20973 +
20974 + if (p_Memac->p_MemacDriverParam)
20975 + {
20976 + /* Called after config */
20977 + XX_Free(p_Memac->p_MemacDriverParam);
20978 + p_Memac->p_MemacDriverParam = NULL;
20979 + }
20980 + else
20981 + /* Called after init */
20982 + FreeInitResources(p_Memac);
20983 +
20984 + XX_Free(p_Memac);
20985 +
20986 + return E_OK;
20987 +}
20988 +
20989 +/* ......................................................................... */
20990 +
20991 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
20992 +{
20993 + p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit;
20994 + p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree;
20995 +
20996 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
20997 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback;
20998 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength;
20999 +
21000 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan;
21001 +
21002 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad;
21003 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */
21004 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck;
21005 +
21006 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException;
21007 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit;
21008 +
21009 + p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException;
21010 +
21011 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */
21012 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL;
21013 +
21014 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous;
21015 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink;
21016 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
21017 +
21018 + p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable;
21019 + p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable;
21020 + p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy;
21021 +
21022 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames;
21023 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames;
21024 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames;
21025 +
21026 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan;
21027 +
21028 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters;
21029 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics;
21030 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = MemacGetFrameSizeCounters;
21031 +
21032 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress;
21033 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress;
21034 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress;
21035 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress;
21036 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress;
21037 + p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId;
21038 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL;
21039 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength;
21040 +
21041 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg;
21042 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg;
21043 +}
21044 +
21045 +
21046 +/*****************************************************************************/
21047 +/* mEMAC Config Main Entry */
21048 +/*****************************************************************************/
21049 +
21050 +/* ......................................................................... */
21051 +
21052 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam)
21053 +{
21054 + t_Memac *p_Memac;
21055 + struct memac_cfg *p_MemacDriverParam;
21056 + uintptr_t baseAddr;
21057 +
21058 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
21059 +
21060 + baseAddr = p_FmMacParam->baseAddr;
21061 + /* Allocate memory for the mEMAC data structure */
21062 + p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac));
21063 + if (!p_Memac)
21064 + {
21065 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure"));
21066 + return NULL;
21067 + }
21068 + memset(p_Memac, 0, sizeof(t_Memac));
21069 + InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver);
21070 +
21071 + /* Allocate memory for the mEMAC driver parameters data structure */
21072 + p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg));
21073 + if (!p_MemacDriverParam)
21074 + {
21075 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters"));
21076 + XX_Free(p_Memac);
21077 + return NULL;
21078 + }
21079 + memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg));
21080 +
21081 + /* Plant parameter structure pointer */
21082 + p_Memac->p_MemacDriverParam = p_MemacDriverParam;
21083 +
21084 + fman_memac_defconfig(p_MemacDriverParam);
21085 +
21086 + p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
21087 +
21088 + p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr);
21089 + p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET);
21090 +
21091 + p_Memac->enetMode = p_FmMacParam->enetMode;
21092 + p_Memac->macId = p_FmMacParam->macId;
21093 + p_Memac->exceptions = MEMAC_default_exceptions;
21094 + p_Memac->f_Exception = p_FmMacParam->f_Exception;
21095 + p_Memac->f_Event = p_FmMacParam->f_Event;
21096 + p_Memac->h_App = p_FmMacParam->h_App;
21097 +
21098 + return p_Memac;
21099 +}
21100 --- /dev/null
21101 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
21102 @@ -0,0 +1,110 @@
21103 +/*
21104 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21105 + *
21106 + * Redistribution and use in source and binary forms, with or without
21107 + * modification, are permitted provided that the following conditions are met:
21108 + * * Redistributions of source code must retain the above copyright
21109 + * notice, this list of conditions and the following disclaimer.
21110 + * * Redistributions in binary form must reproduce the above copyright
21111 + * notice, this list of conditions and the following disclaimer in the
21112 + * documentation and/or other materials provided with the distribution.
21113 + * * Neither the name of Freescale Semiconductor nor the
21114 + * names of its contributors may be used to endorse or promote products
21115 + * derived from this software without specific prior written permission.
21116 + *
21117 + *
21118 + * ALTERNATIVELY, this software may be distributed under the terms of the
21119 + * GNU General Public License ("GPL") as published by the Free Software
21120 + * Foundation, either version 2 of that License or (at your option) any
21121 + * later version.
21122 + *
21123 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21124 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21125 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21126 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21127 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21128 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21129 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21130 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21131 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21132 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21133 + */
21134 +
21135 +
21136 +/******************************************************************************
21137 + @File memac.h
21138 +
21139 + @Description FM Multirate Ethernet MAC (mEMAC)
21140 +*//***************************************************************************/
21141 +#ifndef __MEMAC_H
21142 +#define __MEMAC_H
21143 +
21144 +#include "std_ext.h"
21145 +#include "error_ext.h"
21146 +#include "list_ext.h"
21147 +
21148 +#include "fsl_fman_memac_mii_acc.h"
21149 +#include "fm_mac.h"
21150 +#include "fsl_fman_memac.h"
21151 +
21152 +
21153 +#define MEMAC_default_exceptions \
21154 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI))
21155 +
21156 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
21157 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
21158 + bitMask = MEMAC_IMASK_TECC_ER; break; \
21159 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
21160 + bitMask = MEMAC_IMASK_RECC_ER; break; \
21161 + case e_FM_MAC_EX_TS_FIFO_ECC_ERR: \
21162 + bitMask = MEMAC_IMASK_TSECC_ER; break; \
21163 + case e_FM_MAC_EX_MAGIC_PACKET_INDICATION: \
21164 + bitMask = MEMAC_IMASK_MGI; break; \
21165 + default: bitMask = 0;break;}
21166 +
21167 +
21168 +typedef struct
21169 +{
21170 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
21171 + t_Handle h_App; /**< Handle to the upper layer application */
21172 + struct memac_regs *p_MemMap; /**< Pointer to MAC memory mapped registers */
21173 + struct memac_mii_access_mem_map *p_MiiMemMap; /**< Pointer to MII memory mapped registers */
21174 + uint64_t addr; /**< MAC address of device */
21175 + e_EnetMode enetMode; /**< Ethernet physical interface */
21176 + t_FmMacExceptionCallback *f_Exception;
21177 + int mdioIrq;
21178 + t_FmMacExceptionCallback *f_Event;
21179 + bool indAddrRegUsed[MEMAC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
21180 + uint64_t paddr[MEMAC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
21181 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
21182 + t_EthHash *p_MulticastAddrHash; /**< Pointer to driver's global address hash table */
21183 + t_EthHash *p_UnicastAddrHash; /**< Pointer to driver's individual address hash table */
21184 + bool debugMode;
21185 + uint8_t macId;
21186 + uint32_t exceptions;
21187 + struct memac_cfg *p_MemacDriverParam;
21188 +} t_Memac;
21189 +
21190 +
21191 +/* Internal PHY access */
21192 +#define PHY_MDIO_ADDR 0
21193 +
21194 +/* Internal PHY Registers - SGMII */
21195 +#define PHY_SGMII_CR_PHY_RESET 0x8000
21196 +#define PHY_SGMII_CR_RESET_AN 0x0200
21197 +#define PHY_SGMII_CR_DEF_VAL 0x1140
21198 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
21199 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
21200 +#define PHY_SGMII_IF_SPEED_GIGABIT 0x0008
21201 +#define PHY_SGMII_IF_MODE_AN 0x0002
21202 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
21203 +#define PHY_SGMII_IF_MODE_1000X 0x0000
21204 +
21205 +
21206 +#define MEMAC_TO_MII_OFFSET 0x030 /* Offset from the MEM map to the MDIO mem map */
21207 +
21208 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t data);
21209 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
21210 +
21211 +
21212 +#endif /* __MEMAC_H */
21213 --- /dev/null
21214 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
21215 @@ -0,0 +1,78 @@
21216 +/*
21217 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21218 + *
21219 + * Redistribution and use in source and binary forms, with or without
21220 + * modification, are permitted provided that the following conditions are met:
21221 + * * Redistributions of source code must retain the above copyright
21222 + * notice, this list of conditions and the following disclaimer.
21223 + * * Redistributions in binary form must reproduce the above copyright
21224 + * notice, this list of conditions and the following disclaimer in the
21225 + * documentation and/or other materials provided with the distribution.
21226 + * * Neither the name of Freescale Semiconductor nor the
21227 + * names of its contributors may be used to endorse or promote products
21228 + * derived from this software without specific prior written permission.
21229 + *
21230 + *
21231 + * ALTERNATIVELY, this software may be distributed under the terms of the
21232 + * GNU General Public License ("GPL") as published by the Free Software
21233 + * Foundation, either version 2 of that License or (at your option) any
21234 + * later version.
21235 + *
21236 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21237 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21238 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21239 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21240 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21241 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21242 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21243 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21244 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21245 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21246 + */
21247 +
21248 +
21249 +#include "error_ext.h"
21250 +#include "std_ext.h"
21251 +#include "fm_mac.h"
21252 +#include "memac.h"
21253 +#include "xx_ext.h"
21254 +
21255 +#include "fm_common.h"
21256 +#include "memac_mii_acc.h"
21257 +
21258 +
21259 +/*****************************************************************************/
21260 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac,
21261 + uint8_t phyAddr,
21262 + uint8_t reg,
21263 + uint16_t data)
21264 +{
21265 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21266 +
21267 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21268 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21269 +
21270 + return (t_Error)fman_memac_mii_write_phy_reg(p_Memac->p_MiiMemMap,
21271 + phyAddr,
21272 + reg,
21273 + data,
21274 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21275 +}
21276 +
21277 +/*****************************************************************************/
21278 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac,
21279 + uint8_t phyAddr,
21280 + uint8_t reg,
21281 + uint16_t *p_Data)
21282 +{
21283 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21284 +
21285 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21286 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21287 +
21288 + return fman_memac_mii_read_phy_reg(p_Memac->p_MiiMemMap,
21289 + phyAddr,
21290 + reg,
21291 + p_Data,
21292 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21293 +}
21294 --- /dev/null
21295 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
21296 @@ -0,0 +1,73 @@
21297 +/*
21298 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21299 + *
21300 + * Redistribution and use in source and binary forms, with or without
21301 + * modification, are permitted provided that the following conditions are met:
21302 + * * Redistributions of source code must retain the above copyright
21303 + * notice, this list of conditions and the following disclaimer.
21304 + * * Redistributions in binary form must reproduce the above copyright
21305 + * notice, this list of conditions and the following disclaimer in the
21306 + * documentation and/or other materials provided with the distribution.
21307 + * * Neither the name of Freescale Semiconductor nor the
21308 + * names of its contributors may be used to endorse or promote products
21309 + * derived from this software without specific prior written permission.
21310 + *
21311 + *
21312 + * ALTERNATIVELY, this software may be distributed under the terms of the
21313 + * GNU General Public License ("GPL") as published by the Free Software
21314 + * Foundation, either version 2 of that License or (at your option) any
21315 + * later version.
21316 + *
21317 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21318 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21319 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21320 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21321 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21322 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21323 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21324 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21325 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21326 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21327 + */
21328 +
21329 +
21330 +#ifndef __MEMAC_MII_ACC_H
21331 +#define __MEMAC_MII_ACC_H
21332 +
21333 +#include "std_ext.h"
21334 +
21335 +
21336 +/* MII Management Registers */
21337 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
21338 +#define MDIO_CFG_CLK_DIV_SHIFT 7
21339 +#define MDIO_CFG_HOLD_MASK 0x0000001c
21340 +#define MDIO_CFG_ENC45 0x00000040
21341 +#define MDIO_CFG_READ_ERR 0x00000002
21342 +#define MDIO_CFG_BSY 0x00000001
21343 +
21344 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
21345 +#define MDIO_CTL_READ 0x00008000
21346 +
21347 +#define MDIO_DATA_BSY 0x80000000
21348 +
21349 +#if defined(__MWERKS__) && !defined(__GNUC__)
21350 +#pragma pack(push,1)
21351 +#endif /* defined(__MWERKS__) && ... */
21352 +
21353 +/*----------------------------------------------------*/
21354 +/* MII Configuration Control Memory Map Registers */
21355 +/*----------------------------------------------------*/
21356 +typedef struct t_MemacMiiAccessMemMap
21357 +{
21358 + volatile uint32_t mdio_cfg; /* 0x030 */
21359 + volatile uint32_t mdio_ctrl; /* 0x034 */
21360 + volatile uint32_t mdio_data; /* 0x038 */
21361 + volatile uint32_t mdio_addr; /* 0x03c */
21362 +} t_MemacMiiAccessMemMap ;
21363 +
21364 +#if defined(__MWERKS__) && !defined(__GNUC__)
21365 +#pragma pack(pop)
21366 +#endif /* defined(__MWERKS__) && ... */
21367 +
21368 +
21369 +#endif /* __MEMAC_MII_ACC_H */
21370 --- /dev/null
21371 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
21372 @@ -0,0 +1,1017 @@
21373 +/*
21374 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21375 + *
21376 + * Redistribution and use in source and binary forms, with or without
21377 + * modification, are permitted provided that the following conditions are met:
21378 + * * Redistributions of source code must retain the above copyright
21379 + * notice, this list of conditions and the following disclaimer.
21380 + * * Redistributions in binary form must reproduce the above copyright
21381 + * notice, this list of conditions and the following disclaimer in the
21382 + * documentation and/or other materials provided with the distribution.
21383 + * * Neither the name of Freescale Semiconductor nor the
21384 + * names of its contributors may be used to endorse or promote products
21385 + * derived from this software without specific prior written permission.
21386 + *
21387 + *
21388 + * ALTERNATIVELY, this software may be distributed under the terms of the
21389 + * GNU General Public License ("GPL") as published by the Free Software
21390 + * Foundation, either version 2 of that License or (at your option) any
21391 + * later version.
21392 + *
21393 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21394 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21395 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21396 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21397 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21398 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21399 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21400 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21401 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21402 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21403 + */
21404 +
21405 +
21406 +/******************************************************************************
21407 + @File tgec.c
21408 +
21409 + @Description FM 10G MAC ...
21410 +*//***************************************************************************/
21411 +
21412 +#include "std_ext.h"
21413 +#include "string_ext.h"
21414 +#include "error_ext.h"
21415 +#include "xx_ext.h"
21416 +#include "endian_ext.h"
21417 +#include "debug_ext.h"
21418 +#include "crc_mac_addr_ext.h"
21419 +
21420 +#include "fm_common.h"
21421 +#include "fsl_fman_tgec.h"
21422 +#include "tgec.h"
21423 +
21424 +
21425 +/*****************************************************************************/
21426 +/* Internal routines */
21427 +/*****************************************************************************/
21428 +
21429 +static t_Error CheckInitParameters(t_Tgec *p_Tgec)
21430 +{
21431 + if (ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000)
21432 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed"));
21433 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
21434 + if (p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS)
21435 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0"));
21436 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
21437 +
21438 + if (p_Tgec->addr == 0)
21439 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address"));
21440 + if (!p_Tgec->f_Exception)
21441 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception"));
21442 + if (!p_Tgec->f_Event)
21443 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event"));
21444 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
21445 + if (!p_Tgec->p_TgecDriverParam->no_length_check_enable)
21446 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
21447 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
21448 + return E_OK;
21449 +}
21450 +
21451 +/* ......................................................................... */
21452 +
21453 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
21454 +{
21455 + uint32_t crc;
21456 +
21457 + /* CRC calculation */
21458 + GET_MAC_ADDR_CRC(ethAddr, crc);
21459 +
21460 + crc = GetMirror32(crc);
21461 +
21462 + return crc;
21463 +}
21464 +
21465 +/* ......................................................................... */
21466 +
21467 +static void TgecErrException(t_Handle h_Tgec)
21468 +{
21469 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21470 + uint32_t event;
21471 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21472 +
21473 + /* do not handle MDIO events */
21474 + event = fman_tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21475 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21476 +
21477 + fman_tgec_ack_event(p_TgecMemMap, event);
21478 +
21479 + if (event & TGEC_IMASK_REM_FAULT)
21480 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT);
21481 + if (event & TGEC_IMASK_LOC_FAULT)
21482 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT);
21483 + if (event & TGEC_IMASK_TX_ECC_ER)
21484 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
21485 + if (event & TGEC_IMASK_TX_FIFO_UNFL)
21486 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL);
21487 + if (event & TGEC_IMASK_TX_FIFO_OVFL)
21488 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL);
21489 + if (event & TGEC_IMASK_TX_ER)
21490 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER);
21491 + if (event & TGEC_IMASK_RX_FIFO_OVFL)
21492 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL);
21493 + if (event & TGEC_IMASK_RX_ECC_ER)
21494 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
21495 + if (event & TGEC_IMASK_RX_JAB_FRM)
21496 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM);
21497 + if (event & TGEC_IMASK_RX_OVRSZ_FRM)
21498 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM);
21499 + if (event & TGEC_IMASK_RX_RUNT_FRM)
21500 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM);
21501 + if (event & TGEC_IMASK_RX_FRAG_FRM)
21502 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM);
21503 + if (event & TGEC_IMASK_RX_LEN_ER)
21504 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER);
21505 + if (event & TGEC_IMASK_RX_CRC_ER)
21506 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER);
21507 + if (event & TGEC_IMASK_RX_ALIGN_ER)
21508 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER);
21509 +}
21510 +
21511 +/* ......................................................................... */
21512 +
21513 +static void TgecException(t_Handle h_Tgec)
21514 +{
21515 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21516 + uint32_t event;
21517 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21518 +
21519 + /* handle only MDIO events */
21520 + event = fman_tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21521 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21522 +
21523 + fman_tgec_ack_event(p_TgecMemMap, event);
21524 +
21525 + if (event & TGEC_IMASK_MDIO_SCAN_EVENT)
21526 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO);
21527 + if (event & TGEC_IMASK_MDIO_CMD_CMPL)
21528 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL);
21529 +}
21530 +
21531 +/* ......................................................................... */
21532 +
21533 +static void FreeInitResources(t_Tgec *p_Tgec)
21534 +{
21535 + if (p_Tgec->mdioIrq != NO_IRQ)
21536 + {
21537 + XX_DisableIntr(p_Tgec->mdioIrq);
21538 + XX_FreeIntr(p_Tgec->mdioIrq);
21539 + }
21540 +
21541 + FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR);
21542 +
21543 + /* release the driver's group hash table */
21544 + FreeHashTable(p_Tgec->p_MulticastAddrHash);
21545 + p_Tgec->p_MulticastAddrHash = NULL;
21546 +
21547 + /* release the driver's individual hash table */
21548 + FreeHashTable(p_Tgec->p_UnicastAddrHash);
21549 + p_Tgec->p_UnicastAddrHash = NULL;
21550 +}
21551 +
21552 +
21553 +/*****************************************************************************/
21554 +/* 10G MAC API routines */
21555 +/*****************************************************************************/
21556 +
21557 +/* ......................................................................... */
21558 +
21559 +static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode)
21560 +{
21561 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21562 +
21563 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21564 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21565 +
21566 + fman_tgec_enable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21567 +
21568 + return E_OK;
21569 +}
21570 +
21571 +/* ......................................................................... */
21572 +
21573 +static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode)
21574 +{
21575 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21576 +
21577 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21578 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21579 +
21580 + fman_tgec_disable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21581 +
21582 + return E_OK;
21583 +}
21584 +
21585 +/* ......................................................................... */
21586 +
21587 +static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal)
21588 +{
21589 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21590 +
21591 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21592 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21593 +
21594 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, newVal);
21595 +
21596 + return E_OK;
21597 +}
21598 +
21599 +
21600 +/*****************************************************************************/
21601 +/* Tgec Configs modification functions */
21602 +/*****************************************************************************/
21603 +
21604 +/* ......................................................................... */
21605 +
21606 +static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal)
21607 +{
21608 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21609 +
21610 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21611 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21612 +
21613 + p_Tgec->p_TgecDriverParam->loopback_enable = newVal;
21614 +
21615 + return E_OK;
21616 +}
21617 +
21618 +/* ......................................................................... */
21619 +
21620 +static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal)
21621 +{
21622 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21623 +
21624 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21625 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21626 +
21627 + p_Tgec->p_TgecDriverParam->wan_mode_enable = newVal;
21628 +
21629 + return E_OK;
21630 +}
21631 +
21632 +/* ......................................................................... */
21633 +
21634 +static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal)
21635 +{
21636 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21637 +
21638 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21639 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21640 +
21641 + p_Tgec->p_TgecDriverParam->max_frame_length = newVal;
21642 +
21643 + return E_OK;
21644 +}
21645 +
21646 +/* ......................................................................... */
21647 +
21648 +static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal)
21649 +{
21650 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21651 +
21652 + UNUSED(newVal);
21653 +
21654 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21655 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21656 +
21657 + p_Tgec->p_TgecDriverParam->no_length_check_enable = !newVal;
21658 +
21659 + return E_OK;
21660 +}
21661 +
21662 +/* ......................................................................... */
21663 +
21664 +static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
21665 +{
21666 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21667 + uint32_t bitMask = 0;
21668 +
21669 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21670 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21671 +
21672 + GET_EXCEPTION_FLAG(bitMask, exception);
21673 + if (bitMask)
21674 + {
21675 + if (enable)
21676 + p_Tgec->exceptions |= bitMask;
21677 + else
21678 + p_Tgec->exceptions &= ~bitMask;
21679 + }
21680 + else
21681 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
21682 +
21683 + return E_OK;
21684 +}
21685 +
21686 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
21687 +/* ......................................................................... */
21688 +
21689 +static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec)
21690 +{
21691 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21692 +
21693 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21694 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21695 +
21696 + p_Tgec->p_TgecDriverParam->skip_fman11_workaround = TRUE;
21697 +
21698 + return E_OK;
21699 +}
21700 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
21701 +
21702 +
21703 +/*****************************************************************************/
21704 +/* Tgec Run Time API functions */
21705 +/*****************************************************************************/
21706 +
21707 +/* ......................................................................... */
21708 +/* backward compatibility. will be removed in the future. */
21709 +static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime)
21710 +{
21711 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21712 +
21713 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21714 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21715 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21716 +
21717 +
21718 + return E_OK;
21719 +}
21720 +
21721 +/* ......................................................................... */
21722 +
21723 +static t_Error TgecSetTxPauseFrames(t_Handle h_Tgec,
21724 + uint8_t priority,
21725 + uint16_t pauseTime,
21726 + uint16_t threshTime)
21727 +{
21728 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21729 +
21730 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21731 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21732 +
21733 + UNUSED(priority); UNUSED(threshTime);
21734 +
21735 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21736 +
21737 + return E_OK;
21738 +}
21739 +
21740 +/* ......................................................................... */
21741 +
21742 +static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en)
21743 +{
21744 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21745 +
21746 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21747 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21748 +
21749 + fman_tgec_set_rx_ignore_pause_frames(p_Tgec->p_MemMap, en);
21750 +
21751 + return E_OK;
21752 +}
21753 +
21754 +/* ......................................................................... */
21755 +
21756 +static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics)
21757 +{
21758 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21759 + struct tgec_regs *p_TgecMemMap;
21760 +
21761 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21762 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21763 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
21764 +
21765 + p_TgecMemMap = p_Tgec->p_MemMap;
21766 +
21767 + p_Statistics->eStatPkts64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
21768 + p_Statistics->eStatPkts65to127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
21769 + p_Statistics->eStatPkts128to255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
21770 + p_Statistics->eStatPkts256to511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
21771 + p_Statistics->eStatPkts512to1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
21772 + p_Statistics->eStatPkts1024to1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
21773 + p_Statistics->eStatPkts1519to1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
21774 +/* */
21775 + p_Statistics->eStatFragments = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG);
21776 + p_Statistics->eStatJabbers = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR);
21777 +
21778 + p_Statistics->eStatsDropEvents = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP);
21779 + p_Statistics->eStatCRCAlignErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN);
21780 +
21781 + p_Statistics->eStatUndersizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND);
21782 + p_Statistics->eStatOversizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR);
21783 +/* Pause */
21784 + p_Statistics->reStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF);
21785 + p_Statistics->teStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF);
21786 +
21787 +/* MIB II */
21788 + p_Statistics->ifInOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT);
21789 + p_Statistics->ifInUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA);
21790 + p_Statistics->ifInMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA);
21791 + p_Statistics->ifInBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RBCA);
21792 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
21793 + + p_Statistics->ifInMcastPkts
21794 + + p_Statistics->ifInBcastPkts;
21795 + p_Statistics->ifInDiscards = 0;
21796 + p_Statistics->ifInErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR);
21797 +
21798 + p_Statistics->ifOutOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT);
21799 + p_Statistics->ifOutUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA);
21800 + p_Statistics->ifOutMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA);
21801 + p_Statistics->ifOutBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TBCA);
21802 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
21803 + + p_Statistics->ifOutMcastPkts
21804 + + p_Statistics->ifOutBcastPkts;
21805 + p_Statistics->ifOutDiscards = 0;
21806 + p_Statistics->ifOutErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TERR);
21807 +
21808 + return E_OK;
21809 +}
21810 +
21811 +/* ......................................................................... */
21812 +
21813 +static t_Error TgecGetFrameSizeCounters(t_Handle h_Tgec, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
21814 +{
21815 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21816 + struct tgec_regs *p_TgecMemMap;
21817 +
21818 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21819 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21820 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
21821 +
21822 + p_TgecMemMap = p_Tgec->p_MemMap;
21823 +
21824 + switch (type)
21825 + {
21826 + case e_COMM_MODE_NONE:
21827 + break;
21828 +
21829 + case e_COMM_MODE_RX:
21830 + p_FrameSizeCounters->count_pkts_64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
21831 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
21832 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
21833 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
21834 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
21835 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
21836 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
21837 + break;
21838 +
21839 + case e_COMM_MODE_TX:
21840 + //Tx counters not supported
21841 + break;
21842 +
21843 + case e_COMM_MODE_RX_AND_TX:
21844 + //Tx counters not supported
21845 + break;
21846 + }
21847 +
21848 + return E_OK;
21849 +}
21850 +
21851 +
21852 +/* ......................................................................... */
21853 +
21854 +static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec)
21855 +{
21856 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21857 +
21858 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21859 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21860 +
21861 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 1);
21862 +
21863 + return E_OK;
21864 +}
21865 +
21866 +/* ......................................................................... */
21867 +
21868 +static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec)
21869 +{
21870 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21871 +
21872 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21873 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21874 +
21875 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 0);
21876 +
21877 + return E_OK;
21878 +}
21879 +
21880 +/* ......................................................................... */
21881 +
21882 +static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr)
21883 +{
21884 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21885 +
21886 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21887 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21888 +
21889 + p_Tgec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
21890 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)(*p_EnetAddr));
21891 +
21892 + return E_OK;
21893 +}
21894 +
21895 +/* ......................................................................... */
21896 +
21897 +static t_Error TgecResetCounters (t_Handle h_Tgec)
21898 +{
21899 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21900 +
21901 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21902 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21903 +
21904 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
21905 +
21906 + return E_OK;
21907 +}
21908 +
21909 +/* ......................................................................... */
21910 +
21911 +static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
21912 +{
21913 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
21914 + uint64_t ethAddr;
21915 + uint8_t paddrNum;
21916 +
21917 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21918 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21919 +
21920 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
21921 +
21922 + if (ethAddr & GROUP_ADDRESS)
21923 + /* Multicast address has no effect in PADDR */
21924 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
21925 +
21926 + /* Make sure no PADDR contains this address */
21927 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
21928 + if (p_Tgec->indAddrRegUsed[paddrNum])
21929 + if (p_Tgec->paddr[paddrNum] == ethAddr)
21930 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
21931 +
21932 + /* Find first unused PADDR */
21933 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
21934 + {
21935 + if (!(p_Tgec->indAddrRegUsed[paddrNum]))
21936 + {
21937 + /* mark this PADDR as used */
21938 + p_Tgec->indAddrRegUsed[paddrNum] = TRUE;
21939 + /* store address */
21940 + p_Tgec->paddr[paddrNum] = ethAddr;
21941 +
21942 + /* put in hardware */
21943 + fman_tgec_add_addr_in_paddr(p_Tgec->p_MemMap, (uint8_t*)(*p_EthAddr)/* , paddrNum */);
21944 + p_Tgec->numOfIndAddrInRegs++;
21945 +
21946 + return E_OK;
21947 + }
21948 + }
21949 +
21950 + /* No free PADDR */
21951 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
21952 +}
21953 +
21954 +/* ......................................................................... */
21955 +
21956 +static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
21957 +{
21958 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
21959 + uint64_t ethAddr;
21960 + uint8_t paddrNum;
21961 +
21962 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21963 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21964 +
21965 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
21966 +
21967 + /* Find used PADDR containing this address */
21968 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
21969 + {
21970 + if ((p_Tgec->indAddrRegUsed[paddrNum]) &&
21971 + (p_Tgec->paddr[paddrNum] == ethAddr))
21972 + {
21973 + /* mark this PADDR as not used */
21974 + p_Tgec->indAddrRegUsed[paddrNum] = FALSE;
21975 + /* clear in hardware */
21976 + fman_tgec_clear_addr_in_paddr(p_Tgec->p_MemMap /*, paddrNum */);
21977 + p_Tgec->numOfIndAddrInRegs--;
21978 +
21979 + return E_OK;
21980 + }
21981 + }
21982 +
21983 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
21984 +}
21985 +
21986 +/* ......................................................................... */
21987 +
21988 +static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
21989 +{
21990 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21991 + t_EthHashEntry *p_HashEntry;
21992 + uint32_t crc;
21993 + uint32_t hash;
21994 + uint64_t ethAddr;
21995 +
21996 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21997 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21998 +
21999 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22000 +
22001 + if (!(ethAddr & GROUP_ADDRESS))
22002 + /* Unicast addresses not supported in hash */
22003 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
22004 +
22005 + /* CRC calculation */
22006 + crc = GetMacAddrHashCode(ethAddr);
22007 +
22008 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
22009 +
22010 + /* Create element to be added to the driver hash table */
22011 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
22012 + p_HashEntry->addr = ethAddr;
22013 + INIT_LIST(&p_HashEntry->node);
22014 +
22015 + LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]));
22016 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash | TGEC_HASH_MCAST_EN));
22017 +
22018 + return E_OK;
22019 +}
22020 +
22021 +/* ......................................................................... */
22022 +
22023 +static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22024 +{
22025 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22026 + t_EthHashEntry *p_HashEntry = NULL;
22027 + t_List *p_Pos;
22028 + uint32_t crc;
22029 + uint32_t hash;
22030 + uint64_t ethAddr;
22031 +
22032 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22033 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22034 +
22035 + ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
22036 +
22037 + /* CRC calculation */
22038 + crc = GetMacAddrHashCode(ethAddr);
22039 +
22040 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
22041 +
22042 + LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
22043 + {
22044 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
22045 + if (p_HashEntry->addr == ethAddr)
22046 + {
22047 + LIST_DelAndInit(&p_HashEntry->node);
22048 + XX_Free(p_HashEntry);
22049 + break;
22050 + }
22051 + }
22052 + if (LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
22053 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash & ~TGEC_HASH_MCAST_EN));
22054 +
22055 + return E_OK;
22056 +}
22057 +
22058 +/* ......................................................................... */
22059 +
22060 +static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId)
22061 +{
22062 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22063 +
22064 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22065 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22066 +
22067 + UNUSED(p_Tgec);
22068 + UNUSED(macId);
22069 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported"));
22070 +}
22071 +
22072 +/* ......................................................................... */
22073 +
22074 +static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion)
22075 +{
22076 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22077 +
22078 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22079 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22080 +
22081 + *macVersion = fman_tgec_get_revision(p_Tgec->p_MemMap);
22082 +
22083 + return E_OK;
22084 +}
22085 +
22086 +/* ......................................................................... */
22087 +
22088 +static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
22089 +{
22090 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22091 + uint32_t bitMask = 0;
22092 +
22093 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22094 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22095 +
22096 + GET_EXCEPTION_FLAG(bitMask, exception);
22097 + if (bitMask)
22098 + {
22099 + if (enable)
22100 + p_Tgec->exceptions |= bitMask;
22101 + else
22102 + p_Tgec->exceptions &= ~bitMask;
22103 + }
22104 + else
22105 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
22106 +
22107 + if (enable)
22108 + fman_tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask);
22109 + else
22110 + fman_tgec_disable_interrupt(p_Tgec->p_MemMap, bitMask);
22111 +
22112 + return E_OK;
22113 +}
22114 +
22115 +/* ......................................................................... */
22116 +
22117 +static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec)
22118 +{
22119 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22120 +
22121 + SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0);
22122 + SANITY_CHECK_RETURN_VALUE(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE, 0);
22123 +
22124 + return fman_tgec_get_max_frame_len(p_Tgec->p_MemMap);
22125 +}
22126 +
22127 +/* ......................................................................... */
22128 +
22129 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22130 +static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec)
22131 +{
22132 + t_Error err;
22133 +
22134 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22135 + XX_Print("Applying 10G TX ECC workaround (10GMAC-A004) ... ");
22136 +#endif /* (DEBUG_ERRORS > 0) */
22137 + /* enable and set promiscuous */
22138 + fman_tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE);
22139 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE);
22140 + err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId);
22141 + /* disable */
22142 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE);
22143 + fman_tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE);
22144 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
22145 + fman_tgec_ack_event(p_Tgec->p_MemMap, 0xffffffff);
22146 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22147 + if (err)
22148 + XX_Print("FAILED!\n");
22149 + else
22150 + XX_Print("done.\n");
22151 +#endif /* (DEBUG_ERRORS > 0) */
22152 +
22153 + return err;
22154 +}
22155 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22156 +
22157 +/*****************************************************************************/
22158 +/* FM Init & Free API */
22159 +/*****************************************************************************/
22160 +
22161 +/* ......................................................................... */
22162 +
22163 +static t_Error TgecInit(t_Handle h_Tgec)
22164 +{
22165 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22166 + struct tgec_cfg *p_TgecDriverParam;
22167 + t_EnetAddr ethAddr;
22168 + t_Error err;
22169 +
22170 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22171 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22172 + SANITY_CHECK_RETURN_ERROR(p_Tgec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
22173 +
22174 + FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &p_Tgec->fmMacControllerDriver.fmRevInfo);
22175 + CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters);
22176 +
22177 + p_TgecDriverParam = p_Tgec->p_TgecDriverParam;
22178 +
22179 + MAKE_ENET_ADDR_FROM_UINT64(p_Tgec->addr, ethAddr);
22180 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)ethAddr);
22181 +
22182 + /* interrupts */
22183 +#ifdef FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
22184 + {
22185 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev <=2)
22186 + p_Tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT | TGEC_IMASK_LOC_FAULT);
22187 + }
22188 +#endif /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 */
22189 +
22190 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22191 + if (!p_Tgec->p_TgecDriverParam->skip_fman11_workaround &&
22192 + ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK))
22193 + {
22194 + FreeInitResources(p_Tgec);
22195 + REPORT_ERROR(MINOR, err, ("TgecTxEccWorkaround FAILED"));
22196 + }
22197 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22198 +
22199 + err = fman_tgec_init(p_Tgec->p_MemMap, p_TgecDriverParam, p_Tgec->exceptions);
22200 + if (err)
22201 + {
22202 + FreeInitResources(p_Tgec);
22203 + RETURN_ERROR(MAJOR, err, ("This TGEC version does not support the required i/f mode"));
22204 + }
22205 +
22206 + /* Max Frame Length */
22207 + err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm,
22208 + e_FM_MAC_10G,
22209 + p_Tgec->fmMacControllerDriver.macId,
22210 + p_TgecDriverParam->max_frame_length);
22211 + if (err != E_OK)
22212 + {
22213 + FreeInitResources(p_Tgec);
22214 + RETURN_ERROR(MINOR, err, NO_MSG);
22215 + }
22216 +/* we consider having no IPC a non crasher... */
22217 +
22218 +#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
22219 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
22220 + fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(p_Tgec->p_MemMap);
22221 +#endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */
22222 +
22223 + p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22224 + if (!p_Tgec->p_MulticastAddrHash)
22225 + {
22226 + FreeInitResources(p_Tgec);
22227 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22228 + }
22229 +
22230 + p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22231 + if (!p_Tgec->p_UnicastAddrHash)
22232 + {
22233 + FreeInitResources(p_Tgec);
22234 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22235 + }
22236 +
22237 + FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm,
22238 + e_FM_MOD_10G_MAC,
22239 + p_Tgec->macId,
22240 + e_FM_INTR_TYPE_ERR,
22241 + TgecErrException,
22242 + p_Tgec);
22243 + if (p_Tgec->mdioIrq != NO_IRQ)
22244 + {
22245 + XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec);
22246 + XX_EnableIntr(p_Tgec->mdioIrq);
22247 + }
22248 +
22249 + XX_Free(p_TgecDriverParam);
22250 + p_Tgec->p_TgecDriverParam = NULL;
22251 +
22252 + return E_OK;
22253 +}
22254 +
22255 +/* ......................................................................... */
22256 +
22257 +static t_Error TgecFree(t_Handle h_Tgec)
22258 +{
22259 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22260 +
22261 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22262 +
22263 + if (p_Tgec->p_TgecDriverParam)
22264 + {
22265 + /* Called after config */
22266 + XX_Free(p_Tgec->p_TgecDriverParam);
22267 + p_Tgec->p_TgecDriverParam = NULL;
22268 + }
22269 + else
22270 + /* Called after init */
22271 + FreeInitResources(p_Tgec);
22272 +
22273 + XX_Free(p_Tgec);
22274 +
22275 + return E_OK;
22276 +}
22277 +
22278 +/* ......................................................................... */
22279 +
22280 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
22281 +{
22282 + p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit;
22283 + p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree;
22284 +
22285 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
22286 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback;
22287 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength;
22288 +
22289 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = TgecConfigWan;
22290 +
22291 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = NULL; /* TGEC always works with pad+crc */
22292 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */
22293 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck;
22294 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException;
22295 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
22296 +
22297 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22298 + p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround;
22299 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22300 +
22301 + p_FmMacControllerDriver->f_FM_MAC_SetException = TgecSetExcpetion;
22302 +
22303 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = TgecEnable1588TimeStamp;
22304 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = TgecDisable1588TimeStamp;
22305 +
22306 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous;
22307 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL;
22308 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = NULL;
22309 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
22310 +
22311 + p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable;
22312 + p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable;
22313 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
22314 +
22315 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause;
22316 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = TgecSetTxPauseFrames;
22317 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause;
22318 +
22319 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters;
22320 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics;
22321 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = TgecGetFrameSizeCounters;
22322 +
22323 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress;
22324 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress;
22325 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = TgecDelHashMacAddress;
22326 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = TgecAddExactMatchMacAddress;
22327 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = TgecDelExactMatchMacAddress;
22328 + p_FmMacControllerDriver->f_FM_MAC_GetId = TgecGetId;
22329 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = TgecGetVersion;
22330 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = TgecGetMaxFrameLength;
22331 +
22332 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg;
22333 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg;
22334 +}
22335 +
22336 +
22337 +/*****************************************************************************/
22338 +/* Tgec Config Main Entry */
22339 +/*****************************************************************************/
22340 +
22341 +/* ......................................................................... */
22342 +
22343 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam)
22344 +{
22345 + t_Tgec *p_Tgec;
22346 + struct tgec_cfg *p_TgecDriverParam;
22347 + uintptr_t baseAddr;
22348 +
22349 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
22350 +
22351 + baseAddr = p_FmMacParam->baseAddr;
22352 + /* allocate memory for the UCC GETH data structure. */
22353 + p_Tgec = (t_Tgec *)XX_Malloc(sizeof(t_Tgec));
22354 + if (!p_Tgec)
22355 + {
22356 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure"));
22357 + return NULL;
22358 + }
22359 + memset(p_Tgec, 0, sizeof(t_Tgec));
22360 + InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver);
22361 +
22362 + /* allocate memory for the 10G MAC driver parameters data structure. */
22363 + p_TgecDriverParam = (struct tgec_cfg *) XX_Malloc(sizeof(struct tgec_cfg));
22364 + if (!p_TgecDriverParam)
22365 + {
22366 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters"));
22367 + XX_Free(p_Tgec);
22368 + return NULL;
22369 + }
22370 + memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg));
22371 +
22372 + /* Plant parameter structure pointer */
22373 + p_Tgec->p_TgecDriverParam = p_TgecDriverParam;
22374 +
22375 + fman_tgec_defconfig(p_TgecDriverParam);
22376 +
22377 + p_Tgec->p_MemMap = (struct tgec_regs *)UINT_TO_PTR(baseAddr);
22378 + p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET);
22379 + p_Tgec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
22380 + p_Tgec->enetMode = p_FmMacParam->enetMode;
22381 + p_Tgec->macId = p_FmMacParam->macId;
22382 + p_Tgec->exceptions = DEFAULT_exceptions;
22383 + p_Tgec->mdioIrq = p_FmMacParam->mdioIrq;
22384 + p_Tgec->f_Exception = p_FmMacParam->f_Exception;
22385 + p_Tgec->f_Event = p_FmMacParam->f_Event;
22386 + p_Tgec->h_App = p_FmMacParam->h_App;
22387 +
22388 + return p_Tgec;
22389 +}
22390 --- /dev/null
22391 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
22392 @@ -0,0 +1,151 @@
22393 +/*
22394 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22395 + *
22396 + * Redistribution and use in source and binary forms, with or without
22397 + * modification, are permitted provided that the following conditions are met:
22398 + * * Redistributions of source code must retain the above copyright
22399 + * notice, this list of conditions and the following disclaimer.
22400 + * * Redistributions in binary form must reproduce the above copyright
22401 + * notice, this list of conditions and the following disclaimer in the
22402 + * documentation and/or other materials provided with the distribution.
22403 + * * Neither the name of Freescale Semiconductor nor the
22404 + * names of its contributors may be used to endorse or promote products
22405 + * derived from this software without specific prior written permission.
22406 + *
22407 + *
22408 + * ALTERNATIVELY, this software may be distributed under the terms of the
22409 + * GNU General Public License ("GPL") as published by the Free Software
22410 + * Foundation, either version 2 of that License or (at your option) any
22411 + * later version.
22412 + *
22413 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22414 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22415 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22416 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22417 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22418 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22419 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22420 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22421 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22422 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22423 + */
22424 +
22425 +
22426 +/******************************************************************************
22427 + @File tgec.h
22428 +
22429 + @Description FM 10G MAC ...
22430 +*//***************************************************************************/
22431 +#ifndef __TGEC_H
22432 +#define __TGEC_H
22433 +
22434 +#include "std_ext.h"
22435 +#include "error_ext.h"
22436 +#include "list_ext.h"
22437 +#include "enet_ext.h"
22438 +
22439 +#include "tgec_mii_acc.h"
22440 +#include "fm_mac.h"
22441 +
22442 +
22443 +#define DEFAULT_exceptions \
22444 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
22445 + TGEC_IMASK_REM_FAULT | \
22446 + TGEC_IMASK_LOC_FAULT | \
22447 + TGEC_IMASK_TX_ECC_ER | \
22448 + TGEC_IMASK_TX_FIFO_UNFL | \
22449 + TGEC_IMASK_TX_FIFO_OVFL | \
22450 + TGEC_IMASK_TX_ER | \
22451 + TGEC_IMASK_RX_FIFO_OVFL | \
22452 + TGEC_IMASK_RX_ECC_ER | \
22453 + TGEC_IMASK_RX_JAB_FRM | \
22454 + TGEC_IMASK_RX_OVRSZ_FRM | \
22455 + TGEC_IMASK_RX_RUNT_FRM | \
22456 + TGEC_IMASK_RX_FRAG_FRM | \
22457 + TGEC_IMASK_RX_CRC_ER | \
22458 + TGEC_IMASK_RX_ALIGN_ER))
22459 +
22460 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
22461 + case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \
22462 + bitMask = TGEC_IMASK_MDIO_SCAN_EVENT ; break; \
22463 + case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \
22464 + bitMask = TGEC_IMASK_MDIO_CMD_CMPL ; break; \
22465 + case e_FM_MAC_EX_10G_REM_FAULT: \
22466 + bitMask = TGEC_IMASK_REM_FAULT ; break; \
22467 + case e_FM_MAC_EX_10G_LOC_FAULT: \
22468 + bitMask = TGEC_IMASK_LOC_FAULT ; break; \
22469 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
22470 + bitMask = TGEC_IMASK_TX_ECC_ER ; break; \
22471 + case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \
22472 + bitMask = TGEC_IMASK_TX_FIFO_UNFL ; break; \
22473 + case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \
22474 + bitMask = TGEC_IMASK_TX_FIFO_OVFL ; break; \
22475 + case e_FM_MAC_EX_10G_TX_ER: \
22476 + bitMask = TGEC_IMASK_TX_ER ; break; \
22477 + case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \
22478 + bitMask = TGEC_IMASK_RX_FIFO_OVFL ; break; \
22479 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
22480 + bitMask = TGEC_IMASK_RX_ECC_ER ; break; \
22481 + case e_FM_MAC_EX_10G_RX_JAB_FRM: \
22482 + bitMask = TGEC_IMASK_RX_JAB_FRM ; break; \
22483 + case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \
22484 + bitMask = TGEC_IMASK_RX_OVRSZ_FRM ; break; \
22485 + case e_FM_MAC_EX_10G_RX_RUNT_FRM: \
22486 + bitMask = TGEC_IMASK_RX_RUNT_FRM ; break; \
22487 + case e_FM_MAC_EX_10G_RX_FRAG_FRM: \
22488 + bitMask = TGEC_IMASK_RX_FRAG_FRM ; break; \
22489 + case e_FM_MAC_EX_10G_RX_LEN_ER: \
22490 + bitMask = TGEC_IMASK_RX_LEN_ER ; break; \
22491 + case e_FM_MAC_EX_10G_RX_CRC_ER: \
22492 + bitMask = TGEC_IMASK_RX_CRC_ER ; break; \
22493 + case e_FM_MAC_EX_10G_RX_ALIGN_ER: \
22494 + bitMask = TGEC_IMASK_RX_ALIGN_ER ; break; \
22495 + default: bitMask = 0;break;}
22496 +
22497 +#define MAX_PACKET_ALIGNMENT 31
22498 +#define MAX_INTER_PACKET_GAP 0x7f
22499 +#define MAX_INTER_PALTERNATE_BEB 0x0f
22500 +#define MAX_RETRANSMISSION 0x0f
22501 +#define MAX_COLLISION_WINDOW 0x03ff
22502 +
22503 +#define TGEC_NUM_OF_PADDRS 1 /* number of pattern match registers (entries) */
22504 +
22505 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
22506 +
22507 +#define HASH_TABLE_SIZE 512 /* Hash table size (= 32 bits * 8 regs) */
22508 +
22509 +#define TGEC_TO_MII_OFFSET 0x1030 /* Offset from the MEM map to the MDIO mem map */
22510 +
22511 +/* 10-gigabit Ethernet MAC Controller ID (10GEC_ID) */
22512 +#define TGEC_ID_ID 0xffff0000
22513 +#define TGEC_ID_MAC_VERSION 0x0000FF00
22514 +#define TGEC_ID_MAC_REV 0x000000ff
22515 +
22516 +
22517 +typedef struct {
22518 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
22519 + t_Handle h_App; /**< Handle to the upper layer application */
22520 + struct tgec_regs *p_MemMap; /**< pointer to 10G memory mapped registers. */
22521 + t_TgecMiiAccessMemMap *p_MiiMemMap; /**< pointer to MII memory mapped registers. */
22522 + uint64_t addr; /**< MAC address of device; */
22523 + e_EnetMode enetMode; /**< Ethernet physical interface */
22524 + t_FmMacExceptionCallback *f_Exception;
22525 + int mdioIrq;
22526 + t_FmMacExceptionCallback *f_Event;
22527 + bool indAddrRegUsed[TGEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
22528 + uint64_t paddr[TGEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
22529 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
22530 + t_EthHash *p_MulticastAddrHash; /**< pointer to driver's global address hash table */
22531 + t_EthHash *p_UnicastAddrHash; /**< pointer to driver's individual address hash table */
22532 + bool debugMode;
22533 + uint8_t macId;
22534 + uint32_t exceptions;
22535 + struct tgec_cfg *p_TgecDriverParam;
22536 +} t_Tgec;
22537 +
22538 +
22539 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t data);
22540 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
22541 +
22542 +
22543 +#endif /* __TGEC_H */
22544 --- /dev/null
22545 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
22546 @@ -0,0 +1,139 @@
22547 +/*
22548 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22549 + *
22550 + * Redistribution and use in source and binary forms, with or without
22551 + * modification, are permitted provided that the following conditions are met:
22552 + * * Redistributions of source code must retain the above copyright
22553 + * notice, this list of conditions and the following disclaimer.
22554 + * * Redistributions in binary form must reproduce the above copyright
22555 + * notice, this list of conditions and the following disclaimer in the
22556 + * documentation and/or other materials provided with the distribution.
22557 + * * Neither the name of Freescale Semiconductor nor the
22558 + * names of its contributors may be used to endorse or promote products
22559 + * derived from this software without specific prior written permission.
22560 + *
22561 + *
22562 + * ALTERNATIVELY, this software may be distributed under the terms of the
22563 + * GNU General Public License ("GPL") as published by the Free Software
22564 + * Foundation, either version 2 of that License or (at your option) any
22565 + * later version.
22566 + *
22567 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22568 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22569 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22570 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22571 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22572 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22573 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22574 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22575 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22576 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22577 + */
22578 +
22579 +
22580 +
22581 +#include "error_ext.h"
22582 +#include "std_ext.h"
22583 +#include "fm_mac.h"
22584 +#include "tgec.h"
22585 +#include "xx_ext.h"
22586 +
22587 +#include "fm_common.h"
22588 +
22589 +
22590 +/*****************************************************************************/
22591 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec,
22592 + uint8_t phyAddr,
22593 + uint8_t reg,
22594 + uint16_t data)
22595 +{
22596 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22597 + t_TgecMiiAccessMemMap *p_MiiAccess;
22598 + uint32_t cfgStatusReg;
22599 +
22600 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22601 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22602 +
22603 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22604 +
22605 + /* Configure MII */
22606 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22607 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22608 + /* (one half of fm clock => 2.5Mhz) */
22609 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22610 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22611 +
22612 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22613 + XX_UDelay (1);
22614 +
22615 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22616 +
22617 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22618 +
22619 + CORE_MemoryBarrier();
22620 +
22621 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22622 + XX_UDelay (1);
22623 +
22624 + WRITE_UINT32(p_MiiAccess->mdio_data, data);
22625 +
22626 + CORE_MemoryBarrier();
22627 +
22628 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22629 + XX_UDelay (1);
22630 +
22631 + return E_OK;
22632 +}
22633 +
22634 +/*****************************************************************************/
22635 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec,
22636 + uint8_t phyAddr,
22637 + uint8_t reg,
22638 + uint16_t *p_Data)
22639 +{
22640 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22641 + t_TgecMiiAccessMemMap *p_MiiAccess;
22642 + uint32_t cfgStatusReg;
22643 +
22644 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22645 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22646 +
22647 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22648 +
22649 + /* Configure MII */
22650 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22651 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22652 + /* (one half of fm clock => 2.5Mhz) */
22653 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22654 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22655 +
22656 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22657 + XX_UDelay (1);
22658 +
22659 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22660 +
22661 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22662 +
22663 + CORE_MemoryBarrier();
22664 +
22665 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22666 + XX_UDelay (1);
22667 +
22668 + WRITE_UINT32(p_MiiAccess->mdio_command, (uint32_t)(phyAddr | MIIMCOM_READ_CYCLE));
22669 +
22670 + CORE_MemoryBarrier();
22671 +
22672 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22673 + XX_UDelay (1);
22674 +
22675 + *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data);
22676 +
22677 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22678 +
22679 + if (cfgStatusReg & MIIMIND_READ_ERROR)
22680 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
22681 + ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfgStatusReg 0x%x",
22682 + ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfgStatusReg));
22683 +
22684 + return E_OK;
22685 +}
22686 --- /dev/null
22687 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
22688 @@ -0,0 +1,80 @@
22689 +/*
22690 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22691 + *
22692 + * Redistribution and use in source and binary forms, with or without
22693 + * modification, are permitted provided that the following conditions are met:
22694 + * * Redistributions of source code must retain the above copyright
22695 + * notice, this list of conditions and the following disclaimer.
22696 + * * Redistributions in binary form must reproduce the above copyright
22697 + * notice, this list of conditions and the following disclaimer in the
22698 + * documentation and/or other materials provided with the distribution.
22699 + * * Neither the name of Freescale Semiconductor nor the
22700 + * names of its contributors may be used to endorse or promote products
22701 + * derived from this software without specific prior written permission.
22702 + *
22703 + *
22704 + * ALTERNATIVELY, this software may be distributed under the terms of the
22705 + * GNU General Public License ("GPL") as published by the Free Software
22706 + * Foundation, either version 2 of that License or (at your option) any
22707 + * later version.
22708 + *
22709 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22710 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22711 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22712 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22713 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22714 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22715 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22716 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22717 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22718 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22719 + */
22720 +
22721 +
22722 +#ifndef __TGEC_MII_ACC_H
22723 +#define __TGEC_MII_ACC_H
22724 +
22725 +#include "std_ext.h"
22726 +
22727 +
22728 +/* MII Management Command Register */
22729 +#define MIIMCOM_READ_POST_INCREMENT 0x00004000
22730 +#define MIIMCOM_READ_CYCLE 0x00008000
22731 +#define MIIMCOM_SCAN_CYCLE 0x00000800
22732 +#define MIIMCOM_PREAMBLE_DISABLE 0x00000400
22733 +
22734 +#define MIIMCOM_MDIO_HOLD_1_REG_CLK 0
22735 +#define MIIMCOM_MDIO_HOLD_2_REG_CLK 1
22736 +#define MIIMCOM_MDIO_HOLD_3_REG_CLK 2
22737 +#define MIIMCOM_MDIO_HOLD_4_REG_CLK 3
22738 +
22739 +#define MIIMCOM_DIV_MASK 0x0000ff00
22740 +#define MIIMCOM_DIV_SHIFT 8
22741 +
22742 +/* MII Management Indicator Register */
22743 +#define MIIMIND_BUSY 0x00000001
22744 +#define MIIMIND_READ_ERROR 0x00000002
22745 +
22746 +#define MIIDATA_BUSY 0x80000000
22747 +
22748 +#if defined(__MWERKS__) && !defined(__GNUC__)
22749 +#pragma pack(push,1)
22750 +#endif /* defined(__MWERKS__) && ... */
22751 +
22752 +/*----------------------------------------------------*/
22753 +/* MII Configuration Control Memory Map Registers */
22754 +/*----------------------------------------------------*/
22755 +typedef _Packed struct t_TgecMiiAccessMemMap
22756 +{
22757 + volatile uint32_t mdio_cfg_status; /* 0x030 */
22758 + volatile uint32_t mdio_command; /* 0x034 */
22759 + volatile uint32_t mdio_data; /* 0x038 */
22760 + volatile uint32_t mdio_regaddr; /* 0x03c */
22761 +} _PackedType t_TgecMiiAccessMemMap ;
22762 +
22763 +#if defined(__MWERKS__) && !defined(__GNUC__)
22764 +#pragma pack(pop)
22765 +#endif /* defined(__MWERKS__) && ... */
22766 +
22767 +
22768 +#endif /* __TGEC_MII_ACC_H */
22769 --- /dev/null
22770 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
22771 @@ -0,0 +1,15 @@
22772 +#
22773 +# Makefile for the Freescale Ethernet controllers
22774 +#
22775 +ccflags-y += -DVERSION=\"\"
22776 +#
22777 +#Include netcomm SW specific definitions
22778 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
22779 +
22780 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
22781 +
22782 +ccflags-y += -I$(NCSW_FM_INC)
22783 +
22784 +obj-y += fsl-ncsw-macsec.o
22785 +
22786 +fsl-ncsw-macsec-objs := fm_macsec.o fm_macsec_guest.o fm_macsec_master.o fm_macsec_secy.o
22787 --- /dev/null
22788 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
22789 @@ -0,0 +1,237 @@
22790 +/*
22791 + * Copyright 2008-2015 Freescale Semiconductor Inc.
22792 + *
22793 + * Redistribution and use in source and binary forms, with or without
22794 + * modification, are permitted provided that the following conditions are met:
22795 + * * Redistributions of source code must retain the above copyright
22796 + * notice, this list of conditions and the following disclaimer.
22797 + * * Redistributions in binary form must reproduce the above copyright
22798 + * notice, this list of conditions and the following disclaimer in the
22799 + * documentation and/or other materials provided with the distribution.
22800 + * * Neither the name of Freescale Semiconductor nor the
22801 + * names of its contributors may be used to endorse or promote products
22802 + * derived from this software without specific prior written permission.
22803 + *
22804 + *
22805 + * ALTERNATIVELY, this software may be distributed under the terms of the
22806 + * GNU General Public License ("GPL") as published by the Free Software
22807 + * Foundation, either version 2 of that License or (at your option) any
22808 + * later version.
22809 + *
22810 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22811 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22812 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22813 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22814 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22815 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22816 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22817 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22818 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22819 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22820 + */
22821 +/******************************************************************************
22822 +
22823 + @File fm_macsec.c
22824 +
22825 + @Description FM MACSEC driver routines implementation.
22826 +*//***************************************************************************/
22827 +
22828 +#include "std_ext.h"
22829 +#include "error_ext.h"
22830 +#include "xx_ext.h"
22831 +#include "string_ext.h"
22832 +#include "sprint_ext.h"
22833 +#include "debug_ext.h"
22834 +
22835 +#include "fm_macsec.h"
22836 +
22837 +
22838 +/****************************************/
22839 +/* API Init unit functions */
22840 +/****************************************/
22841 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam)
22842 +{
22843 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver;
22844 +
22845 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecParam, E_INVALID_HANDLE, NULL);
22846 +
22847 + if (p_FmMacsecParam->guestMode)
22848 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_GUEST_Config(p_FmMacsecParam);
22849 + else
22850 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_MASTER_Config(p_FmMacsecParam);
22851 +
22852 + if (!p_FmMacsecControllerDriver)
22853 + return NULL;
22854 +
22855 + return (t_Handle)p_FmMacsecControllerDriver;
22856 +}
22857 +
22858 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec)
22859 +{
22860 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22861 +
22862 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22863 +
22864 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Init)
22865 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Init(h_FmMacsec);
22866 +
22867 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22868 +}
22869 +
22870 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec)
22871 +{
22872 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22873 +
22874 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22875 +
22876 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Free)
22877 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Free(h_FmMacsec);
22878 +
22879 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22880 +}
22881 +
22882 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
22883 +{
22884 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22885 +
22886 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22887 +
22888 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment)
22889 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment(h_FmMacsec, treatMode);
22890 +
22891 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22892 +}
22893 +
22894 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
22895 +{
22896 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22897 +
22898 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22899 +
22900 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment)
22901 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment(h_FmMacsec, deliverUncontrolled);
22902 +
22903 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22904 +}
22905 +
22906 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
22907 +{
22908 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22909 +
22910 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22911 +
22912 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment)
22913 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(h_FmMacsec, discardUncontrolled);
22914 +
22915 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22916 +}
22917 +
22918 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
22919 +{
22920 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22921 +
22922 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22923 +
22924 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment)
22925 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment(h_FmMacsec, treatMode);
22926 +
22927 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22928 +}
22929 +
22930 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
22931 +{
22932 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22933 +
22934 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22935 +
22936 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold)
22937 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold(h_FmMacsec, pnExhThr);
22938 +
22939 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22940 +}
22941 +
22942 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec)
22943 +{
22944 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22945 +
22946 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22947 +
22948 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable)
22949 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable(h_FmMacsec);
22950 +
22951 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22952 +}
22953 +
22954 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec)
22955 +{
22956 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22957 +
22958 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22959 +
22960 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI)
22961 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI(h_FmMacsec);
22962 +
22963 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22964 +}
22965 +
22966 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
22967 +{
22968 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22969 +
22970 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22971 +
22972 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException)
22973 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException(h_FmMacsec, exception, enable);
22974 +
22975 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22976 +}
22977 +
22978 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
22979 +{
22980 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22981 +
22982 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22983 +
22984 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision)
22985 + return p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision(h_FmMacsec, p_MacsecRevision);
22986 +
22987 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22988 +}
22989 +
22990 +
22991 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec)
22992 +{
22993 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22994 +
22995 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22996 +
22997 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Enable)
22998 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Enable(h_FmMacsec);
22999 +
23000 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23001 +}
23002 +
23003 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec)
23004 +{
23005 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23006 +
23007 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23008 +
23009 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Disable)
23010 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Disable(h_FmMacsec);
23011 +
23012 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23013 +}
23014 +
23015 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23016 +{
23017 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23018 +
23019 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23020 +
23021 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_SetException)
23022 + return p_FmMacsecControllerDriver->f_FM_MACSEC_SetException(h_FmMacsec, exception, enable);
23023 +
23024 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23025 +}
23026 +
23027 --- /dev/null
23028 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
23029 @@ -0,0 +1,203 @@
23030 +/*
23031 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23032 + *
23033 + * Redistribution and use in source and binary forms, with or without
23034 + * modification, are permitted provided that the following conditions are met:
23035 + * * Redistributions of source code must retain the above copyright
23036 + * notice, this list of conditions and the following disclaimer.
23037 + * * Redistributions in binary form must reproduce the above copyright
23038 + * notice, this list of conditions and the following disclaimer in the
23039 + * documentation and/or other materials provided with the distribution.
23040 + * * Neither the name of Freescale Semiconductor nor the
23041 + * names of its contributors may be used to endorse or promote products
23042 + * derived from this software without specific prior written permission.
23043 + *
23044 + *
23045 + * ALTERNATIVELY, this software may be distributed under the terms of the
23046 + * GNU General Public License ("GPL") as published by the Free Software
23047 + * Foundation, either version 2 of that License or (at your option) any
23048 + * later version.
23049 + *
23050 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23051 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23052 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23053 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23054 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23055 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23056 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23057 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23058 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23059 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23060 + */
23061 +
23062 +/******************************************************************************
23063 + @File fm_macsec.h
23064 +
23065 + @Description FM MACSEC internal structures and definitions.
23066 +*//***************************************************************************/
23067 +#ifndef __FM_MACSEC_H
23068 +#define __FM_MACSEC_H
23069 +
23070 +#include "error_ext.h"
23071 +#include "std_ext.h"
23072 +#include "fm_macsec_ext.h"
23073 +
23074 +#include "fm_common.h"
23075 +
23076 +
23077 +#define __ERR_MODULE__ MODULE_FM_MACSEC
23078 +
23079 +
23080 +typedef struct
23081 +{
23082 + t_Error (*f_FM_MACSEC_Init) (t_Handle h_FmMacsec);
23083 + t_Error (*f_FM_MACSEC_Free) (t_Handle h_FmMacsec);
23084 +
23085 + t_Error (*f_FM_MACSEC_ConfigUnknownSciFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
23086 + t_Error (*f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23087 + t_Error (*f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) (t_Handle h_FmMacsec, bool discardUncontrolled);
23088 + t_Error (*f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23089 + t_Error (*f_FM_MACSEC_ConfigUntagFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
23090 + t_Error (*f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23091 + t_Error (*f_FM_MACSEC_ConfigPnExhaustionThreshold) (t_Handle h_FmMacsec, uint32_t pnExhThr);
23092 + t_Error (*f_FM_MACSEC_ConfigKeysUnreadable) (t_Handle h_FmMacsec);
23093 + t_Error (*f_FM_MACSEC_ConfigSectagWithoutSCI) (t_Handle h_FmMacsec);
23094 + t_Error (*f_FM_MACSEC_ConfigException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
23095 +
23096 + t_Error (*f_FM_MACSEC_GetRevision) (t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
23097 + t_Error (*f_FM_MACSEC_Enable) (t_Handle h_FmMacsec);
23098 + t_Error (*f_FM_MACSEC_Disable) (t_Handle h_FmMacsec);
23099 + t_Error (*f_FM_MACSEC_SetException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
23100 +
23101 +} t_FmMacsecControllerDriver;
23102 +
23103 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam);
23104 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParams);
23105 +
23106 +/***********************************************************************/
23107 +/* MACSEC internal routines */
23108 +/***********************************************************************/
23109 +
23110 +/**************************************************************************//**
23111 +
23112 + @Group FM_MACSEC_InterModule_grp FM MACSEC Inter-Module Unit
23113 +
23114 + @Description FM MACSEC Inter Module functions -
23115 + These are not User API routines but routines that may be called
23116 + from other modules. This will be the case in a single core environment,
23117 + where instead of using the XX messaging mechanism, the routines may be
23118 + called from other modules. In a multicore environment, the other modules may
23119 + be run by other cores and therefore these routines may not be called directly.
23120 +
23121 + @{
23122 +*//***************************************************************************/
23123 +
23124 +#define MAX_NUM_OF_SA_PER_SC 4
23125 +
23126 +typedef enum
23127 +{
23128 + e_SC_RX = 0,
23129 + e_SC_TX
23130 +} e_ScType;
23131 +
23132 +typedef enum
23133 +{
23134 + e_SC_SA_A = 0,
23135 + e_SC_SA_B ,
23136 + e_SC_SA_C ,
23137 + e_SC_SA_D
23138 +} e_ScSaId;
23139 +
23140 +typedef struct
23141 +{
23142 + uint32_t scId;
23143 + macsecSCI_t sci;
23144 + bool replayProtect;
23145 + uint32_t replayWindow;
23146 + e_FmMacsecValidFrameBehavior validateFrames;
23147 + uint16_t confidentialityOffset;
23148 + e_FmMacsecSecYCipherSuite cipherSuite;
23149 +} t_RxScParams;
23150 +
23151 +typedef struct
23152 +{
23153 + uint32_t scId;
23154 + macsecSCI_t sci;
23155 + bool protectFrames;
23156 + e_FmMacsecSciInsertionMode sciInsertionMode;
23157 + bool confidentialityEnable;
23158 + uint16_t confidentialityOffset;
23159 + e_FmMacsecSecYCipherSuite cipherSuite;
23160 +} t_TxScParams;
23161 +
23162 +typedef enum e_FmMacsecGlobalExceptions {
23163 + e_FM_MACSEC_EX_TX_SC, /**< Tx Sc 0 frame discarded error. */
23164 + e_FM_MACSEC_EX_ECC /**< MACSEC memory ECC multiple-bit error. */
23165 +} e_FmMacsecGlobalExceptions;
23166 +
23167 +typedef enum e_FmMacsecGlobalEvents {
23168 + e_FM_MACSEC_EV_TX_SC_NEXT_PN /**< Tx Sc 0 Next Pn exhaustion threshold reached. */
23169 +} e_FmMacsecGlobalEvents;
23170 +
23171 +/**************************************************************************//**
23172 + @Description Enum for inter-module interrupts registration
23173 +*//***************************************************************************/
23174 +typedef enum e_FmMacsecEventModules{
23175 + e_FM_MACSEC_MOD_SC_TX,
23176 + e_FM_MACSEC_MOD_DUMMY_LAST
23177 +} e_FmMacsecEventModules;
23178 +
23179 +typedef enum e_FmMacsecInterModuleEvent {
23180 + e_FM_MACSEC_EV_SC_TX,
23181 + e_FM_MACSEC_EV_ERR_SC_TX,
23182 + e_FM_MACSEC_EV_DUMMY_LAST
23183 +} e_FmMacsecInterModuleEvent;
23184 +
23185 +#define NUM_OF_INTER_MODULE_EVENTS (NUM_OF_TX_SC * 2)
23186 +
23187 +#define GET_MACSEC_MODULE_EVENT(mod, id, intrType, event) \
23188 + switch(mod){ \
23189 + case e_FM_MACSEC_MOD_SC_TX: \
23190 + event = (intrType == e_FM_INTR_TYPE_ERR) ? \
23191 + e_FM_MACSEC_EV_ERR_SC_TX: \
23192 + e_FM_MACSEC_EV_SC_TX; \
23193 + event += (uint8_t)(2 * id);break; \
23194 + break; \
23195 + default:event = e_FM_MACSEC_EV_DUMMY_LAST; \
23196 + break;}
23197 +
23198 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23199 + e_FmMacsecEventModules module,
23200 + uint8_t modId,
23201 + e_FmIntrType intrType,
23202 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23203 + t_Handle h_Arg);
23204 +
23205 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23206 + e_FmMacsecEventModules module,
23207 + uint8_t modId,
23208 + e_FmIntrType intrType);
23209 +
23210 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds);
23211 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds);
23212 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams);
23213 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId);
23214 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_RxScParams);
23215 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId);
23216 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
23217 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key);
23218 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23219 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23220 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive);
23221 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN);
23222 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN);
23223 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an);
23224 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An);
23225 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable);
23226 +
23227 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable);
23228 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable);
23229 +
23230 +
23231 +
23232 +#endif /* __FM_MACSEC_H */
23233 --- /dev/null
23234 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
23235 @@ -0,0 +1,59 @@
23236 +/*
23237 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23238 + *
23239 + * Redistribution and use in source and binary forms, with or without
23240 + * modification, are permitted provided that the following conditions are met:
23241 + * * Redistributions of source code must retain the above copyright
23242 + * notice, this list of conditions and the following disclaimer.
23243 + * * Redistributions in binary form must reproduce the above copyright
23244 + * notice, this list of conditions and the following disclaimer in the
23245 + * documentation and/or other materials provided with the distribution.
23246 + * * Neither the name of Freescale Semiconductor nor the
23247 + * names of its contributors may be used to endorse or promote products
23248 + * derived from this software without specific prior written permission.
23249 + *
23250 + *
23251 + * ALTERNATIVELY, this software may be distributed under the terms of the
23252 + * GNU General Public License ("GPL") as published by the Free Software
23253 + * Foundation, either version 2 of that License or (at your option) any
23254 + * later version.
23255 + *
23256 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23257 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23258 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23259 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23260 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23261 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23262 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23263 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23264 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23265 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23266 + */
23267 +
23268 +/******************************************************************************
23269 + @File fm_macsec.c
23270 +
23271 + @Description FM MACSEC driver routines implementation.
23272 +*//***************************************************************************/
23273 +
23274 +#include "std_ext.h"
23275 +#include "error_ext.h"
23276 +#include "xx_ext.h"
23277 +#include "string_ext.h"
23278 +#include "sprint_ext.h"
23279 +#include "debug_ext.h"
23280 +#include "fm_macsec.h"
23281 +
23282 +
23283 +/****************************************/
23284 +/* static functions */
23285 +/****************************************/
23286 +
23287 +/****************************************/
23288 +/* API Init unit functions */
23289 +/****************************************/
23290 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam)
23291 +{
23292 + UNUSED(p_FmMacsecParam);
23293 + return NULL;
23294 +}
23295 --- /dev/null
23296 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
23297 @@ -0,0 +1,1031 @@
23298 +/*
23299 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23300 + *
23301 + * Redistribution and use in source and binary forms, with or without
23302 + * modification, are permitted provided that the following conditions are met:
23303 + * * Redistributions of source code must retain the above copyright
23304 + * notice, this list of conditions and the following disclaimer.
23305 + * * Redistributions in binary form must reproduce the above copyright
23306 + * notice, this list of conditions and the following disclaimer in the
23307 + * documentation and/or other materials provided with the distribution.
23308 + * * Neither the name of Freescale Semiconductor nor the
23309 + * names of its contributors may be used to endorse or promote products
23310 + * derived from this software without specific prior written permission.
23311 + *
23312 + *
23313 + * ALTERNATIVELY, this software may be distributed under the terms of the
23314 + * GNU General Public License ("GPL") as published by the Free Software
23315 + * Foundation, either version 2 of that License or (at your option) any
23316 + * later version.
23317 + *
23318 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23319 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23320 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23321 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23322 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23323 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23324 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23325 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23326 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23327 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23328 + */
23329 +
23330 +/******************************************************************************
23331 + @File fm_macsec.c
23332 +
23333 + @Description FM MACSEC driver routines implementation.
23334 +*//***************************************************************************/
23335 +
23336 +#include "std_ext.h"
23337 +#include "error_ext.h"
23338 +#include "xx_ext.h"
23339 +#include "string_ext.h"
23340 +#include "sprint_ext.h"
23341 +#include "fm_mac_ext.h"
23342 +
23343 +#include "fm_macsec_master.h"
23344 +
23345 +
23346 +extern uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
23347 +
23348 +
23349 +/****************************************/
23350 +/* static functions */
23351 +/****************************************/
23352 +static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec)
23353 +{
23354 + if (!p_FmMacsec->f_Exception)
23355 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
23356 +
23357 + return E_OK;
23358 +}
23359 +
23360 +static void UnimplementedIsr(t_Handle h_Arg, uint32_t id)
23361 +{
23362 + UNUSED(h_Arg); UNUSED(id);
23363 +
23364 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
23365 +}
23366 +
23367 +static void MacsecEventIsr(t_Handle h_FmMacsec)
23368 +{
23369 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23370 + uint32_t events,event,i;
23371 +
23372 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23373 +
23374 + events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr);
23375 + events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever);
23376 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events);
23377 +
23378 + for (i=0; i<NUM_OF_TX_SC; i++)
23379 + if (events & FM_MACSEC_EV_TX_SC_NEXT_PN(i))
23380 + {
23381 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_NORMAL, event);
23382 + p_FmMacsec->intrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i);
23383 + }
23384 +}
23385 +
23386 +static void MacsecErrorIsr(t_Handle h_FmMacsec)
23387 +{
23388 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23389 + uint32_t errors,error,i;
23390 +
23391 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23392 +
23393 + errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err);
23394 + errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer);
23395 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors);
23396 +
23397 + for (i=0; i<NUM_OF_TX_SC; i++)
23398 + if (errors & FM_MACSEC_EX_TX_SC(i))
23399 + {
23400 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_ERR, error);
23401 + p_FmMacsec->intrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i);
23402 + }
23403 +
23404 + if (errors & FM_MACSEC_EX_ECC)
23405 + {
23406 + uint8_t eccType;
23407 + uint32_t tmpReg;
23408 +
23409 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec);
23410 + ASSERT_COND(tmpReg & MECC_CAP);
23411 + eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT);
23412 +
23413 + if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC))
23414 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC);
23415 + else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC))
23416 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC);
23417 + else
23418 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg);
23419 + }
23420 +}
23421 +
23422 +static t_Error MacsecInit(t_Handle h_FmMacsec)
23423 +{
23424 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23425 + t_FmMacsecDriverParam *p_FmMacsecDriverParam = NULL;
23426 + uint32_t tmpReg,i,macId;
23427 +
23428 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23429 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23430 +
23431 + CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters);
23432 +
23433 + p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam;
23434 +
23435 + for (i=0;i<e_FM_MACSEC_EV_DUMMY_LAST;i++)
23436 + p_FmMacsec->intrMng[i].f_Isr = UnimplementedIsr;
23437 +
23438 + tmpReg = 0;
23439 + tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)|
23440 + (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT) |
23441 + (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT) |
23442 + (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT) |
23443 + (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) |
23444 + (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT) |
23445 + (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT) |
23446 + (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT) |
23447 + (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT);
23448 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
23449 +
23450 + tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac);
23451 + /* At least Ethernet FCS (4 bytes) overhead must be subtracted from MFL.
23452 + * In addition, the SCI (8 bytes) overhead might be subtracted as well. */
23453 + tmpReg -= p_FmMacsecDriverParam->mflSubtract;
23454 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg);
23455 +
23456 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr);
23457 +
23458 + if (!p_FmMacsec->userExceptions)
23459 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23460 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23461 +
23462 + p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC;
23463 + if (p_FmMacsecDriverParam->reservedSc0)
23464 + p_FmMacsec->numRxScAvailable --;
23465 + p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC;
23466 +
23467 + XX_Free(p_FmMacsecDriverParam);
23468 + p_FmMacsec->p_FmMacsecDriverParam = NULL;
23469 +
23470 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23471 + FmRegisterIntr(p_FmMacsec->h_Fm,
23472 + e_FM_MOD_MACSEC,
23473 + (uint8_t)macId,
23474 + e_FM_INTR_TYPE_NORMAL,
23475 + MacsecEventIsr,
23476 + p_FmMacsec);
23477 +
23478 + FmRegisterIntr(p_FmMacsec->h_Fm,
23479 + e_FM_MOD_MACSEC,
23480 + 0,
23481 + e_FM_INTR_TYPE_ERR,
23482 + MacsecErrorIsr,
23483 + p_FmMacsec);
23484 +
23485 + return E_OK;
23486 +}
23487 +
23488 +static t_Error MacsecFree(t_Handle h_FmMacsec)
23489 +{
23490 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23491 + uint32_t macId;
23492 +
23493 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23494 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23495 +
23496 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23497 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23498 + e_FM_MOD_MACSEC,
23499 + (uint8_t)macId,
23500 + e_FM_INTR_TYPE_NORMAL);
23501 +
23502 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23503 + e_FM_MOD_MACSEC,
23504 + 0,
23505 + e_FM_INTR_TYPE_ERR);
23506 +
23507 + if (p_FmMacsec->rxScSpinLock)
23508 + XX_FreeSpinlock(p_FmMacsec->rxScSpinLock);
23509 + if (p_FmMacsec->txScSpinLock)
23510 + XX_FreeSpinlock(p_FmMacsec->txScSpinLock);
23511 +
23512 + XX_Free(p_FmMacsec);
23513 +
23514 + return E_OK;
23515 +}
23516 +
23517 +static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
23518 +{
23519 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23520 +
23521 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23522 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23523 +
23524 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode;
23525 +
23526 + return E_OK;
23527 +}
23528 +
23529 +static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23530 +{
23531 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23532 +
23533 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23534 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23535 +
23536 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled;
23537 +
23538 + return E_OK;
23539 +}
23540 +
23541 +static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23542 +{
23543 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23544 +
23545 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23546 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23547 +
23548 + p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled;
23549 +
23550 + return E_OK;
23551 +}
23552 +
23553 +static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23554 +{
23555 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23556 +
23557 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23558 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23559 +
23560 + p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled;
23561 +
23562 + return E_OK;
23563 +}
23564 +
23565 +static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
23566 +{
23567 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23568 +
23569 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23570 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23571 +
23572 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled;
23573 +
23574 + return E_OK;
23575 +}
23576 +
23577 +static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
23578 +{
23579 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23580 +
23581 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23582 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23583 +
23584 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode;
23585 +
23586 + return E_OK;
23587 +}
23588 +
23589 +static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
23590 +{
23591 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23592 +
23593 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23594 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23595 +
23596 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr;
23597 +
23598 + return E_OK;
23599 +}
23600 +
23601 +static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec)
23602 +{
23603 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23604 +
23605 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23606 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23607 +
23608 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE;
23609 +
23610 + return E_OK;
23611 +}
23612 +
23613 +static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec)
23614 +{
23615 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23616 +
23617 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23618 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23619 +
23620 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE;
23621 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract += MACSEC_SCI_SIZE;
23622 +
23623 + return E_OK;
23624 +}
23625 +
23626 +static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23627 +{
23628 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23629 + uint32_t bitMask = 0;
23630 +
23631 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23632 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23633 +
23634 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23635 + if (bitMask)
23636 + {
23637 + if (enable)
23638 + p_FmMacsec->userExceptions |= bitMask;
23639 + else
23640 + p_FmMacsec->userExceptions &= ~bitMask;
23641 + }
23642 + else
23643 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23644 +
23645 + return E_OK;
23646 +}
23647 +
23648 +static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
23649 +{
23650 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23651 +
23652 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23653 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23654 +
23655 + *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1);
23656 +
23657 + return E_OK;
23658 +}
23659 +
23660 +static t_Error MacsecEnable(t_Handle h_FmMacsec)
23661 +{
23662 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23663 + uint32_t tmpReg;
23664 +
23665 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23666 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23667 +
23668 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23669 + tmpReg |= CFG_BYPN;
23670 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23671 +
23672 + return E_OK;
23673 +}
23674 +
23675 +static t_Error MacsecDisable(t_Handle h_FmMacsec)
23676 +{
23677 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23678 + uint32_t tmpReg;
23679 +
23680 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23681 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23682 +
23683 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23684 + tmpReg &= ~CFG_BYPN;
23685 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23686 +
23687 + return E_OK;
23688 +}
23689 +
23690 +static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23691 +{
23692 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23693 + uint32_t bitMask;
23694 +
23695 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23696 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23697 +
23698 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23699 + if (bitMask)
23700 + {
23701 + if (enable)
23702 + p_FmMacsec->userExceptions |= bitMask;
23703 + else
23704 + p_FmMacsec->userExceptions &= ~bitMask;
23705 + }
23706 + else
23707 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23708 +
23709 + if (!p_FmMacsec->userExceptions)
23710 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23711 + else
23712 + p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC;
23713 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23714 +
23715 + return E_OK;
23716 +}
23717 +
23718 +static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver)
23719 +{
23720 + p_FmMacsecControllerDriver->f_FM_MACSEC_Init = MacsecInit;
23721 + p_FmMacsecControllerDriver->f_FM_MACSEC_Free = MacsecFree;
23722 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment = MacsecConfigUnknownSciFrameTreatment;
23723 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment = MacsecConfigInvalidTagsFrameTreatment;
23724 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment = MacsecConfigEncryptWithNoChangedTextFrameTreatment;
23725 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment = MacsecConfigUntagFrameTreatment;
23726 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment = MacsecConfigChangedTextWithNoEncryptFrameTreatment;
23727 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment = MacsecConfigOnlyScbIsSetFrameTreatment;
23728 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold = MacsecConfigPnExhaustionThreshold;
23729 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable = MacsecConfigKeysUnreadable;
23730 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI = MacsecConfigSectagWithoutSCI;
23731 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException = MacsecConfigException;
23732 + p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision = MacsecGetRevision;
23733 + p_FmMacsecControllerDriver->f_FM_MACSEC_Enable = MacsecEnable;
23734 + p_FmMacsecControllerDriver->f_FM_MACSEC_Disable = MacsecDisable;
23735 + p_FmMacsecControllerDriver->f_FM_MACSEC_SetException = MacsecSetException;
23736 +}
23737 +
23738 +/****************************************/
23739 +/* Inter-Module functions */
23740 +/****************************************/
23741 +
23742 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23743 + e_FmMacsecEventModules module,
23744 + uint8_t modId,
23745 + e_FmIntrType intrType,
23746 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23747 + t_Handle h_Arg)
23748 +{
23749 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23750 + uint8_t event= 0;
23751 +
23752 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23753 +
23754 + GET_MACSEC_MODULE_EVENT(module, modId, intrType, event);
23755 +
23756 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
23757 + p_FmMacsec->intrMng[event].f_Isr = f_Isr;
23758 + p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg;
23759 +}
23760 +
23761 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23762 + e_FmMacsecEventModules module,
23763 + uint8_t modId,
23764 + e_FmIntrType intrType)
23765 +{
23766 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23767 + uint8_t event= 0;
23768 +
23769 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23770 +
23771 + GET_MACSEC_MODULE_EVENT(module, modId,intrType, event);
23772 +
23773 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
23774 + p_FmMacsec->intrMng[event].f_Isr = NULL;
23775 + p_FmMacsec->intrMng[event].h_SrcHandle = NULL;
23776 +}
23777 +
23778 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds)
23779 +{
23780 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23781 + t_Error err = E_OK;
23782 + bool *p_ScTable;
23783 + uint32_t *p_ScAvailable,i;
23784 +
23785 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23786 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
23787 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
23788 +
23789 + if (type == e_SC_RX)
23790 + {
23791 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
23792 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
23793 + i = (NUM_OF_RX_SC - 1);
23794 + }
23795 + else
23796 + {
23797 + p_ScTable = (bool *)p_FmMacsec->txScTable;
23798 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
23799 + i = (NUM_OF_TX_SC - 1);
23800 +
23801 + }
23802 + if (*p_ScAvailable < numOfScs)
23803 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available"));
23804 +
23805 + if (isPtp)
23806 + {
23807 + i = 0;
23808 + if (p_ScTable[i])
23809 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available"));
23810 + }
23811 +
23812 + for (;numOfScs;i--)
23813 + {
23814 + if (p_ScTable[i])
23815 + continue;
23816 + numOfScs --;
23817 + (*p_ScAvailable)--;
23818 + p_ScIds[numOfScs] = i;
23819 + p_ScTable[i] = TRUE;
23820 + }
23821 +
23822 + return err;
23823 +}
23824 +
23825 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds)
23826 +{
23827 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23828 + t_Error err = E_OK;
23829 + bool *p_ScTable;
23830 + uint32_t *p_ScAvailable,maxNumOfSc,i;
23831 +
23832 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23833 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
23834 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
23835 +
23836 + if (type == e_SC_RX)
23837 + {
23838 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
23839 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
23840 + maxNumOfSc = NUM_OF_RX_SC;
23841 + }
23842 + else
23843 + {
23844 + p_ScTable = (bool *)p_FmMacsec->txScTable;
23845 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
23846 + maxNumOfSc = NUM_OF_TX_SC;
23847 + }
23848 +
23849 + if ((*p_ScAvailable + numOfScs) > maxNumOfSc)
23850 + RETURN_ERROR(MINOR, E_FULL, ("Too much SCs"));
23851 +
23852 + for (i=0;i<numOfScs;i++)
23853 + {
23854 + p_ScTable[p_ScIds[i]] = FALSE;
23855 + (*p_ScAvailable)++;
23856 + }
23857 +
23858 + return err;
23859 +
23860 +}
23861 +
23862 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable)
23863 +{
23864 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23865 + uint32_t tmpReg = 0;
23866 +
23867 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23868 +
23869 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23870 + if (enable && (tmpReg & CFG_S0I))
23871 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode"));
23872 +
23873 + if (enable)
23874 + tmpReg |= CFG_S0I;
23875 + else
23876 + tmpReg &= ~CFG_S0I;
23877 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
23878 +
23879 + return E_OK;
23880 +}
23881 +
23882 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams)
23883 +{
23884 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23885 + t_Error err = E_OK;
23886 + uint32_t tmpReg = 0, intFlags;
23887 +
23888 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23889 + SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE);
23890 + SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23891 +
23892 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
23893 +
23894 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId);
23895 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg);
23896 + if (tmpReg & RX_SCCFG_SCI_EN_MASK)
23897 + {
23898 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23899 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId));
23900 + }
23901 +
23902 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci));
23903 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci));
23904 + tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK);
23905 + tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK);
23906 + tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK);
23907 + tmpReg |= RX_SCCFG_SCI_EN_MASK;
23908 + tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT);
23909 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
23910 +
23911 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow);
23912 +
23913 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23914 +
23915 + return err;
23916 +}
23917 +
23918 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId)
23919 +{
23920 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23921 + t_Error err = E_OK;
23922 + uint32_t tmpReg = 0, intFlags;
23923 +
23924 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23925 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23926 +
23927 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
23928 +
23929 + tmpReg &= ~RX_SCCFG_SCI_EN_MASK;
23930 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
23931 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
23932 +
23933 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23934 +
23935 + return err;
23936 +}
23937 +
23938 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams)
23939 +{
23940 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23941 + t_Error err = E_OK;
23942 + uint32_t tmpReg = 0, intFlags;
23943 + bool alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE;
23944 +
23945 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23946 + SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE);
23947 + SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
23948 +
23949 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
23950 +
23951 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId);
23952 +
23953 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
23954 + if (tmpReg & TX_SCCFG_SCE_MASK)
23955 + {
23956 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
23957 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId));
23958 + }
23959 +
23960 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci));
23961 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci));
23962 + alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG);
23963 + useES = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA);
23964 +
23965 + tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK);
23966 + tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK);
23967 + tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK);
23968 + tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK);
23969 + tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK);
23970 + tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK);
23971 + tmpReg |= TX_SCCFG_SCE_MASK;
23972 + tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT);
23973 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
23974 +
23975 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
23976 +
23977 + return err;
23978 +}
23979 +
23980 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId)
23981 +{
23982 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23983 + t_Error err = E_OK;
23984 + uint32_t tmpReg = 0, intFlags;
23985 +
23986 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23987 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
23988 +
23989 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
23990 +
23991 + tmpReg &= ~TX_SCCFG_SCE_MASK;
23992 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
23993 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
23994 +
23995 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
23996 +
23997 + return err;
23998 +}
23999 +
24000 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
24001 +{
24002 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24003 + t_Error err = E_OK;
24004 + uint32_t tmpReg = 0, intFlags;
24005 +
24006 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24007 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24008 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24009 +
24010 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24011 +
24012 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24013 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn);
24014 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn);
24015 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t));
24016 +
24017 + tmpReg |= RX_SACFG_ACTIVE;
24018 + tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK);
24019 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24020 +
24021 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24022 +
24023 + return err;
24024 +}
24025 +
24026 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key)
24027 +{
24028 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24029 + t_Error err = E_OK;
24030 + uint32_t tmpReg = 0, intFlags;
24031 +
24032 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24033 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24034 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24035 +
24036 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24037 +
24038 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24039 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn);
24040 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t));
24041 +
24042 + tmpReg |= TX_SACFG_ACTIVE;
24043 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
24044 +
24045 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24046 +
24047 + return err;
24048 +}
24049 +
24050 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
24051 +{
24052 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24053 + t_Error err = E_OK;
24054 + uint32_t tmpReg = 0, i, intFlags;
24055 +
24056 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24057 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24058 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24059 +
24060 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24061 +
24062 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24063 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0);
24064 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0);
24065 + for (i=0; i<4; i++)
24066 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0);
24067 +
24068 + tmpReg |= RX_SACFG_ACTIVE;
24069 + tmpReg &= ~RX_SACFG_EN_MASK;
24070 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24071 +
24072 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24073 +
24074 + return err;
24075 +}
24076 +
24077 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
24078 +{
24079 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24080 + t_Error err = E_OK;
24081 + uint32_t tmpReg = 0, i, intFlags;
24082 +
24083 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24084 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24085 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24086 +
24087 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24088 +
24089 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24090 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0);
24091 + for (i=0; i<4; i++)
24092 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0);
24093 +
24094 + tmpReg |= TX_SACFG_ACTIVE;
24095 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
24096 +
24097 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24098 +
24099 + return err;
24100 +}
24101 +
24102 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive)
24103 +{
24104 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24105 + t_Error err = E_OK;
24106 + uint32_t tmpReg = 0, intFlags;
24107 +
24108 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24109 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24110 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24111 +
24112 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24113 +
24114 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24115 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs);
24116 + if (enableReceive)
24117 + tmpReg |= RX_SACFG_EN_MASK;
24118 + else
24119 + tmpReg &= ~RX_SACFG_EN_MASK;
24120 +
24121 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24122 +
24123 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24124 +
24125 + return err;
24126 +}
24127 +
24128 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN)
24129 +{
24130 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24131 + t_Error err = E_OK;
24132 + uint32_t intFlags;
24133 +
24134 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24135 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24136 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24137 +
24138 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24139 +
24140 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24141 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN);
24142 +
24143 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24144 +
24145 + return err;
24146 +}
24147 +
24148 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN)
24149 +{
24150 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24151 + t_Error err = E_OK;
24152 + uint32_t intFlags;
24153 +
24154 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24155 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24156 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24157 +
24158 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24159 +
24160 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24161 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN);
24162 +
24163 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24164 +
24165 + return err;
24166 +}
24167 +
24168 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an)
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_TX_SC, E_INVALID_HANDLE);
24177 +
24178 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24179 +
24180 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24181 +
24182 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24183 +
24184 + tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK);
24185 + tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK);
24186 +
24187 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24188 +
24189 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24190 +
24191 + return err;
24192 +}
24193 +
24194 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An)
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(p_An, E_INVALID_HANDLE);
24203 +
24204 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24205 +
24206 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24207 +
24208 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24209 +
24210 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24211 +
24212 + *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT);
24213 +
24214 + return err;
24215 +}
24216 +
24217 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable)
24218 +{
24219 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24220 + uint32_t bitMask;
24221 +
24222 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24223 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24224 +
24225 + GET_EXCEPTION_FLAG(bitMask, exception, scId);
24226 + if (bitMask)
24227 + {
24228 + if (enable)
24229 + p_FmMacsec->exceptions |= bitMask;
24230 + else
24231 + p_FmMacsec->exceptions &= ~bitMask;
24232 + }
24233 + else
24234 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
24235 +
24236 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
24237 +
24238 + return E_OK;
24239 +}
24240 +
24241 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable)
24242 +{
24243 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24244 + uint32_t bitMask;
24245 +
24246 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24247 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24248 +
24249 + GET_EVENT_FLAG(bitMask, event, scId);
24250 + if (bitMask)
24251 + {
24252 + if (enable)
24253 + p_FmMacsec->events |= bitMask;
24254 + else
24255 + p_FmMacsec->events &= ~bitMask;
24256 + }
24257 + else
24258 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
24259 +
24260 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events);
24261 +
24262 + return E_OK;
24263 +}
24264 +
24265 +/****************************************/
24266 +/* API Init unit functions */
24267 +/****************************************/
24268 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam)
24269 +{
24270 + t_FmMacsec *p_FmMacsec;
24271 + uint32_t macId;
24272 +
24273 + /* Allocate FM MACSEC structure */
24274 + p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec));
24275 + if (!p_FmMacsec)
24276 + {
24277 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure"));
24278 + return NULL;
24279 + }
24280 + memset(p_FmMacsec, 0, sizeof(t_FmMacsec));
24281 + InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver);
24282 +
24283 + /* Allocate the FM MACSEC driver's parameters structure */
24284 + p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam));
24285 + if (!p_FmMacsec->p_FmMacsecDriverParam)
24286 + {
24287 + XX_Free(p_FmMacsec);
24288 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters"));
24289 + return NULL;
24290 + }
24291 + memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam));
24292 +
24293 + /* Initialize FM MACSEC parameters which will be kept by the driver */
24294 + p_FmMacsec->h_Fm = p_FmMacsecParam->h_Fm;
24295 + p_FmMacsec->h_FmMac = p_FmMacsecParam->nonGuestParams.h_FmMac;
24296 + p_FmMacsec->p_FmMacsecRegs = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr);
24297 + p_FmMacsec->f_Exception = p_FmMacsecParam->nonGuestParams.f_Exception;
24298 + p_FmMacsec->h_App = p_FmMacsecParam->nonGuestParams.h_App;
24299 + p_FmMacsec->userExceptions = DEFAULT_userExceptions;
24300 + p_FmMacsec->exceptions = DEFAULT_exceptions;
24301 + p_FmMacsec->events = DEFAULT_events;
24302 + p_FmMacsec->rxScSpinLock = XX_InitSpinlock();
24303 + p_FmMacsec->txScSpinLock = XX_InitSpinlock();
24304 +
24305 + /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */
24306 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = DEFAULT_unknownSciFrameTreatment;
24307 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = DEFAULT_invalidTagsFrameTreatment;
24308 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = DEFAULT_encryptWithNoChangedTextFrameTreatment;
24309 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = DEFAULT_untagFrameTreatment;
24310 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = DEFAULT_keysUnreadable;
24311 + p_FmMacsec->p_FmMacsecDriverParam->reservedSc0 = DEFAULT_sc0ReservedForPTP;
24312 + p_FmMacsec->p_FmMacsecDriverParam->byPassMode = !DEFAULT_normalMode;
24313 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = DEFAULT_pnExhThr;
24314 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead = DEFAULT_sectagOverhead;
24315 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract = DEFAULT_mflSubtract;
24316 + /* build the FM MACSEC master IPC address */
24317 + memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE);
24318 + FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId);
24319 + if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master",
24320 + FmGetId(p_FmMacsec->h_Fm),macId) != 24)
24321 + {
24322 + XX_Free(p_FmMacsec->p_FmMacsecDriverParam);
24323 + XX_Free(p_FmMacsec);
24324 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
24325 + return NULL;
24326 + }
24327 + return p_FmMacsec;
24328 +}
24329 --- /dev/null
24330 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
24331 @@ -0,0 +1,479 @@
24332 +/*
24333 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24334 + *
24335 + * Redistribution and use in source and binary forms, with or without
24336 + * modification, are permitted provided that the following conditions are met:
24337 + * * Redistributions of source code must retain the above copyright
24338 + * notice, this list of conditions and the following disclaimer.
24339 + * * Redistributions in binary form must reproduce the above copyright
24340 + * notice, this list of conditions and the following disclaimer in the
24341 + * documentation and/or other materials provided with the distribution.
24342 + * * Neither the name of Freescale Semiconductor nor the
24343 + * names of its contributors may be used to endorse or promote products
24344 + * derived from this software without specific prior written permission.
24345 + *
24346 + *
24347 + * ALTERNATIVELY, this software may be distributed under the terms of the
24348 + * GNU General Public License ("GPL") as published by the Free Software
24349 + * Foundation, either version 2 of that License or (at your option) any
24350 + * later version.
24351 + *
24352 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24353 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24354 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24355 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24356 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24357 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24358 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24359 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24360 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24361 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24362 + */
24363 +
24364 +/******************************************************************************
24365 + @File fm_macsec_master.h
24366 +
24367 + @Description FM MACSEC internal structures and definitions.
24368 +*//***************************************************************************/
24369 +#ifndef __FM_MACSEC_MASTER_H
24370 +#define __FM_MACSEC_MASTER_H
24371 +
24372 +#include "error_ext.h"
24373 +#include "std_ext.h"
24374 +
24375 +#include "fm_macsec.h"
24376 +
24377 +
24378 +#define MACSEC_ICV_SIZE 16
24379 +#define MACSEC_SECTAG_SIZE 16
24380 +#define MACSEC_SCI_SIZE 8
24381 +#define MACSEC_FCS_SIZE 4
24382 +
24383 +/**************************************************************************//**
24384 + @Description Exceptions
24385 +*//***************************************************************************/
24386 +
24387 +#define FM_MACSEC_EX_TX_SC_0 0x80000000
24388 +#define FM_MACSEC_EX_TX_SC(sc) (FM_MACSEC_EX_TX_SC_0 >> (sc))
24389 +#define FM_MACSEC_EX_ECC 0x00000001
24390 +
24391 +#define GET_EXCEPTION_FLAG(bitMask, exception, id) switch (exception){ \
24392 + case e_FM_MACSEC_EX_TX_SC: \
24393 + bitMask = FM_MACSEC_EX_TX_SC(id); break; \
24394 + case e_FM_MACSEC_EX_ECC: \
24395 + bitMask = FM_MACSEC_EX_ECC; break; \
24396 + default: bitMask = 0;break;}
24397 +
24398 +#define FM_MACSEC_USER_EX_SINGLE_BIT_ECC 0x80000000
24399 +#define FM_MACSEC_USER_EX_MULTI_BIT_ECC 0x40000000
24400 +
24401 +#define GET_USER_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
24402 + case e_FM_MACSEC_EX_SINGLE_BIT_ECC: \
24403 + bitMask = FM_MACSEC_USER_EX_SINGLE_BIT_ECC; break; \
24404 + case e_FM_MACSEC_EX_MULTI_BIT_ECC: \
24405 + bitMask = FM_MACSEC_USER_EX_MULTI_BIT_ECC; break; \
24406 + default: bitMask = 0;break;}
24407 +
24408 +/**************************************************************************//**
24409 + @Description Events
24410 +*//***************************************************************************/
24411 +
24412 +#define FM_MACSEC_EV_TX_SC_0_NEXT_PN 0x80000000
24413 +#define FM_MACSEC_EV_TX_SC_NEXT_PN(sc) (FM_MACSEC_EV_TX_SC_0_NEXT_PN >> (sc))
24414 +
24415 +#define GET_EVENT_FLAG(bitMask, event, id) switch (event){ \
24416 + case e_FM_MACSEC_EV_TX_SC_NEXT_PN: \
24417 + bitMask = FM_MACSEC_EV_TX_SC_NEXT_PN(id); break; \
24418 + default: bitMask = 0;break;}
24419 +
24420 +/**************************************************************************//**
24421 + @Description Defaults
24422 +*//***************************************************************************/
24423 +#define DEFAULT_userExceptions (FM_MACSEC_USER_EX_SINGLE_BIT_ECC |\
24424 + FM_MACSEC_USER_EX_MULTI_BIT_ECC)
24425 +
24426 +#define DEFAULT_exceptions (FM_MACSEC_EX_TX_SC(0) |\
24427 + FM_MACSEC_EX_TX_SC(1) |\
24428 + FM_MACSEC_EX_TX_SC(2) |\
24429 + FM_MACSEC_EX_TX_SC(3) |\
24430 + FM_MACSEC_EX_TX_SC(4) |\
24431 + FM_MACSEC_EX_TX_SC(5) |\
24432 + FM_MACSEC_EX_TX_SC(6) |\
24433 + FM_MACSEC_EX_TX_SC(7) |\
24434 + FM_MACSEC_EX_TX_SC(8) |\
24435 + FM_MACSEC_EX_TX_SC(9) |\
24436 + FM_MACSEC_EX_TX_SC(10) |\
24437 + FM_MACSEC_EX_TX_SC(11) |\
24438 + FM_MACSEC_EX_TX_SC(12) |\
24439 + FM_MACSEC_EX_TX_SC(13) |\
24440 + FM_MACSEC_EX_TX_SC(14) |\
24441 + FM_MACSEC_EX_TX_SC(15) |\
24442 + FM_MACSEC_EX_ECC )
24443 +
24444 +#define DEFAULT_events (FM_MACSEC_EV_TX_SC_NEXT_PN(0) |\
24445 + FM_MACSEC_EV_TX_SC_NEXT_PN(1) |\
24446 + FM_MACSEC_EV_TX_SC_NEXT_PN(2) |\
24447 + FM_MACSEC_EV_TX_SC_NEXT_PN(3) |\
24448 + FM_MACSEC_EV_TX_SC_NEXT_PN(4) |\
24449 + FM_MACSEC_EV_TX_SC_NEXT_PN(5) |\
24450 + FM_MACSEC_EV_TX_SC_NEXT_PN(6) |\
24451 + FM_MACSEC_EV_TX_SC_NEXT_PN(7) |\
24452 + FM_MACSEC_EV_TX_SC_NEXT_PN(8) |\
24453 + FM_MACSEC_EV_TX_SC_NEXT_PN(9) |\
24454 + FM_MACSEC_EV_TX_SC_NEXT_PN(10) |\
24455 + FM_MACSEC_EV_TX_SC_NEXT_PN(11) |\
24456 + FM_MACSEC_EV_TX_SC_NEXT_PN(12) |\
24457 + FM_MACSEC_EV_TX_SC_NEXT_PN(13) |\
24458 + FM_MACSEC_EV_TX_SC_NEXT_PN(14) |\
24459 + FM_MACSEC_EV_TX_SC_NEXT_PN(15) )
24460 +
24461 +#define DEFAULT_unknownSciFrameTreatment e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH
24462 +#define DEFAULT_invalidTagsFrameTreatment FALSE
24463 +#define DEFAULT_encryptWithNoChangedTextFrameTreatment FALSE
24464 +#define DEFAULT_untagFrameTreatment e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED
24465 +#define DEFAULT_changedTextWithNoEncryptFrameTreatment FALSE
24466 +#define DEFAULT_onlyScbIsSetFrameTreatment FALSE
24467 +#define DEFAULT_keysUnreadable FALSE
24468 +#define DEFAULT_normalMode TRUE
24469 +#define DEFAULT_sc0ReservedForPTP FALSE
24470 +#define DEFAULT_initNextPn 1
24471 +#define DEFAULT_pnExhThr 0xffffffff
24472 +#define DEFAULT_sectagOverhead (MACSEC_ICV_SIZE + MACSEC_SECTAG_SIZE)
24473 +#define DEFAULT_mflSubtract MACSEC_FCS_SIZE
24474 +
24475 +
24476 +/**************************************************************************//**
24477 + @Description Memory Mapped Registers
24478 +*//***************************************************************************/
24479 +
24480 +#if defined(__MWERKS__) && !defined(__GNUC__)
24481 +#pragma pack(push,1)
24482 +#endif /* defined(__MWERKS__) && ... */
24483 +
24484 +typedef _Packed struct
24485 +{
24486 + /* MACsec configuration */
24487 + volatile uint32_t cfg; /**< MACsec configuration */
24488 + volatile uint32_t et; /**< MACsec EtherType */
24489 + volatile uint8_t res1[56]; /**< reserved */
24490 + volatile uint32_t mfl; /**< Maximum Frame Length */
24491 + volatile uint32_t tpnet; /**< TX Packet Number exhaustion threshold */
24492 + volatile uint8_t res2[56]; /**< reserved */
24493 + volatile uint32_t rxsca; /**< RX SC access select */
24494 + volatile uint8_t res3[60]; /**< reserved */
24495 + volatile uint32_t txsca; /**< TX SC access select */
24496 + volatile uint8_t res4[60]; /**< reserved */
24497 +
24498 + /* RX configuration, status and statistic */
24499 + volatile uint32_t rxsci1h; /**< RX Secure Channel Identifier first half */
24500 + volatile uint32_t rxsci2h; /**< RX Secure Channel Identifier second half */
24501 + volatile uint8_t res5[8]; /**< reserved */
24502 + volatile uint32_t ifio1hs; /**< ifInOctets first half Statistic */
24503 + volatile uint32_t ifio2hs; /**< ifInOctets second half Statistic */
24504 + volatile uint32_t ifiups; /**< ifInUcastPkts Statistic */
24505 + volatile uint8_t res6[4]; /**< reserved */
24506 + volatile uint32_t ifimps; /**< ifInMulticastPkts Statistic */
24507 + volatile uint32_t ifibps; /**< ifInBroadcastPkts Statistic */
24508 + volatile uint32_t rxsccfg; /**< RX Secure Channel configuration */
24509 + volatile uint32_t rpw; /**< replayWindow */
24510 + volatile uint8_t res7[16]; /**< reserved */
24511 + volatile uint32_t inov1hs; /**< InOctetsValidated first half Statistic */
24512 + volatile uint32_t inov2hs; /**< InOctetsValidated second half Statistic */
24513 + volatile uint32_t inod1hs; /**< InOctetsDecrypted first half Statistic */
24514 + volatile uint32_t inod2hs; /**< InOctetsDecrypted second half Statistic */
24515 + volatile uint32_t rxscipus; /**< RX Secure Channel InPktsUnchecked Statistic */
24516 + volatile uint32_t rxscipds; /**< RX Secure Channel InPktsDelayed Statistic */
24517 + volatile uint32_t rxscipls; /**< RX Secure Channel InPktsLate Statistic */
24518 + volatile uint8_t res8[4]; /**< reserved */
24519 + volatile uint32_t rxaninuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InNotUsingSA Statistic */
24520 + volatile uint32_t rxanipuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InPktsUnusedSA Statistic */
24521 + _Packed struct
24522 + {
24523 + volatile uint32_t rxsacs; /**< RX Security Association configuration and status */
24524 + volatile uint32_t rxsanpn; /**< RX Security Association nextPN */
24525 + volatile uint32_t rxsalpn; /**< RX Security Association lowestPN */
24526 + volatile uint32_t rxsaipos; /**< RX Security Association InPktsOK Statistic */
24527 + volatile uint32_t rxsak[4]; /**< RX Security Association key (128 bit) */
24528 + volatile uint32_t rxsah[4]; /**< RX Security Association hash (128 bit) */
24529 + volatile uint32_t rxsaipis; /**< RX Security Association InPktsInvalid Statistic */
24530 + volatile uint32_t rxsaipnvs; /**< RX Security Association InPktsNotValid Statistic */
24531 + volatile uint8_t res9[8]; /**< reserved */
24532 + } _PackedType fmMacsecRxScSa[NUM_OF_SA_PER_RX_SC];
24533 +
24534 + /* TX configuration, status and statistic */
24535 + volatile uint32_t txsci1h; /**< TX Secure Channel Identifier first half */
24536 + volatile uint32_t txsci2h; /**< TX Secure Channel Identifier second half */
24537 + volatile uint8_t res10[8]; /**< reserved */
24538 + volatile uint32_t ifoo1hs; /**< ifOutOctets first half Statistic */
24539 + volatile uint32_t ifoo2hs; /**< ifOutOctets second half Statistic */
24540 + volatile uint32_t ifoups; /**< ifOutUcastPkts Statistic */
24541 + volatile uint32_t opus; /**< OutPktsUntagged Statistic */
24542 + volatile uint32_t ifomps; /**< ifOutMulticastPkts Statistic */
24543 + volatile uint32_t ifobps; /**< ifOutBroadcastPkts Statistic */
24544 + volatile uint32_t txsccfg; /**< TX Secure Channel configuration */
24545 + volatile uint32_t optls; /**< OutPktsTooLong Statistic */
24546 + volatile uint8_t res11[16]; /**< reserved */
24547 + volatile uint32_t oop1hs; /**< OutOctetsProtected first half Statistic */
24548 + volatile uint32_t oop2hs; /**< OutOctetsProtected second half Statistic */
24549 + volatile uint32_t ooe1hs; /**< OutOctetsEncrypted first half Statistic */
24550 + volatile uint32_t ooe2hs; /**< OutOctetsEncrypted second half Statistic */
24551 + volatile uint8_t res12[48]; /**< reserved */
24552 + _Packed struct
24553 + {
24554 + volatile uint32_t txsacs; /**< TX Security Association configuration and status */
24555 + volatile uint32_t txsanpn; /**< TX Security Association nextPN */
24556 + volatile uint32_t txsaopps; /**< TX Security Association OutPktsProtected Statistic */
24557 + volatile uint32_t txsaopes; /**< TX Security Association OutPktsEncrypted Statistic */
24558 + volatile uint32_t txsak[4]; /**< TX Security Association key (128 bit) */
24559 + volatile uint32_t txsah[4]; /**< TX Security Association hash (128 bit) */
24560 + volatile uint8_t res13[16]; /**< reserved */
24561 + } _PackedType fmMacsecTxScSa[NUM_OF_SA_PER_TX_SC];
24562 + volatile uint8_t res14[248]; /**< reserved */
24563 +
24564 + /* Global configuration and status */
24565 + volatile uint32_t ip_rev1; /**< MACsec IP Block Revision 1 register */
24566 + volatile uint32_t ip_rev2; /**< MACsec IP Block Revision 2 register */
24567 + volatile uint32_t evr; /**< MACsec Event Register */
24568 + volatile uint32_t ever; /**< MACsec Event Enable Register */
24569 + volatile uint32_t evfr; /**< MACsec Event Force Register */
24570 + volatile uint32_t err; /**< MACsec Error Register */
24571 + volatile uint32_t erer; /**< MACsec Error Enable Register */
24572 + volatile uint32_t erfr; /**< MACsec Error Force Register */
24573 + volatile uint8_t res15[40]; /**< reserved */
24574 + volatile uint32_t meec; /**< MACsec Memory ECC Error Capture Register */
24575 + volatile uint32_t idle; /**< MACsec Idle status Register */
24576 + volatile uint8_t res16[184]; /**< reserved */
24577 + /* DEBUG */
24578 + volatile uint32_t rxec; /**< MACsec RX error capture Register */
24579 + volatile uint8_t res17[28]; /**< reserved */
24580 + volatile uint32_t txec; /**< MACsec TX error capture Register */
24581 + volatile uint8_t res18[220]; /**< reserved */
24582 +
24583 + /* Macsec Rx global statistic */
24584 + volatile uint32_t ifiocp1hs; /**< ifInOctetsCp first half Statistic */
24585 + volatile uint32_t ifiocp2hs; /**< ifInOctetsCp second half Statistic */
24586 + volatile uint32_t ifiupcps; /**< ifInUcastPktsCp Statistic */
24587 + volatile uint8_t res19[4]; /**< reserved */
24588 + volatile uint32_t ifioup1hs; /**< ifInOctetsUp first half Statistic */
24589 + volatile uint32_t ifioup2hs; /**< ifInOctetsUp second half Statistic */
24590 + volatile uint32_t ifiupups; /**< ifInUcastPktsUp Statistic */
24591 + volatile uint8_t res20[4]; /**< reserved */
24592 + volatile uint32_t ifimpcps; /**< ifInMulticastPktsCp Statistic */
24593 + volatile uint32_t ifibpcps; /**< ifInBroadcastPktsCp Statistic */
24594 + volatile uint32_t ifimpups; /**< ifInMulticastPktsUp Statistic */
24595 + volatile uint32_t ifibpups; /**< ifInBroadcastPktsUp Statistic */
24596 + volatile uint32_t ipwts; /**< InPktsWithoutTag Statistic */
24597 + volatile uint32_t ipkays; /**< InPktsKaY Statistic */
24598 + volatile uint32_t ipbts; /**< InPktsBadTag Statistic */
24599 + volatile uint32_t ipsnfs; /**< InPktsSCINotFound Statistic */
24600 + volatile uint32_t ipuecs; /**< InPktsUnsupportedEC Statistic */
24601 + volatile uint32_t ipescbs; /**< InPktsEponSingleCopyBroadcast Statistic */
24602 + volatile uint32_t iptls; /**< InPktsTooLong Statistic */
24603 + volatile uint8_t res21[52]; /**< reserved */
24604 +
24605 + /* Macsec Tx global statistic */
24606 + volatile uint32_t opds; /**< OutPktsDiscarded Statistic */
24607 +#if (DPAA_VERSION >= 11)
24608 + volatile uint8_t res22[124]; /**< reserved */
24609 + _Packed struct
24610 + {
24611 + volatile uint32_t rxsak[8]; /**< RX Security Association key (128/256 bit) */
24612 + volatile uint8_t res23[32]; /**< reserved */
24613 + } _PackedType rxScSaKey[NUM_OF_SA_PER_RX_SC];
24614 + _Packed struct
24615 + {
24616 + volatile uint32_t txsak[8]; /**< TX Security Association key (128/256 bit) */
24617 + volatile uint8_t res24[32]; /**< reserved */
24618 + } _PackedType txScSaKey[NUM_OF_SA_PER_TX_SC];
24619 +#endif /* (DPAA_VERSION >= 11) */
24620 +} _PackedType t_FmMacsecRegs;
24621 +
24622 +#if defined(__MWERKS__) && !defined(__GNUC__)
24623 +#pragma pack(pop)
24624 +#endif /* defined(__MWERKS__) && ... */
24625 +
24626 +
24627 +/**************************************************************************//**
24628 + @Description General defines
24629 +*//***************************************************************************/
24630 +
24631 +#define SCI_HIGH_MASK 0xffffffff00000000LL
24632 +#define SCI_LOW_MASK 0x00000000ffffffffLL
24633 +
24634 +#define LONG_SHIFT 32
24635 +
24636 +#define GET_SCI_FIRST_HALF(sci) (uint32_t)((macsecSCI_t)((macsecSCI_t)(sci) & SCI_HIGH_MASK) >> LONG_SHIFT)
24637 +#define GET_SCI_SECOND_HALF(sci) (uint32_t)((macsecSCI_t)(sci) & SCI_LOW_MASK)
24638 +
24639 +/**************************************************************************//**
24640 + @Description Configuration defines
24641 +*//***************************************************************************/
24642 +
24643 +/* masks */
24644 +#define CFG_UECT 0x00000800
24645 +#define CFG_ESCBT 0x00000400
24646 +#define CFG_USFT 0x00000300
24647 +#define CFG_ITT 0x00000080
24648 +#define CFG_KFT 0x00000040
24649 +#define CFG_UFT 0x00000030
24650 +#define CFG_KSS 0x00000004
24651 +#define CFG_BYPN 0x00000002
24652 +#define CFG_S0I 0x00000001
24653 +
24654 +#define ET_TYPE 0x0000ffff
24655 +
24656 +#define MFL_MAX_LEN 0x0000ffff
24657 +
24658 +#define RXSCA_SC_SEL 0x0000000f
24659 +
24660 +#define TXSCA_SC_SEL 0x0000000f
24661 +
24662 +#define IP_REV_1_IP_ID 0xffff0000
24663 +#define IP_REV_1_IP_MJ 0x0000ff00
24664 +#define IP_REV_1_IP_MM 0x000000ff
24665 +
24666 +#define IP_REV_2_IP_INT 0x00ff0000
24667 +#define IP_REV_2_IP_ERR 0x0000ff00
24668 +#define IP_REV_2_IP_CFG 0x000000ff
24669 +
24670 +#define MECC_CAP 0x80000000
24671 +#define MECC_CET 0x40000000
24672 +#define MECC_SERCNT 0x00ff0000
24673 +#define MECC_MEMADDR 0x000001ff
24674 +
24675 +/* shifts */
24676 +#define CFG_UECT_SHIFT (31-20)
24677 +#define CFG_ESCBT_SHIFT (31-21)
24678 +#define CFG_USFT_SHIFT (31-23)
24679 +#define CFG_ITT_SHIFT (31-24)
24680 +#define CFG_KFT_SHIFT (31-25)
24681 +#define CFG_UFT_SHIFT (31-27)
24682 +#define CFG_KSS_SHIFT (31-29)
24683 +#define CFG_BYPN_SHIFT (31-30)
24684 +#define CFG_S0I_SHIFT (31-31)
24685 +
24686 +#define IP_REV_1_IP_ID_SHIFT (31-15)
24687 +#define IP_REV_1_IP_MJ_SHIFT (31-23)
24688 +#define IP_REV_1_IP_MM_SHIFT (31-31)
24689 +
24690 +#define IP_REV_2_IP_INT_SHIFT (31-15)
24691 +#define IP_REV_2_IP_ERR_SHIFT (31-23)
24692 +#define IP_REV_2_IP_CFG_SHIFT (31-31)
24693 +
24694 +#define MECC_CAP_SHIFT (31-0)
24695 +#define MECC_CET_SHIFT (31-1)
24696 +#define MECC_SERCNT_SHIFT (31-15)
24697 +#define MECC_MEMADDR_SHIFT (31-31)
24698 +
24699 +/**************************************************************************//**
24700 + @Description RX SC defines
24701 +*//***************************************************************************/
24702 +
24703 +/* masks */
24704 +#define RX_SCCFG_SCI_EN_MASK 0x00000800
24705 +#define RX_SCCFG_RP_MASK 0x00000400
24706 +#define RX_SCCFG_VF_MASK 0x00000300
24707 +#define RX_SCCFG_CO_MASK 0x0000003f
24708 +
24709 +/* shifts */
24710 +#define RX_SCCFG_SCI_EN_SHIFT (31-20)
24711 +#define RX_SCCFG_RP_SHIFT (31-21)
24712 +#define RX_SCCFG_VF_SHIFT (31-23)
24713 +#define RX_SCCFG_CO_SHIFT (31-31)
24714 +#define RX_SCCFG_CS_SHIFT (31-7)
24715 +
24716 +/**************************************************************************//**
24717 + @Description RX SA defines
24718 +*//***************************************************************************/
24719 +
24720 +/* masks */
24721 +#define RX_SACFG_ACTIVE 0x80000000
24722 +#define RX_SACFG_AN_MASK 0x00000006
24723 +#define RX_SACFG_EN_MASK 0x00000001
24724 +
24725 +/* shifts */
24726 +#define RX_SACFG_AN_SHIFT (31-30)
24727 +#define RX_SACFG_EN_SHIFT (31-31)
24728 +
24729 +/**************************************************************************//**
24730 + @Description TX SC defines
24731 +*//***************************************************************************/
24732 +
24733 +/* masks */
24734 +#define TX_SCCFG_AN_MASK 0x000c0000
24735 +#define TX_SCCFG_ASA_MASK 0x00020000
24736 +#define TX_SCCFG_SCE_MASK 0x00010000
24737 +#define TX_SCCFG_CO_MASK 0x00003f00
24738 +#define TX_SCCFG_CE_MASK 0x00000010
24739 +#define TX_SCCFG_PF_MASK 0x00000008
24740 +#define TX_SCCFG_AIS_MASK 0x00000004
24741 +#define TX_SCCFG_UES_MASK 0x00000002
24742 +#define TX_SCCFG_USCB_MASK 0x00000001
24743 +
24744 +/* shifts */
24745 +#define TX_SCCFG_AN_SHIFT (31-13)
24746 +#define TX_SCCFG_ASA_SHIFT (31-14)
24747 +#define TX_SCCFG_SCE_SHIFT (31-15)
24748 +#define TX_SCCFG_CO_SHIFT (31-23)
24749 +#define TX_SCCFG_CE_SHIFT (31-27)
24750 +#define TX_SCCFG_PF_SHIFT (31-28)
24751 +#define TX_SCCFG_AIS_SHIFT (31-29)
24752 +#define TX_SCCFG_UES_SHIFT (31-30)
24753 +#define TX_SCCFG_USCB_SHIFT (31-31)
24754 +#define TX_SCCFG_CS_SHIFT (31-7)
24755 +
24756 +/**************************************************************************//**
24757 + @Description TX SA defines
24758 +*//***************************************************************************/
24759 +
24760 +/* masks */
24761 +#define TX_SACFG_ACTIVE 0x80000000
24762 +
24763 +
24764 +typedef struct
24765 +{
24766 + void (*f_Isr) (t_Handle h_Arg, uint32_t id);
24767 + t_Handle h_SrcHandle;
24768 +} t_FmMacsecIntrSrc;
24769 +
24770 +typedef struct
24771 +{
24772 + e_FmMacsecUnknownSciFrameTreatment unknownSciTreatMode;
24773 + bool invalidTagsDeliverUncontrolled;
24774 + bool changedTextWithNoEncryptDeliverUncontrolled;
24775 + bool onlyScbIsSetDeliverUncontrolled;
24776 + bool encryptWithNoChangedTextDiscardUncontrolled;
24777 + e_FmMacsecUntagFrameTreatment untagTreatMode;
24778 + uint32_t pnExhThr;
24779 + bool keysUnreadable;
24780 + bool byPassMode;
24781 + bool reservedSc0;
24782 + uint32_t sectagOverhead;
24783 + uint32_t mflSubtract;
24784 +} t_FmMacsecDriverParam;
24785 +
24786 +typedef struct
24787 +{
24788 + t_FmMacsecControllerDriver fmMacsecControllerDriver;
24789 + t_Handle h_Fm;
24790 + t_FmMacsecRegs *p_FmMacsecRegs;
24791 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
24792 + char fmMacsecModuleName[MODULE_NAME_SIZE];
24793 + t_FmMacsecIntrSrc intrMng[NUM_OF_INTER_MODULE_EVENTS];
24794 + uint32_t events;
24795 + uint32_t exceptions;
24796 + uint32_t userExceptions;
24797 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
24798 + t_Handle h_App; /**< A handle to an application layer object; This handle will
24799 + be passed by the driver upon calling the above callbacks */
24800 + bool rxScTable[NUM_OF_RX_SC];
24801 + uint32_t numRxScAvailable;
24802 + bool txScTable[NUM_OF_TX_SC];
24803 + uint32_t numTxScAvailable;
24804 + t_Handle rxScSpinLock;
24805 + t_Handle txScSpinLock;
24806 + t_FmMacsecDriverParam *p_FmMacsecDriverParam;
24807 +} t_FmMacsec;
24808 +
24809 +
24810 +#endif /* __FM_MACSEC_MASTER_H */
24811 --- /dev/null
24812 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
24813 @@ -0,0 +1,883 @@
24814 +/*
24815 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24816 + *
24817 + * Redistribution and use in source and binary forms, with or without
24818 + * modification, are permitted provided that the following conditions are met:
24819 + * * Redistributions of source code must retain the above copyright
24820 + * notice, this list of conditions and the following disclaimer.
24821 + * * Redistributions in binary form must reproduce the above copyright
24822 + * notice, this list of conditions and the following disclaimer in the
24823 + * documentation and/or other materials provided with the distribution.
24824 + * * Neither the name of Freescale Semiconductor nor the
24825 + * names of its contributors may be used to endorse or promote products
24826 + * derived from this software without specific prior written permission.
24827 + *
24828 + *
24829 + * ALTERNATIVELY, this software may be distributed under the terms of the
24830 + * GNU General Public License ("GPL") as published by the Free Software
24831 + * Foundation, either version 2 of that License or (at your option) any
24832 + * later version.
24833 + *
24834 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24835 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24836 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24837 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24838 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24839 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24840 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24841 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24842 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24843 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24844 + */
24845 +
24846 +/******************************************************************************
24847 + @File fm_macsec_secy.c
24848 +
24849 + @Description FM MACSEC SECY driver routines implementation.
24850 +*//***************************************************************************/
24851 +
24852 +#include "std_ext.h"
24853 +#include "error_ext.h"
24854 +#include "xx_ext.h"
24855 +#include "string_ext.h"
24856 +#include "sprint_ext.h"
24857 +
24858 +#include "fm_macsec_secy.h"
24859 +
24860 +
24861 +/****************************************/
24862 +/* static functions */
24863 +/****************************************/
24864 +static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
24865 +{
24866 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
24867 +
24868 + UNUSED(id);
24869 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
24870 +
24871 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
24872 + p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED);
24873 +}
24874 +
24875 +static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
24876 +{
24877 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
24878 +
24879 + UNUSED(id);
24880 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
24881 +
24882 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
24883 + p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN);
24884 +}
24885 +
24886 +static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY)
24887 +{
24888 + if (!p_FmMacsecSecY->f_Exception)
24889 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
24890 +
24891 + if (!p_FmMacsecSecY->f_Event)
24892 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided"));
24893 +
24894 + if (!p_FmMacsecSecY->numOfRxSc)
24895 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'"));
24896 +
24897 +
24898 + return E_OK;
24899 +}
24900 +
24901 +static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY *p_FmMacsecSecY,
24902 + macsecSCI_t sci,
24903 + e_FmMacsecSecYCipherSuite cipherSuite,
24904 + e_ScType type)
24905 +{
24906 + t_SecYSc *p_ScTable;
24907 + void *p_Params;
24908 + uint32_t numOfSc,i;
24909 + t_Error err = E_OK;
24910 + t_RxScParams rxScParams;
24911 + t_TxScParams txScParams;
24912 +
24913 + ASSERT_COND(p_FmMacsecSecY);
24914 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
24915 +
24916 + if (type == e_SC_RX)
24917 + {
24918 + memset(&rxScParams, 0, sizeof(rxScParams));
24919 + i = (NUM_OF_RX_SC - 1);
24920 + p_ScTable = p_FmMacsecSecY->p_RxSc;
24921 + numOfSc = p_FmMacsecSecY->numOfRxSc;
24922 + rxScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
24923 + rxScParams.replayProtect = p_FmMacsecSecY->replayProtect;
24924 + rxScParams.replayWindow = p_FmMacsecSecY->replayWindow;
24925 + rxScParams.validateFrames = p_FmMacsecSecY->validateFrames;
24926 + rxScParams.cipherSuite = cipherSuite;
24927 + p_Params = &rxScParams;
24928 + }
24929 + else
24930 + {
24931 + memset(&txScParams, 0, sizeof(txScParams));
24932 + i = (NUM_OF_TX_SC - 1);
24933 + p_ScTable = p_FmMacsecSecY->p_TxSc;
24934 + numOfSc = p_FmMacsecSecY->numOfTxSc;
24935 + txScParams.sciInsertionMode = p_FmMacsecSecY->sciInsertionMode;
24936 + txScParams.protectFrames = p_FmMacsecSecY->protectFrames;
24937 + txScParams.confidentialityEnable = p_FmMacsecSecY->confidentialityEnable;
24938 + txScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
24939 + txScParams.cipherSuite = cipherSuite;
24940 + p_Params = &txScParams;
24941 + }
24942 +
24943 + for (i=0;i<numOfSc;i++)
24944 + if (!p_ScTable[i].inUse)
24945 + break;
24946 + if (i == numOfSc)
24947 + {
24948 + REPORT_ERROR(MAJOR, E_FULL, ("FM MACSEC SECY SC"));
24949 + return NULL;
24950 + }
24951 +
24952 + if (type == e_SC_RX)
24953 + {
24954 + ((t_RxScParams *)p_Params)->scId = p_ScTable[i].scId;
24955 + ((t_RxScParams *)p_Params)->sci = sci;
24956 + if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK)
24957 + {
24958 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
24959 + return NULL;
24960 + }
24961 + }
24962 + else
24963 + {
24964 + ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId;
24965 + ((t_TxScParams *)p_Params)->sci = sci;
24966 + if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK)
24967 + {
24968 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
24969 + return NULL;
24970 + }
24971 + }
24972 +
24973 + p_ScTable[i].inUse = TRUE;
24974 + return &p_ScTable[i];
24975 +}
24976 +
24977 +static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type)
24978 +{
24979 + t_Error err = E_OK;
24980 +
24981 + ASSERT_COND(p_FmMacsecSecY);
24982 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
24983 + ASSERT_COND(p_FmSecYSc);
24984 +
24985 + if (type == e_SC_RX)
24986 + {
24987 + if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
24988 + RETURN_ERROR(MINOR, err, NO_MSG);
24989 + }
24990 + else
24991 + if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
24992 + RETURN_ERROR(MINOR, err, NO_MSG);
24993 +
24994 + p_FmSecYSc->inUse = FALSE;
24995 +
24996 + return err;
24997 +}
24998 +
24999 +/****************************************/
25000 +/* API Init unit functions */
25001 +/****************************************/
25002 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam)
25003 +{
25004 + t_FmMacsecSecY *p_FmMacsecSecY;
25005 +
25006 + /* Allocate FM MACSEC structure */
25007 + p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY));
25008 + if (!p_FmMacsecSecY)
25009 + {
25010 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure"));
25011 + return NULL;
25012 + }
25013 + memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY));
25014 +
25015 + /* Allocate the FM MACSEC driver's parameters structure */
25016 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam));
25017 + if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam)
25018 + {
25019 + XX_Free(p_FmMacsecSecY);
25020 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters"));
25021 + return NULL;
25022 + }
25023 + memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam));
25024 +
25025 + /* Initialize FM MACSEC SECY parameters which will be kept by the driver */
25026 + p_FmMacsecSecY->h_FmMacsec = p_FmMacsecSecYParam->h_FmMacsec;
25027 + p_FmMacsecSecY->f_Event = p_FmMacsecSecYParam->f_Event;
25028 + p_FmMacsecSecY->f_Exception = p_FmMacsecSecYParam->f_Exception;
25029 + p_FmMacsecSecY->h_App = p_FmMacsecSecYParam->h_App;
25030 + p_FmMacsecSecY->confidentialityEnable = DEFAULT_confidentialityEnable;
25031 + p_FmMacsecSecY->confidentialityOffset = DEFAULT_confidentialityOffset;
25032 + p_FmMacsecSecY->validateFrames = DEFAULT_validateFrames;
25033 + p_FmMacsecSecY->replayProtect = DEFAULT_replayEnable;
25034 + p_FmMacsecSecY->replayWindow = DEFAULT_replayWindow;
25035 + p_FmMacsecSecY->protectFrames = DEFAULT_protectFrames;
25036 + p_FmMacsecSecY->sciInsertionMode = DEFAULT_sciInsertionMode;
25037 + p_FmMacsecSecY->isPointToPoint = DEFAULT_ptp;
25038 + p_FmMacsecSecY->numOfRxSc = p_FmMacsecSecYParam->numReceiveChannels;
25039 + p_FmMacsecSecY->numOfTxSc = DEFAULT_numOfTxSc;
25040 + p_FmMacsecSecY->exceptions = DEFAULT_exceptions;
25041 + p_FmMacsecSecY->events = DEFAULT_events;
25042 +
25043 + memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams,
25044 + &p_FmMacsecSecYParam->txScParams,
25045 + sizeof(t_FmMacsecSecYSCParams));
25046 + return p_FmMacsecSecY;
25047 +}
25048 +
25049 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY)
25050 +{
25051 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25052 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam = NULL;
25053 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j;
25054 + t_Error err;
25055 +
25056 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25057 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE);
25058 +
25059 + CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters);
25060 +
25061 + p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam;
25062 +
25063 + if ((p_FmMacsecSecY->isPointToPoint) &&
25064 + ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK))
25065 + RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point"));
25066 +
25067 + /* Rx Sc Allocation */
25068 + p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
25069 + if (!p_FmMacsecSecY->p_RxSc)
25070 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
25071 + memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
25072 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
25073 + {
25074 + if (p_FmMacsecSecY->p_TxSc)
25075 + XX_Free(p_FmMacsecSecY->p_TxSc);
25076 + if (p_FmMacsecSecY->p_RxSc)
25077 + XX_Free(p_FmMacsecSecY->p_RxSc);
25078 + return ERROR_CODE(err);
25079 + }
25080 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
25081 + {
25082 + p_FmMacsecSecY->p_RxSc[i].scId = rxScIds[i];
25083 + p_FmMacsecSecY->p_RxSc[i].type = e_SC_RX;
25084 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
25085 + p_FmMacsecSecY->p_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25086 + }
25087 +
25088 + /* Tx Sc Allocation */
25089 + p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
25090 + if (!p_FmMacsecSecY->p_TxSc)
25091 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
25092 + memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
25093 +
25094 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
25095 + {
25096 + if (p_FmMacsecSecY->p_TxSc)
25097 + XX_Free(p_FmMacsecSecY->p_TxSc);
25098 + if (p_FmMacsecSecY->p_RxSc)
25099 + XX_Free(p_FmMacsecSecY->p_RxSc);
25100 + return ERROR_CODE(err);
25101 + }
25102 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++)
25103 + {
25104 + p_FmMacsecSecY->p_TxSc[i].scId = txScIds[i];
25105 + p_FmMacsecSecY->p_TxSc[i].type = e_SC_TX;
25106 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
25107 + p_FmMacsecSecY->p_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25108 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
25109 + e_FM_MACSEC_MOD_SC_TX,
25110 + (uint8_t)txScIds[i],
25111 + e_FM_INTR_TYPE_ERR,
25112 + FmMacsecSecYExceptionsIsr,
25113 + p_FmMacsecSecY);
25114 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
25115 + e_FM_MACSEC_MOD_SC_TX,
25116 + (uint8_t)txScIds[i],
25117 + e_FM_INTR_TYPE_NORMAL,
25118 + FmMacsecSecYEventsIsr,
25119 + p_FmMacsecSecY);
25120 +
25121 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25122 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE);
25123 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25124 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE);
25125 + }
25126 +
25127 + FmMacsecSecYCreateSc(p_FmMacsecSecY,
25128 + p_FmMacsecSecYDriverParam->txScParams.sci,
25129 + p_FmMacsecSecYDriverParam->txScParams.cipherSuite,
25130 + e_SC_TX);
25131 + XX_Free(p_FmMacsecSecYDriverParam);
25132 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL;
25133 +
25134 + return E_OK;
25135 +}
25136 +
25137 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY)
25138 +{
25139 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25140 + t_Error err = E_OK;
25141 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i;
25142 +
25143 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25144 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25145 +
25146 + if (p_FmMacsecSecY->isPointToPoint)
25147 + FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE);
25148 + if (p_FmMacsecSecY->p_RxSc)
25149 + {
25150 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
25151 + rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId;
25152 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
25153 + return ERROR_CODE(err);
25154 + XX_Free(p_FmMacsecSecY->p_RxSc);
25155 + }
25156 + if (p_FmMacsecSecY->p_TxSc)
25157 + {
25158 + FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX);
25159 +
25160 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++) {
25161 + txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId;
25162 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25163 + e_FM_MACSEC_MOD_SC_TX,
25164 + (uint8_t)txScIds[i],
25165 + e_FM_INTR_TYPE_ERR);
25166 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25167 + e_FM_MACSEC_MOD_SC_TX,
25168 + (uint8_t)txScIds[i],
25169 + e_FM_INTR_TYPE_NORMAL);
25170 +
25171 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25172 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE);
25173 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25174 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE);
25175 + }
25176 +
25177 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
25178 + return ERROR_CODE(err);
25179 + XX_Free(p_FmMacsecSecY->p_TxSc);
25180 + }
25181 +
25182 + XX_Free(p_FmMacsecSecY);
25183 +
25184 + return err;
25185 +}
25186 +
25187 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode)
25188 +{
25189 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25190 +
25191 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25192 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25193 +
25194 + p_FmMacsecSecY->sciInsertionMode = sciInsertionMode;
25195 +
25196 + return E_OK;
25197 +}
25198 +
25199 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames)
25200 +{
25201 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25202 +
25203 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25204 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25205 +
25206 + p_FmMacsecSecY->protectFrames = protectFrames;
25207 +
25208 + return E_OK;
25209 +}
25210 +
25211 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow)
25212 +{
25213 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25214 +
25215 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25216 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25217 +
25218 + p_FmMacsecSecY->replayProtect = replayProtect;
25219 + p_FmMacsecSecY->replayWindow = replayWindow;
25220 +
25221 + return E_OK;
25222 +}
25223 +
25224 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames)
25225 +{
25226 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25227 +
25228 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25229 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25230 +
25231 + p_FmMacsecSecY->validateFrames = validateFrames;
25232 +
25233 + return E_OK;
25234 +}
25235 +
25236 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset)
25237 +{
25238 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25239 +
25240 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25241 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25242 +
25243 + p_FmMacsecSecY->confidentialityEnable = confidentialityEnable;
25244 + p_FmMacsecSecY->confidentialityOffset = confidentialityOffset;
25245 +
25246 + return E_OK;
25247 +}
25248 +
25249 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY)
25250 +{
25251 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25252 +
25253 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25254 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25255 +
25256 + p_FmMacsecSecY->numOfRxSc = 1;
25257 + p_FmMacsecSecY->isPointToPoint = TRUE;
25258 + p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP;
25259 +
25260 + return E_OK;
25261 +}
25262 +
25263 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable)
25264 +{
25265 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25266 + uint32_t bitMask = 0;
25267 +
25268 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25269 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25270 +
25271 + GET_EXCEPTION_FLAG(bitMask, exception);
25272 + if (bitMask)
25273 + {
25274 + if (enable)
25275 + p_FmMacsecSecY->exceptions |= bitMask;
25276 + else
25277 + p_FmMacsecSecY->exceptions &= ~bitMask;
25278 + }
25279 + else
25280 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
25281 +
25282 + return E_OK;
25283 +}
25284 +
25285 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25286 +{
25287 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25288 + uint32_t bitMask = 0;
25289 +
25290 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25291 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25292 +
25293 + GET_EVENT_FLAG(bitMask, event);
25294 + if (bitMask)
25295 + {
25296 + if (enable)
25297 + p_FmMacsecSecY->events |= bitMask;
25298 + else
25299 + p_FmMacsecSecY->events &= ~bitMask;
25300 + }
25301 + else
25302 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
25303 +
25304 + return E_OK;
25305 +}
25306 +
25307 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams)
25308 +{
25309 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25310 +
25311 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL);
25312 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL);
25313 + SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL);
25314 + SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL);
25315 +
25316 + return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX);
25317 +}
25318 +
25319 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc)
25320 +{
25321 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25322 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25323 +
25324 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25325 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25326 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25327 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25328 +
25329 + return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX);
25330 +}
25331 +
25332 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
25333 +{
25334 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25335 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25336 + t_Error err = E_OK;
25337 +
25338 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25339 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25340 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25341 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25342 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25343 +
25344 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25345 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an));
25346 +
25347 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK)
25348 + RETURN_ERROR(MINOR, err, NO_MSG);
25349 +
25350 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25351 + return err;
25352 +}
25353 +
25354 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25355 +{
25356 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25357 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25358 + t_Error err = E_OK;
25359 +
25360 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25361 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25362 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25363 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25364 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25365 +
25366 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25367 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25368 +
25369 + if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25370 + RETURN_ERROR(MINOR, err, NO_MSG);
25371 +
25372 + p_FmSecYSc->numOfSa--;
25373 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25374 + /* TODO - check if statistics need to be read*/
25375 + return err;
25376 +}
25377 +
25378 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25379 +{
25380 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25381 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25382 + t_Error err = E_OK;
25383 +
25384 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25385 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25386 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25387 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25388 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25389 +
25390 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25391 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25392 +
25393 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25394 + RETURN_ERROR(MINOR, err, NO_MSG);
25395 +
25396 + p_FmSecYSc->sa[an].active = TRUE;
25397 + return err;
25398 +}
25399 +
25400 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25401 +{
25402 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25403 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25404 + t_Error err = E_OK;
25405 +
25406 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25407 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25408 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25409 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25410 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25411 +
25412 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25413 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25414 +
25415 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25416 + RETURN_ERROR(MINOR, err, NO_MSG);
25417 +
25418 + p_FmSecYSc->sa[an].active = FALSE;
25419 + return err;
25420 +}
25421 +
25422 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN)
25423 +{
25424 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25425 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25426 + t_Error err = E_OK;
25427 +
25428 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25429 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25430 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25431 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25432 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25433 +
25434 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25435 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25436 +
25437 + if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK)
25438 + RETURN_ERROR(MINOR, err, NO_MSG);
25439 +
25440 + return err;
25441 +}
25442 +
25443 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN)
25444 +{
25445 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25446 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25447 + t_Error err = E_OK;
25448 +
25449 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25450 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25451 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25452 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25453 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25454 +
25455 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25456 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25457 +
25458 + if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK)
25459 + RETURN_ERROR(MINOR, err, NO_MSG);
25460 +
25461 + return err;
25462 +}
25463 +
25464 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key)
25465 +{
25466 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25467 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25468 + t_Error err = E_OK;
25469 +
25470 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25471 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25472 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25473 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25474 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25475 +
25476 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25477 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25478 +
25479 + if (p_FmSecYSc->sa[an].active)
25480 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25481 + RETURN_ERROR(MINOR, err, NO_MSG);
25482 +
25483 + /* TODO - statistics should be read */
25484 +
25485 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK)
25486 + RETURN_ERROR(MINOR, err, NO_MSG);
25487 +
25488 + if (p_FmSecYSc->sa[an].active)
25489 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25490 + RETURN_ERROR(MINOR, err, NO_MSG);
25491 + return err;
25492 +}
25493 +
25494 +
25495 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key)
25496 +{
25497 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25498 + t_SecYSc *p_FmSecYSc;
25499 + t_Error err = E_OK;
25500 +
25501 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25502 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25503 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25504 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25505 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25506 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25507 +
25508 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25509 + RETURN_ERROR(MINOR, err, ("An %d is already assigned",an));
25510 +
25511 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK)
25512 + RETURN_ERROR(MINOR, err, NO_MSG);
25513 +
25514 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25515 + return err;
25516 +}
25517 +
25518 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an)
25519 +{
25520 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25521 + t_SecYSc *p_FmSecYSc;
25522 + t_Error err = E_OK;
25523 +
25524 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25525 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25526 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25527 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25528 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25529 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25530 +
25531 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25532 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25533 +
25534 + if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25535 + RETURN_ERROR(MINOR, err, NO_MSG);
25536 +
25537 + p_FmSecYSc->numOfSa--;
25538 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25539 + /* TODO - check if statistics need to be read*/
25540 + return err;
25541 +}
25542 +
25543 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key)
25544 +{
25545 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25546 + t_SecYSc *p_FmSecYSc;
25547 + macsecAN_t currentAn;
25548 + t_Error err = E_OK;
25549 +
25550 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25551 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25552 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25553 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25554 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25555 + SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25556 +
25557 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25558 + p_FmSecYSc->scId,
25559 + &currentAn)) != E_OK)
25560 + RETURN_ERROR(MINOR, err, NO_MSG);
25561 +
25562 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25563 + p_FmSecYSc->scId,
25564 + p_FmSecYSc->sa[nextActiveAn].saId,
25565 + nextActiveAn)) != E_OK)
25566 + RETURN_ERROR(MINOR, err, NO_MSG);
25567 +
25568 + /* TODO - statistics should be read */
25569 +
25570 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK)
25571 + RETURN_ERROR(MINOR, err, NO_MSG);
25572 +
25573 + return err;
25574 +}
25575 +
25576 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an)
25577 +{
25578 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25579 + t_SecYSc *p_FmSecYSc;
25580 + t_Error err = E_OK;
25581 +
25582 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25583 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25584 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25585 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25586 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25587 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25588 +
25589 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25590 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25591 +
25592 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25593 + p_FmSecYSc->scId,
25594 + p_FmSecYSc->sa[an].saId,
25595 + an)) != E_OK)
25596 + RETURN_ERROR(MINOR, err, NO_MSG);
25597 +
25598 + return err;
25599 +}
25600 +
25601 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An)
25602 +{
25603 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25604 + t_SecYSc *p_FmSecYSc;
25605 + t_Error err = E_OK;
25606 +
25607 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25608 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25609 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25610 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25611 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25612 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
25613 +
25614 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25615 + p_FmSecYSc->scId,
25616 + p_An)) != E_OK)
25617 + RETURN_ERROR(MINOR, err, NO_MSG);
25618 +
25619 + return err;
25620 +}
25621 +
25622 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId)
25623 +{
25624 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25625 + t_Error err = E_OK;
25626 +
25627 + SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE);
25628 + SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE);
25629 + SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25630 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25631 +#ifdef DISABLE_SANITY_CHECKS
25632 + UNUSED(h_FmMacsecSecY);
25633 +#endif /* DISABLE_SANITY_CHECKS */
25634 +
25635 + *p_ScPhysId = p_FmSecYSc->scId;
25636 + return err;
25637 +}
25638 +
25639 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId)
25640 +{
25641 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25642 + t_SecYSc *p_FmSecYSc;
25643 + t_Error err = E_OK;
25644 +
25645 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25646 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25647 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25648 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25649 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25650 +
25651 + *p_ScPhysId = p_FmSecYSc->scId;
25652 + return err;
25653 +}
25654 +
25655 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable)
25656 +{
25657 + UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable);
25658 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25659 +}
25660 +
25661 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25662 +{
25663 + UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable);
25664 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25665 +}
25666 +
25667 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics)
25668 +{
25669 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25670 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25671 +}
25672 +
25673 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics)
25674 +{
25675 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics);
25676 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25677 +}
25678 +
25679 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics)
25680 +{
25681 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics);
25682 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25683 +}
25684 +
25685 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics)
25686 +{
25687 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25688 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25689 +}
25690 +
25691 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics)
25692 +{
25693 + UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics);
25694 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25695 +}
25696 +
25697 --- /dev/null
25698 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
25699 @@ -0,0 +1,144 @@
25700 +/*
25701 + * Copyright 2008-2015 Freescale Semiconductor Inc.
25702 + *
25703 + * Redistribution and use in source and binary forms, with or without
25704 + * modification, are permitted provided that the following conditions are met:
25705 + * * Redistributions of source code must retain the above copyright
25706 + * notice, this list of conditions and the following disclaimer.
25707 + * * Redistributions in binary form must reproduce the above copyright
25708 + * notice, this list of conditions and the following disclaimer in the
25709 + * documentation and/or other materials provided with the distribution.
25710 + * * Neither the name of Freescale Semiconductor nor the
25711 + * names of its contributors may be used to endorse or promote products
25712 + * derived from this software without specific prior written permission.
25713 + *
25714 + *
25715 + * ALTERNATIVELY, this software may be distributed under the terms of the
25716 + * GNU General Public License ("GPL") as published by the Free Software
25717 + * Foundation, either version 2 of that License or (at your option) any
25718 + * later version.
25719 + *
25720 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25721 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25722 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25723 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25724 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25725 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25726 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25727 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25728 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25729 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25730 + */
25731 +
25732 +/******************************************************************************
25733 + @File fm_macsec_secy.h
25734 +
25735 + @Description FM MACSEC SecY internal structures and definitions.
25736 +*//***************************************************************************/
25737 +#ifndef __FM_MACSEC_SECY_H
25738 +#define __FM_MACSEC_SECY_H
25739 +
25740 +#include "error_ext.h"
25741 +#include "std_ext.h"
25742 +
25743 +#include "fm_macsec.h"
25744 +
25745 +
25746 +/**************************************************************************//**
25747 + @Description Exceptions
25748 +*//***************************************************************************/
25749 +
25750 +#define FM_MACSEC_SECY_EX_FRAME_DISCARDED 0x80000000
25751 +
25752 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
25753 + case e_FM_MACSEC_SECY_EX_FRAME_DISCARDED: \
25754 + bitMask = FM_MACSEC_SECY_EX_FRAME_DISCARDED; break; \
25755 + default: bitMask = 0;break;}
25756 +
25757 +/**************************************************************************//**
25758 + @Description Events
25759 +*//***************************************************************************/
25760 +
25761 +#define FM_MACSEC_SECY_EV_NEXT_PN 0x80000000
25762 +
25763 +#define GET_EVENT_FLAG(bitMask, event) switch (event){ \
25764 + case e_FM_MACSEC_SECY_EV_NEXT_PN: \
25765 + bitMask = FM_MACSEC_SECY_EV_NEXT_PN; break; \
25766 + default: bitMask = 0;break;}
25767 +
25768 +/**************************************************************************//**
25769 + @Description Defaults
25770 +*//***************************************************************************/
25771 +
25772 +#define DEFAULT_exceptions (FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25773 +#define DEFAULT_events (FM_MACSEC_SECY_EV_NEXT_PN)
25774 +#define DEFAULT_numOfTxSc 1
25775 +#define DEFAULT_confidentialityEnable FALSE
25776 +#define DEFAULT_confidentialityOffset 0
25777 +#define DEFAULT_sciInsertionMode e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG
25778 +#define DEFAULT_validateFrames e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
25779 +#define DEFAULT_replayEnable FALSE
25780 +#define DEFAULT_replayWindow 0
25781 +#define DEFAULT_protectFrames TRUE
25782 +#define DEFAULT_ptp FALSE
25783 +
25784 +/**************************************************************************//**
25785 + @Description General defines
25786 +*//***************************************************************************/
25787 +
25788 +#define SECY_AN_FREE_VALUE MAX_NUM_OF_SA_PER_SC
25789 +
25790 +
25791 +typedef struct {
25792 + e_ScSaId saId;
25793 + bool active;
25794 + union {
25795 + t_FmMacsecSecYRxSaStatistics rxSaStatistics;
25796 + t_FmMacsecSecYTxSaStatistics txSaStatistics;
25797 + };
25798 +} t_SecYSa;
25799 +
25800 +typedef struct {
25801 + bool inUse;
25802 + uint32_t scId;
25803 + e_ScType type;
25804 + uint8_t numOfSa;
25805 + t_SecYSa sa[MAX_NUM_OF_SA_PER_SC];
25806 + union {
25807 + t_FmMacsecSecYRxScStatistics rxScStatistics;
25808 + t_FmMacsecSecYTxScStatistics txScStatistics;
25809 + };
25810 +} t_SecYSc;
25811 +
25812 +typedef struct {
25813 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
25814 +} t_FmMacsecSecYDriverParam;
25815 +
25816 +typedef struct {
25817 + t_Handle h_FmMacsec;
25818 + bool confidentialityEnable; /**< TRUE - confidentiality protection and integrity protection
25819 + FALSE - no confidentiality protection, only integrity protection*/
25820 + uint16_t confidentialityOffset; /**< The number of initial octets of each MSDU without confidentiality protection
25821 + common values are 0, 30, and 50 */
25822 + bool replayProtect; /**< replay protection function mode */
25823 + uint32_t replayWindow; /**< the size of the replay window */
25824 + e_FmMacsecValidFrameBehavior validateFrames; /**< validation function mode */
25825 + e_FmMacsecSciInsertionMode sciInsertionMode;
25826 + bool protectFrames;
25827 + bool isPointToPoint;
25828 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for this SecY */
25829 + uint32_t numOfRxSc; /**< Number of receive channels */
25830 + uint32_t numOfTxSc; /**< Number of transmit channels */
25831 + t_SecYSc *p_RxSc;
25832 + t_SecYSc *p_TxSc;
25833 + uint32_t events;
25834 + uint32_t exceptions;
25835 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< TODO */
25836 + t_FmMacsecSecYEventsCallback *f_Event; /**< TODO */
25837 + t_Handle h_App;
25838 + t_FmMacsecSecYStatistics statistics;
25839 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam;
25840 +} t_FmMacsecSecY;
25841 +
25842 +
25843 +#endif /* __FM_MACSEC_SECY_H */
25844 --- /dev/null
25845 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
25846 @@ -0,0 +1,23 @@
25847 +#
25848 +# Makefile for the Freescale Ethernet controllers
25849 +#
25850 +ccflags-y += -DVERSION=\"\"
25851 +#
25852 +#Include netcomm SW specific definitions
25853 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
25854 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
25855 +
25856 +ccflags-y += -I$(NCSW_FM_INC)
25857 +
25858 +
25859 +obj-y += fsl-ncsw-PFM1.o
25860 +
25861 +fsl-ncsw-PFM1-objs := fm.o fm_muram.o fman.o
25862 +
25863 +obj-y += MAC/
25864 +obj-y += Pcd/
25865 +obj-y += SP/
25866 +obj-y += Port/
25867 +obj-y += HC/
25868 +obj-y += Rtc/
25869 +obj-y += MACSEC/
25870 --- /dev/null
25871 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
25872 @@ -0,0 +1,26 @@
25873 +#
25874 +# Makefile for the Freescale Ethernet controllers
25875 +#
25876 +ccflags-y += -DVERSION=\"\"
25877 +#
25878 +#Include netcomm SW specific definitions
25879 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
25880 +
25881 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
25882 +
25883 +ccflags-y += -I$(NCSW_FM_INC)
25884 +
25885 +obj-y += fsl-ncsw-Pcd.o
25886 +
25887 +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
25888 +
25889 +ifeq ($(CONFIG_FMAN_V3H),y)
25890 +fsl-ncsw-Pcd-objs += fm_replic.o
25891 +endif
25892 +ifeq ($(CONFIG_FMAN_V3L),y)
25893 +fsl-ncsw-Pcd-objs += fm_replic.o
25894 +endif
25895 +ifeq ($(CONFIG_FMAN_ARM),y)
25896 +fsl-ncsw-Pcd-objs += fm_replic.o
25897 +endif
25898 +
25899 --- /dev/null
25900 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
25901 @@ -0,0 +1,360 @@
25902 +/*
25903 + * Copyright 2008-2012 Freescale Semiconductor Inc.
25904 + *
25905 + * Redistribution and use in source and binary forms, with or without
25906 + * modification, are permitted provided that the following conditions are met:
25907 + * * Redistributions of source code must retain the above copyright
25908 + * notice, this list of conditions and the following disclaimer.
25909 + * * Redistributions in binary form must reproduce the above copyright
25910 + * notice, this list of conditions and the following disclaimer in the
25911 + * documentation and/or other materials provided with the distribution.
25912 + * * Neither the name of Freescale Semiconductor nor the
25913 + * names of its contributors may be used to endorse or promote products
25914 + * derived from this software without specific prior written permission.
25915 + *
25916 + *
25917 + * ALTERNATIVELY, this software may be distributed under the terms of the
25918 + * GNU General Public License ("GPL") as published by the Free Software
25919 + * Foundation, either version 2 of that License or (at your option) any
25920 + * later version.
25921 + *
25922 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25923 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25924 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25925 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25926 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25927 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25928 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25929 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25930 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25931 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25932 + */
25933 +
25934 +
25935 + /**************************************************************************//**
25936 + @File crc64.h
25937 +
25938 + @Description brief This file contains the CRC64 Table, and __inline__
25939 + functions used for calculating crc.
25940 +*//***************************************************************************/
25941 +#ifndef __CRC64_H
25942 +#define __CRC64_H
25943 +
25944 +#include "std_ext.h"
25945 +
25946 +
25947 +#define BITS_PER_BYTE 8
25948 +
25949 +#define CRC64_EXPON_ECMA_182 0xC96C5795D7870F42ULL
25950 +#define CRC64_DEFAULT_INITVAL 0xFFFFFFFFFFFFFFFFULL
25951 +
25952 +#define CRC64_BYTE_MASK 0xFF
25953 +#define CRC64_TABLE_ENTRIES ( 1 << BITS_PER_BYTE )
25954 +#define CRC64_ODD_MASK 1
25955 +
25956 +
25957 +/**
25958 + \brief '64 bit crc' Table
25959 + */
25960 +struct crc64_t {
25961 + uint64_t initial; /**< Initial seed */
25962 + uint64_t table[CRC64_TABLE_ENTRIES]; /**< CRC table entries */
25963 +};
25964 +
25965 +
25966 +static struct crc64_t CRC64_ECMA_182 = {
25967 + CRC64_DEFAULT_INITVAL,
25968 + {
25969 + 0x0000000000000000ULL,
25970 + 0xb32e4cbe03a75f6fULL,
25971 + 0xf4843657a840a05bULL,
25972 + 0x47aa7ae9abe7ff34ULL,
25973 + 0x7bd0c384ff8f5e33ULL,
25974 + 0xc8fe8f3afc28015cULL,
25975 + 0x8f54f5d357cffe68ULL,
25976 + 0x3c7ab96d5468a107ULL,
25977 + 0xf7a18709ff1ebc66ULL,
25978 + 0x448fcbb7fcb9e309ULL,
25979 + 0x0325b15e575e1c3dULL,
25980 + 0xb00bfde054f94352ULL,
25981 + 0x8c71448d0091e255ULL,
25982 + 0x3f5f08330336bd3aULL,
25983 + 0x78f572daa8d1420eULL,
25984 + 0xcbdb3e64ab761d61ULL,
25985 + 0x7d9ba13851336649ULL,
25986 + 0xceb5ed8652943926ULL,
25987 + 0x891f976ff973c612ULL,
25988 + 0x3a31dbd1fad4997dULL,
25989 + 0x064b62bcaebc387aULL,
25990 + 0xb5652e02ad1b6715ULL,
25991 + 0xf2cf54eb06fc9821ULL,
25992 + 0x41e11855055bc74eULL,
25993 + 0x8a3a2631ae2dda2fULL,
25994 + 0x39146a8fad8a8540ULL,
25995 + 0x7ebe1066066d7a74ULL,
25996 + 0xcd905cd805ca251bULL,
25997 + 0xf1eae5b551a2841cULL,
25998 + 0x42c4a90b5205db73ULL,
25999 + 0x056ed3e2f9e22447ULL,
26000 + 0xb6409f5cfa457b28ULL,
26001 + 0xfb374270a266cc92ULL,
26002 + 0x48190ecea1c193fdULL,
26003 + 0x0fb374270a266cc9ULL,
26004 + 0xbc9d3899098133a6ULL,
26005 + 0x80e781f45de992a1ULL,
26006 + 0x33c9cd4a5e4ecdceULL,
26007 + 0x7463b7a3f5a932faULL,
26008 + 0xc74dfb1df60e6d95ULL,
26009 + 0x0c96c5795d7870f4ULL,
26010 + 0xbfb889c75edf2f9bULL,
26011 + 0xf812f32ef538d0afULL,
26012 + 0x4b3cbf90f69f8fc0ULL,
26013 + 0x774606fda2f72ec7ULL,
26014 + 0xc4684a43a15071a8ULL,
26015 + 0x83c230aa0ab78e9cULL,
26016 + 0x30ec7c140910d1f3ULL,
26017 + 0x86ace348f355aadbULL,
26018 + 0x3582aff6f0f2f5b4ULL,
26019 + 0x7228d51f5b150a80ULL,
26020 + 0xc10699a158b255efULL,
26021 + 0xfd7c20cc0cdaf4e8ULL,
26022 + 0x4e526c720f7dab87ULL,
26023 + 0x09f8169ba49a54b3ULL,
26024 + 0xbad65a25a73d0bdcULL,
26025 + 0x710d64410c4b16bdULL,
26026 + 0xc22328ff0fec49d2ULL,
26027 + 0x85895216a40bb6e6ULL,
26028 + 0x36a71ea8a7ace989ULL,
26029 + 0x0adda7c5f3c4488eULL,
26030 + 0xb9f3eb7bf06317e1ULL,
26031 + 0xfe5991925b84e8d5ULL,
26032 + 0x4d77dd2c5823b7baULL,
26033 + 0x64b62bcaebc387a1ULL,
26034 + 0xd7986774e864d8ceULL,
26035 + 0x90321d9d438327faULL,
26036 + 0x231c512340247895ULL,
26037 + 0x1f66e84e144cd992ULL,
26038 + 0xac48a4f017eb86fdULL,
26039 + 0xebe2de19bc0c79c9ULL,
26040 + 0x58cc92a7bfab26a6ULL,
26041 + 0x9317acc314dd3bc7ULL,
26042 + 0x2039e07d177a64a8ULL,
26043 + 0x67939a94bc9d9b9cULL,
26044 + 0xd4bdd62abf3ac4f3ULL,
26045 + 0xe8c76f47eb5265f4ULL,
26046 + 0x5be923f9e8f53a9bULL,
26047 + 0x1c4359104312c5afULL,
26048 + 0xaf6d15ae40b59ac0ULL,
26049 + 0x192d8af2baf0e1e8ULL,
26050 + 0xaa03c64cb957be87ULL,
26051 + 0xeda9bca512b041b3ULL,
26052 + 0x5e87f01b11171edcULL,
26053 + 0x62fd4976457fbfdbULL,
26054 + 0xd1d305c846d8e0b4ULL,
26055 + 0x96797f21ed3f1f80ULL,
26056 + 0x2557339fee9840efULL,
26057 + 0xee8c0dfb45ee5d8eULL,
26058 + 0x5da24145464902e1ULL,
26059 + 0x1a083bacedaefdd5ULL,
26060 + 0xa9267712ee09a2baULL,
26061 + 0x955cce7fba6103bdULL,
26062 + 0x267282c1b9c65cd2ULL,
26063 + 0x61d8f8281221a3e6ULL,
26064 + 0xd2f6b4961186fc89ULL,
26065 + 0x9f8169ba49a54b33ULL,
26066 + 0x2caf25044a02145cULL,
26067 + 0x6b055fede1e5eb68ULL,
26068 + 0xd82b1353e242b407ULL,
26069 + 0xe451aa3eb62a1500ULL,
26070 + 0x577fe680b58d4a6fULL,
26071 + 0x10d59c691e6ab55bULL,
26072 + 0xa3fbd0d71dcdea34ULL,
26073 + 0x6820eeb3b6bbf755ULL,
26074 + 0xdb0ea20db51ca83aULL,
26075 + 0x9ca4d8e41efb570eULL,
26076 + 0x2f8a945a1d5c0861ULL,
26077 + 0x13f02d374934a966ULL,
26078 + 0xa0de61894a93f609ULL,
26079 + 0xe7741b60e174093dULL,
26080 + 0x545a57dee2d35652ULL,
26081 + 0xe21ac88218962d7aULL,
26082 + 0x5134843c1b317215ULL,
26083 + 0x169efed5b0d68d21ULL,
26084 + 0xa5b0b26bb371d24eULL,
26085 + 0x99ca0b06e7197349ULL,
26086 + 0x2ae447b8e4be2c26ULL,
26087 + 0x6d4e3d514f59d312ULL,
26088 + 0xde6071ef4cfe8c7dULL,
26089 + 0x15bb4f8be788911cULL,
26090 + 0xa6950335e42fce73ULL,
26091 + 0xe13f79dc4fc83147ULL,
26092 + 0x521135624c6f6e28ULL,
26093 + 0x6e6b8c0f1807cf2fULL,
26094 + 0xdd45c0b11ba09040ULL,
26095 + 0x9aefba58b0476f74ULL,
26096 + 0x29c1f6e6b3e0301bULL,
26097 + 0xc96c5795d7870f42ULL,
26098 + 0x7a421b2bd420502dULL,
26099 + 0x3de861c27fc7af19ULL,
26100 + 0x8ec62d7c7c60f076ULL,
26101 + 0xb2bc941128085171ULL,
26102 + 0x0192d8af2baf0e1eULL,
26103 + 0x4638a2468048f12aULL,
26104 + 0xf516eef883efae45ULL,
26105 + 0x3ecdd09c2899b324ULL,
26106 + 0x8de39c222b3eec4bULL,
26107 + 0xca49e6cb80d9137fULL,
26108 + 0x7967aa75837e4c10ULL,
26109 + 0x451d1318d716ed17ULL,
26110 + 0xf6335fa6d4b1b278ULL,
26111 + 0xb199254f7f564d4cULL,
26112 + 0x02b769f17cf11223ULL,
26113 + 0xb4f7f6ad86b4690bULL,
26114 + 0x07d9ba1385133664ULL,
26115 + 0x4073c0fa2ef4c950ULL,
26116 + 0xf35d8c442d53963fULL,
26117 + 0xcf273529793b3738ULL,
26118 + 0x7c0979977a9c6857ULL,
26119 + 0x3ba3037ed17b9763ULL,
26120 + 0x888d4fc0d2dcc80cULL,
26121 + 0x435671a479aad56dULL,
26122 + 0xf0783d1a7a0d8a02ULL,
26123 + 0xb7d247f3d1ea7536ULL,
26124 + 0x04fc0b4dd24d2a59ULL,
26125 + 0x3886b22086258b5eULL,
26126 + 0x8ba8fe9e8582d431ULL,
26127 + 0xcc0284772e652b05ULL,
26128 + 0x7f2cc8c92dc2746aULL,
26129 + 0x325b15e575e1c3d0ULL,
26130 + 0x8175595b76469cbfULL,
26131 + 0xc6df23b2dda1638bULL,
26132 + 0x75f16f0cde063ce4ULL,
26133 + 0x498bd6618a6e9de3ULL,
26134 + 0xfaa59adf89c9c28cULL,
26135 + 0xbd0fe036222e3db8ULL,
26136 + 0x0e21ac88218962d7ULL,
26137 + 0xc5fa92ec8aff7fb6ULL,
26138 + 0x76d4de52895820d9ULL,
26139 + 0x317ea4bb22bfdfedULL,
26140 + 0x8250e80521188082ULL,
26141 + 0xbe2a516875702185ULL,
26142 + 0x0d041dd676d77eeaULL,
26143 + 0x4aae673fdd3081deULL,
26144 + 0xf9802b81de97deb1ULL,
26145 + 0x4fc0b4dd24d2a599ULL,
26146 + 0xfceef8632775faf6ULL,
26147 + 0xbb44828a8c9205c2ULL,
26148 + 0x086ace348f355aadULL,
26149 + 0x34107759db5dfbaaULL,
26150 + 0x873e3be7d8faa4c5ULL,
26151 + 0xc094410e731d5bf1ULL,
26152 + 0x73ba0db070ba049eULL,
26153 + 0xb86133d4dbcc19ffULL,
26154 + 0x0b4f7f6ad86b4690ULL,
26155 + 0x4ce50583738cb9a4ULL,
26156 + 0xffcb493d702be6cbULL,
26157 + 0xc3b1f050244347ccULL,
26158 + 0x709fbcee27e418a3ULL,
26159 + 0x3735c6078c03e797ULL,
26160 + 0x841b8ab98fa4b8f8ULL,
26161 + 0xadda7c5f3c4488e3ULL,
26162 + 0x1ef430e13fe3d78cULL,
26163 + 0x595e4a08940428b8ULL,
26164 + 0xea7006b697a377d7ULL,
26165 + 0xd60abfdbc3cbd6d0ULL,
26166 + 0x6524f365c06c89bfULL,
26167 + 0x228e898c6b8b768bULL,
26168 + 0x91a0c532682c29e4ULL,
26169 + 0x5a7bfb56c35a3485ULL,
26170 + 0xe955b7e8c0fd6beaULL,
26171 + 0xaeffcd016b1a94deULL,
26172 + 0x1dd181bf68bdcbb1ULL,
26173 + 0x21ab38d23cd56ab6ULL,
26174 + 0x9285746c3f7235d9ULL,
26175 + 0xd52f0e859495caedULL,
26176 + 0x6601423b97329582ULL,
26177 + 0xd041dd676d77eeaaULL,
26178 + 0x636f91d96ed0b1c5ULL,
26179 + 0x24c5eb30c5374ef1ULL,
26180 + 0x97eba78ec690119eULL,
26181 + 0xab911ee392f8b099ULL,
26182 + 0x18bf525d915feff6ULL,
26183 + 0x5f1528b43ab810c2ULL,
26184 + 0xec3b640a391f4fadULL,
26185 + 0x27e05a6e926952ccULL,
26186 + 0x94ce16d091ce0da3ULL,
26187 + 0xd3646c393a29f297ULL,
26188 + 0x604a2087398eadf8ULL,
26189 + 0x5c3099ea6de60cffULL,
26190 + 0xef1ed5546e415390ULL,
26191 + 0xa8b4afbdc5a6aca4ULL,
26192 + 0x1b9ae303c601f3cbULL,
26193 + 0x56ed3e2f9e224471ULL,
26194 + 0xe5c372919d851b1eULL,
26195 + 0xa26908783662e42aULL,
26196 + 0x114744c635c5bb45ULL,
26197 + 0x2d3dfdab61ad1a42ULL,
26198 + 0x9e13b115620a452dULL,
26199 + 0xd9b9cbfcc9edba19ULL,
26200 + 0x6a978742ca4ae576ULL,
26201 + 0xa14cb926613cf817ULL,
26202 + 0x1262f598629ba778ULL,
26203 + 0x55c88f71c97c584cULL,
26204 + 0xe6e6c3cfcadb0723ULL,
26205 + 0xda9c7aa29eb3a624ULL,
26206 + 0x69b2361c9d14f94bULL,
26207 + 0x2e184cf536f3067fULL,
26208 + 0x9d36004b35545910ULL,
26209 + 0x2b769f17cf112238ULL,
26210 + 0x9858d3a9ccb67d57ULL,
26211 + 0xdff2a94067518263ULL,
26212 + 0x6cdce5fe64f6dd0cULL,
26213 + 0x50a65c93309e7c0bULL,
26214 + 0xe388102d33392364ULL,
26215 + 0xa4226ac498dedc50ULL,
26216 + 0x170c267a9b79833fULL,
26217 + 0xdcd7181e300f9e5eULL,
26218 + 0x6ff954a033a8c131ULL,
26219 + 0x28532e49984f3e05ULL,
26220 + 0x9b7d62f79be8616aULL,
26221 + 0xa707db9acf80c06dULL,
26222 + 0x14299724cc279f02ULL,
26223 + 0x5383edcd67c06036ULL,
26224 + 0xe0ada17364673f59ULL
26225 + }
26226 +};
26227 +
26228 +
26229 +/**
26230 + \brief Initializes the crc seed
26231 + */
26232 +static __inline__ uint64_t crc64_init(void)
26233 +{
26234 + return CRC64_ECMA_182.initial;
26235 +}
26236 +
26237 +/**
26238 + \brief Computes 64 bit the crc
26239 + \param[in] data Pointer to the Data in the frame
26240 + \param[in] len Length of the Data
26241 + \param[in] crc seed
26242 + \return calculated crc
26243 + */
26244 +static __inline__ uint64_t crc64_compute(void const *data,
26245 + uint32_t len,
26246 + uint64_t seed)
26247 +{
26248 + uint32_t i;
26249 + uint64_t crc = seed;
26250 + uint8_t *bdata = (uint8_t *) data;
26251 +
26252 + for (i = 0; i < len; i++)
26253 + crc =
26254 + CRC64_ECMA_182.
26255 + table[(crc ^ *bdata++) & CRC64_BYTE_MASK] ^ (crc >> 8);
26256 +
26257 + return crc;
26258 +}
26259 +
26260 +
26261 +#endif /* __CRC64_H */
26262 --- /dev/null
26263 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
26264 @@ -0,0 +1,7582 @@
26265 +/*
26266 + * Copyright 2008-2012 Freescale Semiconductor Inc.
26267 + *
26268 + * Redistribution and use in source and binary forms, with or without
26269 + * modification, are permitted provided that the following conditions are met:
26270 + * * Redistributions of source code must retain the above copyright
26271 + * notice, this list of conditions and the following disclaimer.
26272 + * * Redistributions in binary form must reproduce the above copyright
26273 + * notice, this list of conditions and the following disclaimer in the
26274 + * documentation and/or other materials provided with the distribution.
26275 + * * Neither the name of Freescale Semiconductor nor the
26276 + * names of its contributors may be used to endorse or promote products
26277 + * derived from this software without specific prior written permission.
26278 + *
26279 + *
26280 + * ALTERNATIVELY, this software may be distributed under the terms of the
26281 + * GNU General Public License ("GPL") as published by the Free Software
26282 + * Foundation, either version 2 of that License or (at your option) any
26283 + * later version.
26284 + *
26285 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26286 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26287 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26288 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
26289 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26290 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26291 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26292 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26293 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26294 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26295 + */
26296 +
26297 +
26298 +/******************************************************************************
26299 + @File fm_cc.c
26300 +
26301 + @Description FM Coarse Classifier implementation
26302 + *//***************************************************************************/
26303 +#include <linux/math64.h>
26304 +#include "std_ext.h"
26305 +#include "error_ext.h"
26306 +#include "string_ext.h"
26307 +#include "debug_ext.h"
26308 +#include "fm_pcd_ext.h"
26309 +#include "fm_muram_ext.h"
26310 +
26311 +#include "fm_common.h"
26312 +#include "fm_pcd.h"
26313 +#include "fm_hc.h"
26314 +#include "fm_cc.h"
26315 +#include "crc64.h"
26316 +
26317 +/****************************************/
26318 +/* static functions */
26319 +/****************************************/
26320 +
26321 +
26322 +static t_Error CcRootTryLock(t_Handle h_FmPcdCcTree)
26323 +{
26324 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26325 +
26326 + ASSERT_COND(h_FmPcdCcTree);
26327 +
26328 + if (FmPcdLockTryLock(p_FmPcdCcTree->p_Lock))
26329 + return E_OK;
26330 +
26331 + return ERROR_CODE(E_BUSY);
26332 +}
26333 +
26334 +static void CcRootReleaseLock(t_Handle h_FmPcdCcTree)
26335 +{
26336 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26337 +
26338 + ASSERT_COND(h_FmPcdCcTree);
26339 +
26340 + FmPcdLockUnlock(p_FmPcdCcTree->p_Lock);
26341 +}
26342 +
26343 +static void UpdateNodeOwner(t_FmPcdCcNode *p_CcNode, bool add)
26344 +{
26345 + uint32_t intFlags;
26346 +
26347 + ASSERT_COND(p_CcNode);
26348 +
26349 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26350 +
26351 + if (add)
26352 + p_CcNode->owners++;
26353 + else
26354 + {
26355 + ASSERT_COND(p_CcNode->owners);
26356 + p_CcNode->owners--;
26357 + }
26358 +
26359 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26360 +}
26361 +
26362 +static __inline__ t_FmPcdStatsObj* DequeueStatsObj(t_List *p_List)
26363 +{
26364 + t_FmPcdStatsObj *p_StatsObj = NULL;
26365 + t_List *p_Next;
26366 +
26367 + if (!LIST_IsEmpty(p_List))
26368 + {
26369 + p_Next = LIST_FIRST(p_List);
26370 + p_StatsObj = LIST_OBJECT(p_Next, t_FmPcdStatsObj, node);
26371 + ASSERT_COND(p_StatsObj);
26372 + LIST_DelAndInit(p_Next);
26373 + }
26374 +
26375 + return p_StatsObj;
26376 +}
26377 +
26378 +static __inline__ void EnqueueStatsObj(t_List *p_List,
26379 + t_FmPcdStatsObj *p_StatsObj)
26380 +{
26381 + LIST_AddToTail(&p_StatsObj->node, p_List);
26382 +}
26383 +
26384 +static void FreeStatObjects(t_List *p_List, t_Handle h_FmMuram)
26385 +{
26386 + t_FmPcdStatsObj *p_StatsObj;
26387 +
26388 + while (!LIST_IsEmpty(p_List))
26389 + {
26390 + p_StatsObj = DequeueStatsObj(p_List);
26391 + ASSERT_COND(p_StatsObj);
26392 +
26393 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26394 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26395 +
26396 + XX_Free(p_StatsObj);
26397 + }
26398 +}
26399 +
26400 +static t_FmPcdStatsObj* GetStatsObj(t_FmPcdCcNode *p_CcNode)
26401 +{
26402 + t_FmPcdStatsObj* p_StatsObj;
26403 + t_Handle h_FmMuram;
26404 +
26405 + ASSERT_COND(p_CcNode);
26406 +
26407 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26408 + upon node initialization */
26409 + if (p_CcNode->maxNumOfKeys)
26410 + {
26411 + p_StatsObj = DequeueStatsObj(&p_CcNode->availableStatsLst);
26412 +
26413 + /* Clean statistics counters & ADs */
26414 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26415 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26416 + }
26417 + else
26418 + {
26419 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26420 + ASSERT_COND(h_FmMuram);
26421 +
26422 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
26423 + if (!p_StatsObj)
26424 + {
26425 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("statistics object"));
26426 + return NULL;
26427 + }
26428 +
26429 + p_StatsObj->h_StatsAd = (t_Handle)FM_MURAM_AllocMem(
26430 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26431 + if (!p_StatsObj->h_StatsAd)
26432 + {
26433 + XX_Free(p_StatsObj);
26434 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics ADs"));
26435 + return NULL;
26436 + }
26437 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26438 +
26439 + p_StatsObj->h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
26440 + h_FmMuram, p_CcNode->countersArraySize,
26441 + FM_PCD_CC_AD_TABLE_ALIGN);
26442 + if (!p_StatsObj->h_StatsCounters)
26443 + {
26444 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26445 + XX_Free(p_StatsObj);
26446 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics counters"));
26447 + return NULL;
26448 + }
26449 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26450 + }
26451 +
26452 + return p_StatsObj;
26453 +}
26454 +
26455 +static void PutStatsObj(t_FmPcdCcNode *p_CcNode, t_FmPcdStatsObj *p_StatsObj)
26456 +{
26457 + t_Handle h_FmMuram;
26458 +
26459 + ASSERT_COND(p_CcNode);
26460 + ASSERT_COND(p_StatsObj);
26461 +
26462 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26463 + upon node initialization and now will be enqueued back to the list */
26464 + if (p_CcNode->maxNumOfKeys)
26465 + {
26466 + /* Clean statistics counters */
26467 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26468 +
26469 + /* Clean statistics ADs */
26470 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26471 +
26472 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
26473 + }
26474 + else
26475 + {
26476 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26477 + ASSERT_COND(h_FmMuram);
26478 +
26479 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26480 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26481 +
26482 + XX_Free(p_StatsObj);
26483 + }
26484 +}
26485 +
26486 +static void SetStatsCounters(t_AdOfTypeStats *p_StatsAd,
26487 + uint32_t statsCountersAddr)
26488 +{
26489 + uint32_t tmp = (statsCountersAddr & FM_PCD_AD_STATS_COUNTERS_ADDR_MASK);
26490 +
26491 + WRITE_UINT32(p_StatsAd->statsTableAddr, tmp);
26492 +}
26493 +
26494 +
26495 +static void UpdateStatsAd(t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26496 + t_Handle h_Ad, uint64_t physicalMuramBase)
26497 +{
26498 + t_AdOfTypeStats *p_StatsAd;
26499 + uint32_t statsCountersAddr, nextActionAddr, tmp;
26500 +#if (DPAA_VERSION >= 11)
26501 + uint32_t frameLengthRangesAddr;
26502 +#endif /* (DPAA_VERSION >= 11) */
26503 +
26504 + p_StatsAd = (t_AdOfTypeStats *)p_FmPcdCcStatsParams->h_StatsAd;
26505 +
26506 + tmp = FM_PCD_AD_STATS_TYPE;
26507 +
26508 +#if (DPAA_VERSION >= 11)
26509 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26510 + {
26511 + frameLengthRangesAddr = (uint32_t)((XX_VirtToPhys(
26512 + p_FmPcdCcStatsParams->h_StatsFLRs) - physicalMuramBase));
26513 + tmp |= (frameLengthRangesAddr & FM_PCD_AD_STATS_FLR_ADDR_MASK);
26514 + }
26515 +#endif /* (DPAA_VERSION >= 11) */
26516 + WRITE_UINT32(p_StatsAd->profileTableAddr, tmp);
26517 +
26518 + nextActionAddr = (uint32_t)((XX_VirtToPhys(h_Ad) - physicalMuramBase));
26519 + tmp = 0;
26520 + tmp |= (uint32_t)((nextActionAddr << FM_PCD_AD_STATS_NEXT_ACTION_SHIFT)
26521 + & FM_PCD_AD_STATS_NEXT_ACTION_MASK);
26522 + tmp |= (FM_PCD_AD_STATS_NAD_EN | FM_PCD_AD_STATS_OP_CODE);
26523 +
26524 +#if (DPAA_VERSION >= 11)
26525 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26526 + tmp |= FM_PCD_AD_STATS_FLR_EN;
26527 +#endif /* (DPAA_VERSION >= 11) */
26528 +
26529 + WRITE_UINT32(p_StatsAd->nextActionIndx, tmp);
26530 +
26531 + statsCountersAddr = (uint32_t)((XX_VirtToPhys(
26532 + p_FmPcdCcStatsParams->h_StatsCounters) - physicalMuramBase));
26533 + SetStatsCounters(p_StatsAd, statsCountersAddr);
26534 +}
26535 +
26536 +static void FillAdOfTypeContLookup(t_Handle h_Ad,
26537 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26538 + t_Handle h_FmPcd, t_Handle p_CcNode,
26539 + t_Handle h_Manip, t_Handle h_FrmReplic)
26540 +{
26541 + t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_CcNode;
26542 + t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad;
26543 + t_Handle h_TmpAd;
26544 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
26545 + uint32_t tmpReg32;
26546 + t_Handle p_AdNewPtr = NULL;
26547 +
26548 + UNUSED(h_Manip);
26549 + UNUSED(h_FrmReplic);
26550 +
26551 + /* there are 3 cases handled in this routine of building a "Continue lookup" type AD.
26552 + * Case 1: No Manip. The action descriptor is built within the match table.
26553 + * p_AdResult = p_AdNewPtr;
26554 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
26555 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
26556 + * initialized and returned here.
26557 + * p_AdResult (within the match table) will be initialized after
26558 + * this routine returns and point to the existing AD.
26559 + * Case 3: Manip exists. The action descriptor is built within the match table.
26560 + * FmPcdManipUpdateAdContLookupForCc returns a NULL p_AdNewPtr.
26561 + */
26562 +
26563 + /* As default, the "new" ptr is the current one. i.e. the content of the result
26564 + * AD will be written into the match table itself (case (1))*/
26565 + p_AdNewPtr = p_AdContLookup;
26566 +
26567 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
26568 + if (p_FmPcdCcStatsParams)
26569 + {
26570 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
26571 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
26572 +
26573 + /* Swapping addresses between statistics Ad and the current lookup AD */
26574 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
26575 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
26576 + h_Ad = h_TmpAd;
26577 +
26578 + p_AdNewPtr = h_Ad;
26579 + p_AdContLookup = h_Ad;
26580 +
26581 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
26582 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
26583 + }
26584 +
26585 +#if DPAA_VERSION >= 11
26586 + if (h_Manip && h_FrmReplic)
26587 + FmPcdManipUpdateAdContLookupForCc(
26588 + h_Manip,
26589 + h_Ad,
26590 + &p_AdNewPtr,
26591 + (uint32_t)((XX_VirtToPhys(
26592 + FrmReplicGroupGetSourceTableDescriptor(h_FrmReplic))
26593 + - p_FmPcd->physicalMuramBase)));
26594 + else
26595 + if (h_FrmReplic)
26596 + FrmReplicGroupUpdateAd(h_FrmReplic, h_Ad, &p_AdNewPtr);
26597 + else
26598 +#endif /* (DPAA_VERSION >= 11) */
26599 + if (h_Manip)
26600 + FmPcdManipUpdateAdContLookupForCc(
26601 + h_Manip,
26602 + h_Ad,
26603 + &p_AdNewPtr,
26604 +
26605 +#ifdef FM_CAPWAP_SUPPORT
26606 + /*no check for opcode of manip - this step can be reached only with capwap_applic_specific*/
26607 + (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase))
26608 +#else /* not FM_CAPWAP_SUPPORT */
26609 + (uint32_t)((XX_VirtToPhys(p_Node->h_Ad)
26610 + - p_FmPcd->physicalMuramBase))
26611 +#endif /* not FM_CAPWAP_SUPPORT */
26612 + );
26613 +
26614 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
26615 + if (p_AdNewPtr)
26616 + {
26617 + /* cases (1) & (2) */
26618 + tmpReg32 = 0;
26619 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
26620 + tmpReg32 |=
26621 + p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) :
26622 + 0;
26623 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable)
26624 + - p_FmPcd->physicalMuramBase);
26625 + WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32);
26626 +
26627 + tmpReg32 = 0;
26628 + tmpReg32 |= p_Node->numOfKeys << 24;
26629 + tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0);
26630 + tmpReg32 |=
26631 + p_Node->h_KeysMatchTable ? (uint32_t)(XX_VirtToPhys(
26632 + p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) :
26633 + 0;
26634 + WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32);
26635 +
26636 + tmpReg32 = 0;
26637 + tmpReg32 |= p_Node->prsArrayOffset << 24;
26638 + tmpReg32 |= p_Node->offset << 16;
26639 + tmpReg32 |= p_Node->parseCode;
26640 + WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32);
26641 +
26642 + MemCpy8((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask,
26643 + CC_GLBL_MASK_SIZE);
26644 + }
26645 +}
26646 +
26647 +static t_Error AllocAndFillAdForContLookupManip(t_Handle h_CcNode)
26648 +{
26649 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
26650 + uint32_t intFlags;
26651 +
26652 + ASSERT_COND(p_CcNode);
26653 +
26654 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26655 +
26656 + if (!p_CcNode->h_Ad)
26657 + {
26658 + if (p_CcNode->maxNumOfKeys)
26659 + p_CcNode->h_Ad = p_CcNode->h_TmpAd;
26660 + else
26661 + p_CcNode->h_Ad = (t_Handle)FM_MURAM_AllocMem(
26662 + ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram,
26663 + FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26664 +
26665 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26666 +
26667 + if (!p_CcNode->h_Ad)
26668 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
26669 + ("MURAM allocation for CC action descriptor"));
26670 +
26671 + MemSet8(p_CcNode->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26672 +
26673 + FillAdOfTypeContLookup(p_CcNode->h_Ad, NULL, p_CcNode->h_FmPcd,
26674 + p_CcNode, NULL, NULL);
26675 + }
26676 + else
26677 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26678 +
26679 + return E_OK;
26680 +}
26681 +
26682 +static t_Error SetRequiredAction1(
26683 + t_Handle h_FmPcd, uint32_t requiredAction,
26684 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
26685 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
26686 +{
26687 + t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp;
26688 + uint32_t tmpReg32;
26689 + t_Error err;
26690 + t_FmPcdCcNode *p_CcNode;
26691 + int i = 0;
26692 + uint16_t tmp = 0;
26693 + uint16_t profileId;
26694 + uint8_t relativeSchemeId, physicalSchemeId;
26695 + t_CcNodeInformation ccNodeInfo;
26696 +
26697 + for (i = 0; i < numOfEntries; i++)
26698 + {
26699 + if (i == 0)
26700 + h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE);
26701 + else
26702 + h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE);
26703 +
26704 + switch (p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.nextEngine)
26705 + {
26706 + case (e_FM_PCD_CC):
26707 + if (requiredAction)
26708 + {
26709 + p_CcNode =
26710 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode;
26711 + ASSERT_COND(p_CcNode);
26712 + if (p_CcNode->shadowAction == requiredAction)
26713 + break;
26714 + if ((requiredAction & UPDATE_CC_WITH_TREE)
26715 + && !(p_CcNode->shadowAction & UPDATE_CC_WITH_TREE))
26716 + {
26717 +
26718 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26719 + ccNodeInfo.h_CcNode = h_Tree;
26720 + EnqueueNodeInfoToRelevantLst(&p_CcNode->ccTreesLst,
26721 + &ccNodeInfo, NULL);
26722 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26723 + UPDATE_CC_WITH_TREE;
26724 + }
26725 + if ((requiredAction & UPDATE_CC_SHADOW_CLEAR)
26726 + && !(p_CcNode->shadowAction & UPDATE_CC_SHADOW_CLEAR))
26727 + {
26728 +
26729 + p_CcNode->shadowAction = 0;
26730 + }
26731 +
26732 + if ((requiredAction & UPDATE_CC_WITH_DELETE_TREE)
26733 + && !(p_CcNode->shadowAction
26734 + & UPDATE_CC_WITH_DELETE_TREE))
26735 + {
26736 + DequeueNodeInfoFromRelevantLst(&p_CcNode->ccTreesLst,
26737 + h_Tree, NULL);
26738 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26739 + UPDATE_CC_WITH_DELETE_TREE;
26740 + }
26741 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
26742 + != e_FM_PCD_INVALID)
26743 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
26744 + else
26745 + tmp = p_CcNode->numOfKeys;
26746 + err = SetRequiredAction1(h_FmPcd, requiredAction,
26747 + p_CcNode->keyAndNextEngineParams,
26748 + p_CcNode->h_AdTable, tmp, h_Tree);
26749 + if (err != E_OK)
26750 + return err;
26751 + if (requiredAction != UPDATE_CC_SHADOW_CLEAR)
26752 + p_CcNode->shadowAction |= requiredAction;
26753 + }
26754 + break;
26755 +
26756 + case (e_FM_PCD_KG):
26757 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26758 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26759 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26760 + {
26761 + physicalSchemeId =
26762 + FmPcdKgGetSchemeId(
26763 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme);
26764 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(
26765 + h_FmPcd, physicalSchemeId);
26766 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
26767 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
26768 + if (!FmPcdKgIsSchemeValidSw(
26769 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme))
26770 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
26771 + ("Invalid direct scheme."));
26772 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
26773 + RETURN_ERROR(
26774 + MAJOR, E_INVALID_STATE,
26775 + ("For this action scheme has to be direct."));
26776 + err =
26777 + FmPcdKgCcGetSetParams(
26778 + h_FmPcd,
26779 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme,
26780 + requiredAction, 0);
26781 + if (err != E_OK)
26782 + RETURN_ERROR(MAJOR, err, NO_MSG);
26783 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26784 + requiredAction;
26785 + }
26786 + break;
26787 +
26788 + case (e_FM_PCD_PLCR):
26789 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26790 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26791 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26792 + {
26793 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams)
26794 + RETURN_ERROR(
26795 + MAJOR,
26796 + E_NOT_SUPPORTED,
26797 + ("In this initialization only overrideFqid can be initialized"));
26798 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile)
26799 + RETURN_ERROR(
26800 + MAJOR,
26801 + E_NOT_SUPPORTED,
26802 + ("In this initialization only overrideFqid can be initialized"));
26803 + err =
26804 + FmPcdPlcrGetAbsoluteIdByProfileParams(
26805 + h_FmPcd,
26806 + e_FM_PCD_PLCR_SHARED,
26807 + NULL,
26808 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId,
26809 + &profileId);
26810 + if (err != E_OK)
26811 + RETURN_ERROR(MAJOR, err, NO_MSG);
26812 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId,
26813 + requiredAction);
26814 + if (err != E_OK)
26815 + RETURN_ERROR(MAJOR, err, NO_MSG);
26816 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26817 + requiredAction;
26818 + }
26819 + break;
26820 +
26821 + case (e_FM_PCD_DONE):
26822 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26823 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26824 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26825 + {
26826 + tmpReg32 = GET_UINT32(p_AdTmp->nia);
26827 + if ((tmpReg32 & GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
26828 + != GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
26829 + RETURN_ERROR(
26830 + MAJOR,
26831 + E_INVALID_STATE,
26832 + ("Next engine was previously assigned not as PCD_DONE"));
26833 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
26834 + WRITE_UINT32(p_AdTmp->nia, tmpReg32);
26835 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26836 + requiredAction;
26837 + }
26838 + break;
26839 +
26840 + default:
26841 + break;
26842 + }
26843 + }
26844 +
26845 + return E_OK;
26846 +}
26847 +
26848 +static t_Error SetRequiredAction(
26849 + t_Handle h_FmPcd, uint32_t requiredAction,
26850 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
26851 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
26852 +{
26853 + t_Error err = SetRequiredAction1(h_FmPcd, requiredAction,
26854 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
26855 + numOfEntries, h_Tree);
26856 + if (err != E_OK)
26857 + return err;
26858 + return SetRequiredAction1(h_FmPcd, UPDATE_CC_SHADOW_CLEAR,
26859 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
26860 + numOfEntries, h_Tree);
26861 +}
26862 +
26863 +static t_Error ReleaseModifiedDataStructure(
26864 + t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst,
26865 + t_List *h_FmPcdNewPointersLst,
26866 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
26867 + bool useShadowStructs)
26868 +{
26869 + t_List *p_Pos;
26870 + t_Error err = E_OK;
26871 + t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation;
26872 + t_Handle h_Muram;
26873 + t_FmPcdCcNode *p_FmPcdCcNextNode, *p_FmPcdCcWorkingOnNode;
26874 + t_List *p_UpdateLst;
26875 + uint32_t intFlags;
26876 +
26877 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
26878 + SANITY_CHECK_RETURN_ERROR(p_AdditionalParams->h_CurrentNode,
26879 + E_INVALID_HANDLE);
26880 + SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst, E_INVALID_HANDLE);
26881 + SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst, E_INVALID_HANDLE);
26882 +
26883 + /* We don't update subtree of the new node with new tree because it was done in the previous stage */
26884 + if (p_AdditionalParams->h_NodeForAdd)
26885 + {
26886 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForAdd;
26887 +
26888 + if (!p_AdditionalParams->tree)
26889 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
26890 + else
26891 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
26892 +
26893 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26894 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
26895 + p_FmPcdCcNextNode->h_Spinlock);
26896 +
26897 + if (p_CcNodeInformation)
26898 + p_CcNodeInformation->index++;
26899 + else
26900 + {
26901 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26902 + ccNodeInfo.h_CcNode = (t_Handle)p_AdditionalParams->h_CurrentNode;
26903 + ccNodeInfo.index = 1;
26904 + EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo,
26905 + p_FmPcdCcNextNode->h_Spinlock);
26906 + }
26907 + if (p_AdditionalParams->h_ManipForAdd)
26908 + {
26909 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26910 + FmPcdManipGetNodeLstPointedOnThisManip(
26911 + p_AdditionalParams->h_ManipForAdd),
26912 + p_AdditionalParams->h_CurrentNode,
26913 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForAdd));
26914 +
26915 + if (p_CcNodeInformation)
26916 + p_CcNodeInformation->index++;
26917 + else
26918 + {
26919 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26920 + ccNodeInfo.h_CcNode =
26921 + (t_Handle)p_AdditionalParams->h_CurrentNode;
26922 + ccNodeInfo.index = 1;
26923 + EnqueueNodeInfoToRelevantLst(
26924 + FmPcdManipGetNodeLstPointedOnThisManip(
26925 + p_AdditionalParams->h_ManipForAdd),
26926 + &ccNodeInfo,
26927 + FmPcdManipGetSpinlock(
26928 + p_AdditionalParams->h_ManipForAdd));
26929 + }
26930 + }
26931 + }
26932 +
26933 + if (p_AdditionalParams->h_NodeForRmv)
26934 + {
26935 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForRmv;
26936 +
26937 + if (!p_AdditionalParams->tree)
26938 + {
26939 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
26940 + p_FmPcdCcWorkingOnNode =
26941 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
26942 +
26943 + for (p_Pos = LIST_FIRST(&p_FmPcdCcWorkingOnNode->ccTreesLst);
26944 + p_Pos != (&p_FmPcdCcWorkingOnNode->ccTreesLst); p_Pos =
26945 + LIST_NEXT(p_Pos))
26946 + {
26947 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
26948 +
26949 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
26950 +
26951 + err =
26952 + SetRequiredAction(
26953 + h_FmPcd,
26954 + UPDATE_CC_WITH_DELETE_TREE,
26955 + &((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
26956 + PTR_MOVE(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable, p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
26957 + 1, p_CcNodeInformation->h_CcNode);
26958 + }
26959 + }
26960 + else
26961 + {
26962 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
26963 +
26964 + err =
26965 + SetRequiredAction(
26966 + h_FmPcd,
26967 + UPDATE_CC_WITH_DELETE_TREE,
26968 + &((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
26969 + UINT_TO_PTR(((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
26970 + 1, p_AdditionalParams->h_CurrentNode);
26971 + }
26972 + if (err)
26973 + return err;
26974 +
26975 + /* We remove from the subtree of the removed node tree because it wasn't done in the previous stage
26976 + Update ccPrevNodesLst or ccTreeIdLst of the removed node
26977 + Update of the node owner */
26978 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26979 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
26980 + p_FmPcdCcNextNode->h_Spinlock);
26981 +
26982 + ASSERT_COND(p_CcNodeInformation);
26983 + ASSERT_COND(p_CcNodeInformation->index);
26984 +
26985 + p_CcNodeInformation->index--;
26986 +
26987 + if (p_CcNodeInformation->index == 0)
26988 + DequeueNodeInfoFromRelevantLst(p_UpdateLst,
26989 + p_AdditionalParams->h_CurrentNode,
26990 + p_FmPcdCcNextNode->h_Spinlock);
26991 +
26992 + UpdateNodeOwner(p_FmPcdCcNextNode, FALSE);
26993 +
26994 + if (p_AdditionalParams->h_ManipForRmv)
26995 + {
26996 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26997 + FmPcdManipGetNodeLstPointedOnThisManip(
26998 + p_AdditionalParams->h_ManipForRmv),
26999 + p_AdditionalParams->h_CurrentNode,
27000 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForRmv));
27001 +
27002 + ASSERT_COND(p_CcNodeInformation);
27003 + ASSERT_COND(p_CcNodeInformation->index);
27004 +
27005 + p_CcNodeInformation->index--;
27006 +
27007 + if (p_CcNodeInformation->index == 0)
27008 + DequeueNodeInfoFromRelevantLst(
27009 + FmPcdManipGetNodeLstPointedOnThisManip(
27010 + p_AdditionalParams->h_ManipForRmv),
27011 + p_AdditionalParams->h_CurrentNode,
27012 + FmPcdManipGetSpinlock(
27013 + p_AdditionalParams->h_ManipForRmv));
27014 + }
27015 + }
27016 +
27017 + if (p_AdditionalParams->h_ManipForRmv)
27018 + FmPcdManipUpdateOwner(p_AdditionalParams->h_ManipForRmv, FALSE);
27019 +
27020 + if (p_AdditionalParams->p_StatsObjForRmv)
27021 + PutStatsObj((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode),
27022 + p_AdditionalParams->p_StatsObjForRmv);
27023 +
27024 +#if (DPAA_VERSION >= 11)
27025 + if (p_AdditionalParams->h_FrmReplicForRmv)
27026 + FrmReplicGroupUpdateOwner(p_AdditionalParams->h_FrmReplicForRmv,
27027 + FALSE/* remove */);
27028 +#endif /* (DPAA_VERSION >= 11) */
27029 +
27030 + if (!useShadowStructs)
27031 + {
27032 + h_Muram = FmPcdGetMuramHandle(h_FmPcd);
27033 + ASSERT_COND(h_Muram);
27034 +
27035 + if ((p_AdditionalParams->tree && !((t_FmPcd *)h_FmPcd)->p_CcShadow)
27036 + || (!p_AdditionalParams->tree
27037 + && !((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->maxNumOfKeys))
27038 + {
27039 + /* We release new AD which was allocated and updated for copy from to actual AD */
27040 + for (p_Pos = LIST_FIRST(h_FmPcdNewPointersLst);
27041 + p_Pos != (h_FmPcdNewPointersLst); p_Pos = LIST_NEXT(p_Pos))
27042 + {
27043 +
27044 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
27045 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
27046 + FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode);
27047 + }
27048 + }
27049 +
27050 + /* Free Old data structure if it has to be freed - new data structure was allocated*/
27051 + if (p_AdditionalParams->p_AdTableOld)
27052 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_AdTableOld);
27053 +
27054 + if (p_AdditionalParams->p_KeysMatchTableOld)
27055 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_KeysMatchTableOld);
27056 + }
27057 +
27058 + /* Update current modified node with changed fields if it's required*/
27059 + if (!p_AdditionalParams->tree)
27060 + {
27061 + if (p_AdditionalParams->p_AdTableNew)
27062 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable =
27063 + p_AdditionalParams->p_AdTableNew;
27064 +
27065 + if (p_AdditionalParams->p_KeysMatchTableNew)
27066 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_KeysMatchTable =
27067 + p_AdditionalParams->p_KeysMatchTableNew;
27068 +
27069 + /* Locking node's spinlock before updating 'keys and next engine' structure,
27070 + as it maybe used to retrieve keys statistics */
27071 + intFlags =
27072 + XX_LockIntrSpinlock(
27073 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock);
27074 +
27075 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->numOfKeys =
27076 + p_AdditionalParams->numOfKeys;
27077 +
27078 + memcpy(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
27079 + &p_AdditionalParams->keyAndNextEngineParams,
27080 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (CC_MAX_NUM_OF_KEYS));
27081 +
27082 + XX_UnlockIntrSpinlock(
27083 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock,
27084 + intFlags);
27085 + }
27086 + else
27087 + {
27088 + uint8_t numEntries =
27089 + ((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->numOfEntries;
27090 + ASSERT_COND(numEntries < FM_PCD_MAX_NUM_OF_CC_GROUPS);
27091 + memcpy(&((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
27092 + &p_AdditionalParams->keyAndNextEngineParams,
27093 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * numEntries);
27094 + }
27095 +
27096 + ReleaseLst(h_FmPcdOldPointersLst);
27097 + ReleaseLst(h_FmPcdNewPointersLst);
27098 +
27099 + XX_Free(p_AdditionalParams);
27100 +
27101 + return E_OK;
27102 +}
27103 +
27104 +static t_Handle BuildNewAd(
27105 + t_Handle h_Ad,
27106 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
27107 + t_FmPcdCcNode *p_CcNode,
27108 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
27109 +{
27110 + t_FmPcdCcNode *p_FmPcdCcNodeTmp;
27111 + t_Handle h_OrigAd = NULL;
27112 +
27113 + p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
27114 + if (!p_FmPcdCcNodeTmp)
27115 + {
27116 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp"));
27117 + return NULL;
27118 + }
27119 + memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode));
27120 +
27121 + p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys;
27122 + p_FmPcdCcNodeTmp->h_KeysMatchTable =
27123 + p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew;
27124 + p_FmPcdCcNodeTmp->h_AdTable =
27125 + p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew;
27126 +
27127 + p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask;
27128 + p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode;
27129 + p_FmPcdCcNodeTmp->offset = p_CcNode->offset;
27130 + p_FmPcdCcNodeTmp->prsArrayOffset = p_CcNode->prsArrayOffset;
27131 + p_FmPcdCcNodeTmp->ctrlFlow = p_CcNode->ctrlFlow;
27132 + p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_CcNode->ccKeySizeAccExtraction;
27133 + p_FmPcdCcNodeTmp->sizeOfExtraction = p_CcNode->sizeOfExtraction;
27134 + p_FmPcdCcNodeTmp->glblMaskSize = p_CcNode->glblMaskSize;
27135 + p_FmPcdCcNodeTmp->p_GlblMask = p_CcNode->p_GlblMask;
27136 +
27137 + if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
27138 + {
27139 + if (p_FmPcdCcNextEngineParams->h_Manip)
27140 + {
27141 + h_OrigAd = p_CcNode->h_Ad;
27142 + if (AllocAndFillAdForContLookupManip(
27143 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
27144 + != E_OK)
27145 + {
27146 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
27147 + XX_Free(p_FmPcdCcNodeTmp);
27148 + return NULL;
27149 + }
27150 + }
27151 + FillAdOfTypeContLookup(h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27152 + h_OrigAd ? NULL : p_FmPcdCcNextEngineParams->h_Manip, NULL);
27153 + }
27154 +
27155 +#if (DPAA_VERSION >= 11)
27156 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_FR)
27157 + && (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic))
27158 + {
27159 + FillAdOfTypeContLookup(
27160 + h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27161 + p_FmPcdCcNextEngineParams->h_Manip,
27162 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
27163 + }
27164 +#endif /* (DPAA_VERSION >= 11) */
27165 +
27166 + XX_Free(p_FmPcdCcNodeTmp);
27167 +
27168 + return E_OK;
27169 +}
27170 +
27171 +static t_Error DynamicChangeHc(
27172 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27173 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27174 + bool useShadowStructs)
27175 +{
27176 + t_List *p_PosOld, *p_PosNew;
27177 + uint32_t oldAdAddrOffset, newAdAddrOffset;
27178 + uint16_t i = 0;
27179 + t_Error err = E_OK;
27180 + uint8_t numOfModifiedPtr;
27181 +
27182 + ASSERT_COND(h_FmPcd);
27183 + ASSERT_COND(h_OldPointersLst);
27184 + ASSERT_COND(h_NewPointersLst);
27185 +
27186 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27187 +
27188 + if (numOfModifiedPtr)
27189 + {
27190 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27191 + p_PosOld = LIST_FIRST(h_OldPointersLst);
27192 +
27193 + /* Retrieve address of new AD */
27194 + newAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27195 + p_PosNew);
27196 + if (newAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27197 + {
27198 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27199 + h_NewPointersLst,
27200 + p_AdditionalParams, useShadowStructs);
27201 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address"));
27202 + }
27203 +
27204 + for (i = 0; i < numOfModifiedPtr; i++)
27205 + {
27206 + /* Retrieve address of current AD */
27207 + oldAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27208 + p_PosOld);
27209 + if (oldAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27210 + {
27211 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27212 + h_NewPointersLst,
27213 + p_AdditionalParams,
27214 + useShadowStructs);
27215 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old AD address"));
27216 + }
27217 +
27218 + /* Invoke host command to copy from new AD to old AD */
27219 + err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc,
27220 + oldAdAddrOffset, newAdAddrOffset);
27221 + if (err)
27222 + {
27223 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27224 + h_NewPointersLst,
27225 + p_AdditionalParams,
27226 + useShadowStructs);
27227 + RETURN_ERROR(
27228 + MAJOR,
27229 + err,
27230 + ("For part of nodes changes are done - situation is danger"));
27231 + }
27232 +
27233 + p_PosOld = LIST_NEXT(p_PosOld);
27234 + }
27235 + }
27236 + return E_OK;
27237 +}
27238 +
27239 +static t_Error DoDynamicChange(
27240 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27241 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27242 + bool useShadowStructs)
27243 +{
27244 + t_FmPcdCcNode *p_CcNode =
27245 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
27246 + t_List *p_PosNew;
27247 + t_CcNodeInformation *p_CcNodeInfo;
27248 + t_FmPcdCcNextEngineParams nextEngineParams;
27249 + t_Handle h_Ad;
27250 + uint32_t keySize;
27251 + t_Error err = E_OK;
27252 + uint8_t numOfModifiedPtr;
27253 +
27254 + ASSERT_COND(h_FmPcd);
27255 +
27256 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
27257 +
27258 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27259 +
27260 + if (numOfModifiedPtr)
27261 + {
27262 +
27263 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27264 +
27265 + /* Invoke host-command to copy from the new Ad to existing Ads */
27266 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
27267 + p_AdditionalParams, useShadowStructs);
27268 + if (err)
27269 + RETURN_ERROR(MAJOR, err, NO_MSG);
27270 +
27271 + if (useShadowStructs)
27272 + {
27273 + /* When the host-command above has ended, the old structures are 'free'and we can update
27274 + them by copying from the new shadow structures. */
27275 + if (p_CcNode->lclMask)
27276 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
27277 + else
27278 + keySize = p_CcNode->ccKeySizeAccExtraction;
27279 +
27280 + MemCpy8(p_AdditionalParams->p_KeysMatchTableOld,
27281 + p_AdditionalParams->p_KeysMatchTableNew,
27282 + p_CcNode->maxNumOfKeys * keySize * sizeof(uint8_t));
27283 +
27284 + MemCpy8(
27285 + p_AdditionalParams->p_AdTableOld,
27286 + p_AdditionalParams->p_AdTableNew,
27287 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
27288 + * FM_PCD_CC_AD_ENTRY_SIZE));
27289 +
27290 + /* Retrieve the address of the allocated Ad */
27291 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_PosNew);
27292 + h_Ad = p_CcNodeInfo->h_CcNode;
27293 +
27294 + /* Build a new Ad that holds the old (now updated) structures */
27295 + p_AdditionalParams->p_KeysMatchTableNew =
27296 + p_AdditionalParams->p_KeysMatchTableOld;
27297 + p_AdditionalParams->p_AdTableNew = p_AdditionalParams->p_AdTableOld;
27298 +
27299 + nextEngineParams.nextEngine = e_FM_PCD_CC;
27300 + nextEngineParams.params.ccParams.h_CcNode = (t_Handle)p_CcNode;
27301 +
27302 + BuildNewAd(h_Ad, p_AdditionalParams, p_CcNode, &nextEngineParams);
27303 +
27304 + /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */
27305 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
27306 + p_AdditionalParams, useShadowStructs);
27307 + if (err)
27308 + RETURN_ERROR(MAJOR, err, NO_MSG);
27309 + }
27310 + }
27311 +
27312 + err = ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27313 + h_NewPointersLst,
27314 + p_AdditionalParams, useShadowStructs);
27315 + if (err)
27316 + RETURN_ERROR(MAJOR, err, NO_MSG);
27317 +
27318 + return E_OK;
27319 +}
27320 +
27321 +#ifdef FM_CAPWAP_SUPPORT
27322 +static bool IsCapwapApplSpecific(t_Handle h_Node)
27323 +{
27324 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_Node;
27325 + bool isManipForCapwapApplSpecificBuild = FALSE;
27326 + int i = 0;
27327 +
27328 + ASSERT_COND(h_Node);
27329 + /* assumption that this function called only for INDEXED_FLOW_ID - so no miss*/
27330 + for (i = 0; i < p_CcNode->numOfKeys; i++)
27331 + {
27332 + if ( p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip &&
27333 + FmPcdManipIsCapwapApplSpecific(p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip))
27334 + {
27335 + isManipForCapwapApplSpecificBuild = TRUE;
27336 + break;
27337 + }
27338 + }
27339 + return isManipForCapwapApplSpecificBuild;
27340 +
27341 +}
27342 +#endif /* FM_CAPWAP_SUPPORT */
27343 +
27344 +static t_Error CcUpdateParam(
27345 + t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort,
27346 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParams,
27347 + uint16_t numOfEntries, t_Handle h_Ad, bool validate, uint16_t level,
27348 + t_Handle h_FmTree, bool modify)
27349 +{
27350 + t_FmPcdCcNode *p_CcNode;
27351 + t_Error err;
27352 + uint16_t tmp = 0;
27353 + int i = 0;
27354 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
27355 +
27356 + level++;
27357 +
27358 + if (p_CcTree->h_IpReassemblyManip)
27359 + {
27360 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27361 + p_CcTree->h_IpReassemblyManip, NULL, validate,
27362 + level, h_FmTree, modify);
27363 + if (err)
27364 + RETURN_ERROR(MAJOR, err, NO_MSG);
27365 + }
27366 +
27367 + if (p_CcTree->h_CapwapReassemblyManip)
27368 + {
27369 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27370 + p_CcTree->h_CapwapReassemblyManip, NULL, validate,
27371 + level, h_FmTree, modify);
27372 + if (err)
27373 + RETURN_ERROR(MAJOR, err, NO_MSG);
27374 + }
27375 +
27376 + if (numOfEntries)
27377 + {
27378 + for (i = 0; i < numOfEntries; i++)
27379 + {
27380 + if (i == 0)
27381 + h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE);
27382 + else
27383 + h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE);
27384 +
27385 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.nextEngine
27386 + == e_FM_PCD_CC)
27387 + {
27388 + p_CcNode =
27389 + p_CcKeyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
27390 + ASSERT_COND(p_CcNode);
27391 +
27392 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27393 + {
27394 + err =
27395 + FmPcdManipUpdate(
27396 + h_FmPcd,
27397 + NULL,
27398 + h_FmPort,
27399 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27400 + h_Ad, validate, level, h_FmTree, modify);
27401 + if (err)
27402 + RETURN_ERROR(MAJOR, err, NO_MSG);
27403 + }
27404 +
27405 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
27406 + != e_FM_PCD_INVALID)
27407 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
27408 + else
27409 + tmp = p_CcNode->numOfKeys;
27410 +
27411 + err = CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
27412 + p_CcNode->keyAndNextEngineParams, tmp,
27413 + p_CcNode->h_AdTable, validate, level,
27414 + h_FmTree, modify);
27415 + if (err)
27416 + RETURN_ERROR(MAJOR, err, NO_MSG);
27417 + }
27418 + else
27419 + {
27420 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27421 + {
27422 + err =
27423 + FmPcdManipUpdate(
27424 + h_FmPcd,
27425 + NULL,
27426 + h_FmPort,
27427 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27428 + h_Ad, validate, level, h_FmTree, modify);
27429 + if (err)
27430 + RETURN_ERROR(MAJOR, err, NO_MSG);
27431 + }
27432 + }
27433 + }
27434 + }
27435 +
27436 + return E_OK;
27437 +}
27438 +
27439 +static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam)
27440 +{
27441 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.action)
27442 + {
27443 + case (e_FM_PCD_ACTION_EXACT_MATCH):
27444 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27445 + {
27446 + case (e_FM_PCD_EXTRACT_FROM_KEY):
27447 + return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH;
27448 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27449 + return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH;
27450 + default:
27451 + return CC_PRIVATE_INFO_NONE;
27452 + }
27453 +
27454 + case (e_FM_PCD_ACTION_INDEXED_LOOKUP):
27455 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27456 + {
27457 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27458 + return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP;
27459 + case (e_FM_PCD_EXTRACT_FROM_FLOW_ID):
27460 + return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP;
27461 + default:
27462 + return CC_PRIVATE_INFO_NONE;
27463 + }
27464 +
27465 + default:
27466 + break;
27467 + }
27468 +
27469 + return CC_PRIVATE_INFO_NONE;
27470 +}
27471 +
27472 +static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(
27473 + t_List *p_List)
27474 +{
27475 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27476 +
27477 + if (!LIST_IsEmpty(p_List))
27478 + {
27479 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next);
27480 + LIST_DelAndInit(&p_CcNodeInfo->node);
27481 + }
27482 +
27483 + return p_CcNodeInfo;
27484 +}
27485 +
27486 +void ReleaseLst(t_List *p_List)
27487 +{
27488 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27489 +
27490 + if (!LIST_IsEmpty(p_List))
27491 + {
27492 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27493 + while (p_CcNodeInfo)
27494 + {
27495 + XX_Free(p_CcNodeInfo);
27496 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27497 + }
27498 + }
27499 +
27500 + LIST_Del(p_List);
27501 +}
27502 +
27503 +static void DeleteNode(t_FmPcdCcNode *p_CcNode)
27504 +{
27505 + uint32_t i;
27506 +
27507 + if (!p_CcNode)
27508 + return;
27509 +
27510 + if (p_CcNode->p_GlblMask)
27511 + {
27512 + XX_Free(p_CcNode->p_GlblMask);
27513 + p_CcNode->p_GlblMask = NULL;
27514 + }
27515 +
27516 + if (p_CcNode->h_KeysMatchTable)
27517 + {
27518 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27519 + p_CcNode->h_KeysMatchTable);
27520 + p_CcNode->h_KeysMatchTable = NULL;
27521 + }
27522 +
27523 + if (p_CcNode->h_AdTable)
27524 + {
27525 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27526 + p_CcNode->h_AdTable);
27527 + p_CcNode->h_AdTable = NULL;
27528 + }
27529 +
27530 + if (p_CcNode->h_Ad)
27531 + {
27532 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27533 + p_CcNode->h_Ad);
27534 + p_CcNode->h_Ad = NULL;
27535 + p_CcNode->h_TmpAd = NULL;
27536 + }
27537 +
27538 + if (p_CcNode->h_StatsFLRs)
27539 + {
27540 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27541 + p_CcNode->h_StatsFLRs);
27542 + p_CcNode->h_StatsFLRs = NULL;
27543 + }
27544 +
27545 + if (p_CcNode->h_Spinlock)
27546 + {
27547 + XX_FreeSpinlock(p_CcNode->h_Spinlock);
27548 + p_CcNode->h_Spinlock = NULL;
27549 + }
27550 +
27551 + /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */
27552 + if (p_CcNode->isHashBucket
27553 + && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE))
27554 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters =
27555 + p_CcNode->h_PrivMissStatsCounters;
27556 +
27557 + /* Releasing all currently used statistics objects, including 'miss' entry */
27558 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
27559 + if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj)
27560 + PutStatsObj(p_CcNode,
27561 + p_CcNode->keyAndNextEngineParams[i].p_StatsObj);
27562 +
27563 + if (!LIST_IsEmpty(&p_CcNode->availableStatsLst))
27564 + {
27565 + t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
27566 + ASSERT_COND(h_FmMuram);
27567 +
27568 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
27569 + }
27570 +
27571 + LIST_Del(&p_CcNode->availableStatsLst);
27572 +
27573 + ReleaseLst(&p_CcNode->availableStatsLst);
27574 + ReleaseLst(&p_CcNode->ccPrevNodesLst);
27575 + ReleaseLst(&p_CcNode->ccTreeIdLst);
27576 + ReleaseLst(&p_CcNode->ccTreesLst);
27577 +
27578 + XX_Free(p_CcNode);
27579 +}
27580 +
27581 +static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd)
27582 +{
27583 + if (p_FmPcdTree)
27584 + {
27585 + if (p_FmPcdTree->ccTreeBaseAddr)
27586 + {
27587 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd),
27588 + UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr));
27589 + p_FmPcdTree->ccTreeBaseAddr = 0;
27590 + }
27591 +
27592 + ReleaseLst(&p_FmPcdTree->fmPortsLst);
27593 +
27594 + XX_Free(p_FmPcdTree);
27595 + }
27596 +}
27597 +
27598 +static void GetCcExtractKeySize(uint8_t parseCodeRealSize,
27599 + uint8_t *parseCodeCcSize)
27600 +{
27601 + if ((parseCodeRealSize > 0) && (parseCodeRealSize < 2))
27602 + *parseCodeCcSize = 1;
27603 + else
27604 + if (parseCodeRealSize == 2)
27605 + *parseCodeCcSize = 2;
27606 + else
27607 + if ((parseCodeRealSize > 2) && (parseCodeRealSize <= 4))
27608 + *parseCodeCcSize = 4;
27609 + else
27610 + if ((parseCodeRealSize > 4) && (parseCodeRealSize <= 8))
27611 + *parseCodeCcSize = 8;
27612 + else
27613 + if ((parseCodeRealSize > 8) && (parseCodeRealSize <= 16))
27614 + *parseCodeCcSize = 16;
27615 + else
27616 + if ((parseCodeRealSize > 16)
27617 + && (parseCodeRealSize <= 24))
27618 + *parseCodeCcSize = 24;
27619 + else
27620 + if ((parseCodeRealSize > 24)
27621 + && (parseCodeRealSize <= 32))
27622 + *parseCodeCcSize = 32;
27623 + else
27624 + if ((parseCodeRealSize > 32)
27625 + && (parseCodeRealSize <= 40))
27626 + *parseCodeCcSize = 40;
27627 + else
27628 + if ((parseCodeRealSize > 40)
27629 + && (parseCodeRealSize <= 48))
27630 + *parseCodeCcSize = 48;
27631 + else
27632 + if ((parseCodeRealSize > 48)
27633 + && (parseCodeRealSize <= 56))
27634 + *parseCodeCcSize = 56;
27635 + else
27636 + *parseCodeCcSize = 0;
27637 +}
27638 +
27639 +static void GetSizeHeaderField(e_NetHeaderType hdr, t_FmPcdFields field,
27640 + uint8_t *parseCodeRealSize)
27641 +{
27642 + switch (hdr)
27643 + {
27644 + case (HEADER_TYPE_ETH):
27645 + switch (field.eth)
27646 + {
27647 + case (NET_HEADER_FIELD_ETH_DA):
27648 + *parseCodeRealSize = 6;
27649 + break;
27650 +
27651 + case (NET_HEADER_FIELD_ETH_SA):
27652 + *parseCodeRealSize = 6;
27653 + break;
27654 +
27655 + case (NET_HEADER_FIELD_ETH_TYPE):
27656 + *parseCodeRealSize = 2;
27657 + break;
27658 +
27659 + default:
27660 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27661 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27662 + break;
27663 + }
27664 + break;
27665 +
27666 + case (HEADER_TYPE_PPPoE):
27667 + switch (field.pppoe)
27668 + {
27669 + case (NET_HEADER_FIELD_PPPoE_PID):
27670 + *parseCodeRealSize = 2;
27671 + break;
27672 +
27673 + default:
27674 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27675 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27676 + break;
27677 + }
27678 + break;
27679 +
27680 + case (HEADER_TYPE_VLAN):
27681 + switch (field.vlan)
27682 + {
27683 + case (NET_HEADER_FIELD_VLAN_TCI):
27684 + *parseCodeRealSize = 2;
27685 + break;
27686 +
27687 + default:
27688 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2"));
27689 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27690 + break;
27691 + }
27692 + break;
27693 +
27694 + case (HEADER_TYPE_MPLS):
27695 + switch (field.mpls)
27696 + {
27697 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
27698 + *parseCodeRealSize = 4;
27699 + break;
27700 +
27701 + default:
27702 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3"));
27703 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27704 + break;
27705 + }
27706 + break;
27707 +
27708 + case (HEADER_TYPE_IPv4):
27709 + switch (field.ipv4)
27710 + {
27711 + case (NET_HEADER_FIELD_IPv4_DST_IP):
27712 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
27713 + *parseCodeRealSize = 4;
27714 + break;
27715 +
27716 + case (NET_HEADER_FIELD_IPv4_TOS):
27717 + case (NET_HEADER_FIELD_IPv4_PROTO):
27718 + *parseCodeRealSize = 1;
27719 + break;
27720 +
27721 + case (NET_HEADER_FIELD_IPv4_DST_IP
27722 + | NET_HEADER_FIELD_IPv4_SRC_IP):
27723 + *parseCodeRealSize = 8;
27724 + break;
27725 +
27726 + case (NET_HEADER_FIELD_IPv4_TTL):
27727 + *parseCodeRealSize = 1;
27728 + break;
27729 +
27730 + default:
27731 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4"));
27732 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27733 + break;
27734 + }
27735 + break;
27736 +
27737 + case (HEADER_TYPE_IPv6):
27738 + switch (field.ipv6)
27739 + {
27740 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
27741 + | NET_HEADER_FIELD_IPv6_TC):
27742 + *parseCodeRealSize = 4;
27743 + break;
27744 +
27745 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
27746 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
27747 + *parseCodeRealSize = 1;
27748 + break;
27749 +
27750 + case (NET_HEADER_FIELD_IPv6_DST_IP):
27751 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
27752 + *parseCodeRealSize = 16;
27753 + break;
27754 +
27755 + default:
27756 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
27757 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27758 + break;
27759 + }
27760 + break;
27761 +
27762 + case (HEADER_TYPE_IP):
27763 + switch (field.ip)
27764 + {
27765 + case (NET_HEADER_FIELD_IP_DSCP):
27766 + case (NET_HEADER_FIELD_IP_PROTO):
27767 + *parseCodeRealSize = 1;
27768 + break;
27769 +
27770 + default:
27771 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
27772 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27773 + break;
27774 + }
27775 + break;
27776 +
27777 + case (HEADER_TYPE_GRE):
27778 + switch (field.gre)
27779 + {
27780 + case (NET_HEADER_FIELD_GRE_TYPE):
27781 + *parseCodeRealSize = 2;
27782 + break;
27783 +
27784 + default:
27785 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6"));
27786 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27787 + break;
27788 + }
27789 + break;
27790 +
27791 + case (HEADER_TYPE_MINENCAP):
27792 + switch (field.minencap)
27793 + {
27794 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
27795 + *parseCodeRealSize = 1;
27796 + break;
27797 +
27798 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
27799 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
27800 + *parseCodeRealSize = 4;
27801 + break;
27802 +
27803 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
27804 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
27805 + *parseCodeRealSize = 8;
27806 + break;
27807 +
27808 + default:
27809 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7"));
27810 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27811 + break;
27812 + }
27813 + break;
27814 +
27815 + case (HEADER_TYPE_TCP):
27816 + switch (field.tcp)
27817 + {
27818 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
27819 + case (NET_HEADER_FIELD_TCP_PORT_DST):
27820 + *parseCodeRealSize = 2;
27821 + break;
27822 +
27823 + case (NET_HEADER_FIELD_TCP_PORT_SRC
27824 + | NET_HEADER_FIELD_TCP_PORT_DST):
27825 + *parseCodeRealSize = 4;
27826 + break;
27827 +
27828 + default:
27829 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8"));
27830 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27831 + break;
27832 + }
27833 + break;
27834 +
27835 + case (HEADER_TYPE_UDP):
27836 + switch (field.udp)
27837 + {
27838 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
27839 + case (NET_HEADER_FIELD_UDP_PORT_DST):
27840 + *parseCodeRealSize = 2;
27841 + break;
27842 +
27843 + case (NET_HEADER_FIELD_UDP_PORT_SRC
27844 + | NET_HEADER_FIELD_UDP_PORT_DST):
27845 + *parseCodeRealSize = 4;
27846 + break;
27847 +
27848 + default:
27849 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9"));
27850 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27851 + break;
27852 + }
27853 + break;
27854 +
27855 + default:
27856 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10"));
27857 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27858 + break;
27859 + }
27860 +}
27861 +
27862 +t_Error ValidateNextEngineParams(
27863 + t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
27864 + e_FmPcdCcStatsMode statsMode)
27865 +{
27866 + uint16_t absoluteProfileId;
27867 + t_Error err = E_OK;
27868 + uint8_t relativeSchemeId;
27869 +
27870 + if ((statsMode == e_FM_PCD_CC_STATS_MODE_NONE)
27871 + && (p_FmPcdCcNextEngineParams->statisticsEn))
27872 + RETURN_ERROR(
27873 + MAJOR,
27874 + E_CONFLICT,
27875 + ("Statistics are requested for a key, but statistics mode was set"
27876 + "to 'NONE' upon initialization"));
27877 +
27878 + switch (p_FmPcdCcNextEngineParams->nextEngine)
27879 + {
27880 + case (e_FM_PCD_INVALID):
27881 + err = E_NOT_SUPPORTED;
27882 + break;
27883 +
27884 + case (e_FM_PCD_DONE):
27885 + if ((p_FmPcdCcNextEngineParams->params.enqueueParams.action
27886 + == e_FM_PCD_ENQ_FRAME)
27887 + && p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
27888 + {
27889 + if (!p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid)
27890 + RETURN_ERROR(
27891 + MAJOR,
27892 + E_CONFLICT,
27893 + ("When overrideFqid is set, newFqid must not be zero"));
27894 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid
27895 + & ~0x00FFFFFF)
27896 + RETURN_ERROR(
27897 + MAJOR, E_INVALID_VALUE,
27898 + ("fqidForCtrlFlow must be between 1 and 2^24-1"));
27899 + }
27900 + break;
27901 +
27902 + case (e_FM_PCD_KG):
27903 + relativeSchemeId =
27904 + FmPcdKgGetRelativeSchemeId(
27905 + h_FmPcd,
27906 + FmPcdKgGetSchemeId(
27907 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme));
27908 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
27909 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
27910 + if (!FmPcdKgIsSchemeValidSw(
27911 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme))
27912 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
27913 + ("not valid schemeIndex in KG next engine param"));
27914 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
27915 + RETURN_ERROR(
27916 + MAJOR,
27917 + E_INVALID_STATE,
27918 + ("CC Node may point only to a scheme that is always direct."));
27919 + break;
27920 +
27921 + case (e_FM_PCD_PLCR):
27922 + if (p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams)
27923 + {
27924 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
27925 + if (p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile)
27926 + {
27927 + err =
27928 + FmPcdPlcrGetAbsoluteIdByProfileParams(
27929 + h_FmPcd,
27930 + e_FM_PCD_PLCR_SHARED,
27931 + NULL,
27932 + p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId,
27933 + &absoluteProfileId);
27934 + if (err)
27935 + RETURN_ERROR(MAJOR, err,
27936 + ("Shared profile offset is out of range"));
27937 + if (!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId))
27938 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
27939 + ("Invalid profile"));
27940 + }
27941 + }
27942 + break;
27943 +
27944 + case (e_FM_PCD_HASH):
27945 + p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC;
27946 + case (e_FM_PCD_CC):
27947 + if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
27948 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
27949 + ("handler to next Node is NULL"));
27950 + break;
27951 +
27952 +#if (DPAA_VERSION >= 11)
27953 + case (e_FM_PCD_FR):
27954 + if (!p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
27955 + err = E_NOT_SUPPORTED;
27956 + break;
27957 +#endif /* (DPAA_VERSION >= 11) */
27958 +
27959 + default:
27960 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
27961 + ("Next engine is not correct"));
27962 + }
27963 +
27964 +
27965 + return err;
27966 +}
27967 +
27968 +static uint8_t GetGenParseCode(e_FmPcdExtractFrom src,
27969 + uint32_t offset, bool glblMask,
27970 + uint8_t *parseArrayOffset, bool fromIc,
27971 + ccPrivateInfo_t icCode)
27972 +{
27973 + if (!fromIc)
27974 + {
27975 + switch (src)
27976 + {
27977 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
27978 + if (glblMask)
27979 + return CC_PC_GENERIC_WITH_MASK;
27980 + else
27981 + return CC_PC_GENERIC_WITHOUT_MASK;
27982 +
27983 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
27984 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
27985 + if (offset)
27986 + return CC_PR_OFFSET;
27987 + else
27988 + return CC_PR_WITHOUT_OFFSET;
27989 +
27990 + default:
27991 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
27992 + return CC_PC_ILLEGAL;
27993 + }
27994 + }
27995 + else
27996 + {
27997 + switch (icCode)
27998 + {
27999 + case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH):
28000 + *parseArrayOffset = 0x50;
28001 + return CC_PC_GENERIC_IC_GMASK;
28002 +
28003 + case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH):
28004 + *parseArrayOffset = 0x48;
28005 + return CC_PC_GENERIC_IC_GMASK;
28006 +
28007 + case (CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP):
28008 + *parseArrayOffset = 0x48;
28009 + return CC_PC_GENERIC_IC_HASH_INDEXED;
28010 +
28011 + case (CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP):
28012 + *parseArrayOffset = 0x16;
28013 + return CC_PC_GENERIC_IC_HASH_INDEXED;
28014 +
28015 + default:
28016 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
28017 + break;
28018 + }
28019 + }
28020 +
28021 + return CC_PC_ILLEGAL;
28022 +}
28023 +
28024 +static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index,
28025 + t_FmPcdFields field)
28026 +{
28027 + switch (hdr)
28028 + {
28029 + case (HEADER_TYPE_NONE):
28030 + ASSERT_COND(FALSE);
28031 + return CC_PC_ILLEGAL;
28032 +
28033 + case (HEADER_TYPE_ETH):
28034 + switch (field.eth)
28035 + {
28036 + case (NET_HEADER_FIELD_ETH_DA):
28037 + return CC_PC_FF_MACDST;
28038 + case (NET_HEADER_FIELD_ETH_SA):
28039 + return CC_PC_FF_MACSRC;
28040 + case (NET_HEADER_FIELD_ETH_TYPE):
28041 + return CC_PC_FF_ETYPE;
28042 + default:
28043 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28044 + return CC_PC_ILLEGAL;
28045 + }
28046 +
28047 + case (HEADER_TYPE_VLAN):
28048 + switch (field.vlan)
28049 + {
28050 + case (NET_HEADER_FIELD_VLAN_TCI):
28051 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28052 + || (index == e_FM_PCD_HDR_INDEX_1))
28053 + return CC_PC_FF_TCI1;
28054 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28055 + return CC_PC_FF_TCI2;
28056 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28057 + return CC_PC_ILLEGAL;
28058 + default:
28059 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28060 + return CC_PC_ILLEGAL;
28061 + }
28062 +
28063 + case (HEADER_TYPE_MPLS):
28064 + switch (field.mpls)
28065 + {
28066 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
28067 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28068 + || (index == e_FM_PCD_HDR_INDEX_1))
28069 + return CC_PC_FF_MPLS1;
28070 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28071 + return CC_PC_FF_MPLS_LAST;
28072 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
28073 + return CC_PC_ILLEGAL;
28074 + default:
28075 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28076 + return CC_PC_ILLEGAL;
28077 + }
28078 +
28079 + case (HEADER_TYPE_IPv4):
28080 + switch (field.ipv4)
28081 + {
28082 + case (NET_HEADER_FIELD_IPv4_DST_IP):
28083 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28084 + || (index == e_FM_PCD_HDR_INDEX_1))
28085 + return CC_PC_FF_IPV4DST1;
28086 + if (index == e_FM_PCD_HDR_INDEX_2)
28087 + return CC_PC_FF_IPV4DST2;
28088 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28089 + return CC_PC_ILLEGAL;
28090 + case (NET_HEADER_FIELD_IPv4_TOS):
28091 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28092 + || (index == e_FM_PCD_HDR_INDEX_1))
28093 + return CC_PC_FF_IPV4IPTOS_TC1;
28094 + if (index == e_FM_PCD_HDR_INDEX_2)
28095 + return CC_PC_FF_IPV4IPTOS_TC2;
28096 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28097 + return CC_PC_ILLEGAL;
28098 + case (NET_HEADER_FIELD_IPv4_PROTO):
28099 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28100 + || (index == e_FM_PCD_HDR_INDEX_1))
28101 + return CC_PC_FF_IPV4PTYPE1;
28102 + if (index == e_FM_PCD_HDR_INDEX_2)
28103 + return CC_PC_FF_IPV4PTYPE2;
28104 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28105 + return CC_PC_ILLEGAL;
28106 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
28107 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28108 + || (index == e_FM_PCD_HDR_INDEX_1))
28109 + return CC_PC_FF_IPV4SRC1;
28110 + if (index == e_FM_PCD_HDR_INDEX_2)
28111 + return CC_PC_FF_IPV4SRC2;
28112 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28113 + return CC_PC_ILLEGAL;
28114 + case (NET_HEADER_FIELD_IPv4_SRC_IP
28115 + | NET_HEADER_FIELD_IPv4_DST_IP):
28116 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28117 + || (index == e_FM_PCD_HDR_INDEX_1))
28118 + return CC_PC_FF_IPV4SRC1_IPV4DST1;
28119 + if (index == e_FM_PCD_HDR_INDEX_2)
28120 + return CC_PC_FF_IPV4SRC2_IPV4DST2;
28121 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28122 + return CC_PC_ILLEGAL;
28123 + case (NET_HEADER_FIELD_IPv4_TTL):
28124 + return CC_PC_FF_IPV4TTL;
28125 + default:
28126 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28127 + return CC_PC_ILLEGAL;
28128 + }
28129 +
28130 + case (HEADER_TYPE_IPv6):
28131 + switch (field.ipv6)
28132 + {
28133 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
28134 + | NET_HEADER_FIELD_IPv6_TC):
28135 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28136 + || (index == e_FM_PCD_HDR_INDEX_1))
28137 + return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1;
28138 + if (index == e_FM_PCD_HDR_INDEX_2)
28139 + return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2;
28140 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28141 + return CC_PC_ILLEGAL;
28142 +
28143 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
28144 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28145 + || (index == e_FM_PCD_HDR_INDEX_1))
28146 + return CC_PC_FF_IPV6PTYPE1;
28147 + if (index == e_FM_PCD_HDR_INDEX_2)
28148 + return CC_PC_FF_IPV6PTYPE2;
28149 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28150 + return CC_PC_FF_IPPID;
28151 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28152 + return CC_PC_ILLEGAL;
28153 +
28154 + case (NET_HEADER_FIELD_IPv6_DST_IP):
28155 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28156 + || (index == e_FM_PCD_HDR_INDEX_1))
28157 + return CC_PC_FF_IPV6DST1;
28158 + if (index == e_FM_PCD_HDR_INDEX_2)
28159 + return CC_PC_FF_IPV6DST2;
28160 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28161 + return CC_PC_ILLEGAL;
28162 +
28163 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
28164 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28165 + || (index == e_FM_PCD_HDR_INDEX_1))
28166 + return CC_PC_FF_IPV6SRC1;
28167 + if (index == e_FM_PCD_HDR_INDEX_2)
28168 + return CC_PC_FF_IPV6SRC2;
28169 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28170 + return CC_PC_ILLEGAL;
28171 +
28172 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
28173 + return CC_PC_FF_IPV6HOP_LIMIT;
28174 +
28175 + default:
28176 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28177 + return CC_PC_ILLEGAL;
28178 + }
28179 +
28180 + case (HEADER_TYPE_IP):
28181 + switch (field.ip)
28182 + {
28183 + case (NET_HEADER_FIELD_IP_DSCP):
28184 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28185 + || (index == e_FM_PCD_HDR_INDEX_1))
28186 + return CC_PC_FF_IPDSCP;
28187 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28188 + return CC_PC_ILLEGAL;
28189 +
28190 + case (NET_HEADER_FIELD_IP_PROTO):
28191 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28192 + return CC_PC_FF_IPPID;
28193 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28194 + return CC_PC_ILLEGAL;
28195 +
28196 + default:
28197 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28198 + return CC_PC_ILLEGAL;
28199 + }
28200 +
28201 + case (HEADER_TYPE_GRE):
28202 + switch (field.gre)
28203 + {
28204 + case (NET_HEADER_FIELD_GRE_TYPE):
28205 + return CC_PC_FF_GREPTYPE;
28206 +
28207 + default:
28208 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28209 + return CC_PC_ILLEGAL;
28210 + }
28211 +
28212 + case (HEADER_TYPE_MINENCAP):
28213 + switch (field.minencap)
28214 + {
28215 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
28216 + return CC_PC_FF_MINENCAP_PTYPE;
28217 +
28218 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
28219 + return CC_PC_FF_MINENCAP_IPDST;
28220 +
28221 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
28222 + return CC_PC_FF_MINENCAP_IPSRC;
28223 +
28224 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
28225 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
28226 + return CC_PC_FF_MINENCAP_IPSRC_IPDST;
28227 +
28228 + default:
28229 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28230 + return CC_PC_ILLEGAL;
28231 + }
28232 +
28233 + case (HEADER_TYPE_TCP):
28234 + switch (field.tcp)
28235 + {
28236 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
28237 + return CC_PC_FF_L4PSRC;
28238 +
28239 + case (NET_HEADER_FIELD_TCP_PORT_DST):
28240 + return CC_PC_FF_L4PDST;
28241 +
28242 + case (NET_HEADER_FIELD_TCP_PORT_DST
28243 + | NET_HEADER_FIELD_TCP_PORT_SRC):
28244 + return CC_PC_FF_L4PSRC_L4PDST;
28245 +
28246 + default:
28247 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28248 + return CC_PC_ILLEGAL;
28249 + }
28250 +
28251 + case (HEADER_TYPE_PPPoE):
28252 + switch (field.pppoe)
28253 + {
28254 + case (NET_HEADER_FIELD_PPPoE_PID):
28255 + return CC_PC_FF_PPPPID;
28256 +
28257 + default:
28258 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28259 + return CC_PC_ILLEGAL;
28260 + }
28261 +
28262 + case (HEADER_TYPE_UDP):
28263 + switch (field.udp)
28264 + {
28265 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
28266 + return CC_PC_FF_L4PSRC;
28267 +
28268 + case (NET_HEADER_FIELD_UDP_PORT_DST):
28269 + return CC_PC_FF_L4PDST;
28270 +
28271 + case (NET_HEADER_FIELD_UDP_PORT_DST
28272 + | NET_HEADER_FIELD_UDP_PORT_SRC):
28273 + return CC_PC_FF_L4PSRC_L4PDST;
28274 +
28275 + default:
28276 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28277 + return CC_PC_ILLEGAL;
28278 + }
28279 +
28280 + default:
28281 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28282 + return CC_PC_ILLEGAL;
28283 + }
28284 +}
28285 +
28286 +static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex,
28287 + uint32_t offset, bool glblMask,
28288 + uint8_t *parseArrayOffset)
28289 +{
28290 + bool offsetRelevant = FALSE;
28291 +
28292 + if (offset)
28293 + offsetRelevant = TRUE;
28294 +
28295 + switch (hdr)
28296 + {
28297 + case (HEADER_TYPE_NONE):
28298 + ASSERT_COND(FALSE);
28299 + return CC_PC_ILLEGAL;
28300 +
28301 + case (HEADER_TYPE_ETH):
28302 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
28303 + break;
28304 +
28305 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
28306 + if (offset || glblMask)
28307 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
28308 + else
28309 + return CC_PC_PR_SHIM1;
28310 + break;
28311 +
28312 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
28313 + if (offset || glblMask)
28314 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
28315 + else
28316 + return CC_PC_PR_SHIM2;
28317 + break;
28318 +
28319 + case (HEADER_TYPE_LLC_SNAP):
28320 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
28321 + break;
28322 +
28323 + case (HEADER_TYPE_PPPoE):
28324 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
28325 + break;
28326 +
28327 + case (HEADER_TYPE_MPLS):
28328 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28329 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28330 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
28331 + else
28332 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28333 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
28334 + else
28335 + {
28336 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
28337 + return CC_PC_ILLEGAL;
28338 + }
28339 + break;
28340 +
28341 + case (HEADER_TYPE_IPv4):
28342 + case (HEADER_TYPE_IPv6):
28343 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28344 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28345 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
28346 + else
28347 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
28348 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
28349 + else
28350 + {
28351 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
28352 + return CC_PC_ILLEGAL;
28353 + }
28354 + break;
28355 +
28356 + case (HEADER_TYPE_MINENCAP):
28357 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
28358 + break;
28359 +
28360 + case (HEADER_TYPE_GRE):
28361 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
28362 + break;
28363 +
28364 + case (HEADER_TYPE_TCP):
28365 + case (HEADER_TYPE_UDP):
28366 + case (HEADER_TYPE_IPSEC_AH):
28367 + case (HEADER_TYPE_IPSEC_ESP):
28368 + case (HEADER_TYPE_DCCP):
28369 + case (HEADER_TYPE_SCTP):
28370 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
28371 + break;
28372 +
28373 + default:
28374 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation"));
28375 + return CC_PC_ILLEGAL;
28376 + }
28377 +
28378 + if (offsetRelevant)
28379 + return CC_PR_OFFSET;
28380 + else
28381 + return CC_PR_WITHOUT_OFFSET;
28382 +}
28383 +
28384 +static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field,
28385 + uint32_t offset, uint8_t *parseArrayOffset,
28386 + e_FmPcdHdrIndex hdrIndex)
28387 +{
28388 + bool offsetRelevant = FALSE;
28389 +
28390 + if (offset)
28391 + offsetRelevant = TRUE;
28392 +
28393 + switch (hdr)
28394 + {
28395 + case (HEADER_TYPE_NONE):
28396 + ASSERT_COND(FALSE);
28397 + break;
28398 + case (HEADER_TYPE_ETH):
28399 + switch (field.eth)
28400 + {
28401 + case (NET_HEADER_FIELD_ETH_TYPE):
28402 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
28403 + break;
28404 +
28405 + default:
28406 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28407 + return CC_PC_ILLEGAL;
28408 + }
28409 + break;
28410 +
28411 + case (HEADER_TYPE_VLAN):
28412 + switch (field.vlan)
28413 + {
28414 + case (NET_HEADER_FIELD_VLAN_TCI):
28415 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28416 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28417 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
28418 + else
28419 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28420 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
28421 + break;
28422 +
28423 + default:
28424 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28425 + return CC_PC_ILLEGAL;
28426 + }
28427 + break;
28428 +
28429 + default:
28430 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header "));
28431 + return CC_PC_ILLEGAL;
28432 + }
28433 +
28434 + if (offsetRelevant)
28435 + return CC_PR_OFFSET;
28436 + else
28437 + return CC_PR_WITHOUT_OFFSET;
28438 +}
28439 +
28440 +static void FillAdOfTypeResult(t_Handle h_Ad,
28441 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
28442 + t_FmPcd *p_FmPcd,
28443 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams)
28444 +{
28445 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult *)h_Ad;
28446 + t_Handle h_TmpAd;
28447 + uint32_t tmp = 0, tmpNia = 0;
28448 + uint16_t profileId;
28449 + t_Handle p_AdNewPtr = NULL;
28450 + t_Error err = E_OK;
28451 +
28452 + /* There are 3 cases handled in this routine of building a "result" type AD.
28453 + * Case 1: No Manip. The action descriptor is built within the match table.
28454 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
28455 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
28456 + * initialized and returned here.
28457 + * p_AdResult (within the match table) will be initialized after
28458 + * this routine returns and point to the existing AD.
28459 + * Case 3: Manip exists. The action descriptor is built within the match table.
28460 + * FmPcdManipUpdateAdResultForCc returns a NULL p_AdNewPtr.
28461 + *
28462 + * If statistics were enabled and the statistics mode of this node requires
28463 + * a statistics Ad, it will be placed after the result Ad and before the
28464 + * manip Ad, if manip Ad exists here.
28465 + */
28466 +
28467 + /* As default, the "new" ptr is the current one. i.e. the content of the result
28468 + * AD will be written into the match table itself (case (1))*/
28469 + p_AdNewPtr = p_AdResult;
28470 +
28471 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
28472 + if (p_FmPcdCcStatsParams)
28473 + {
28474 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
28475 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
28476 +
28477 + /* Swapping addresses between statistics Ad and the current lookup AD addresses */
28478 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
28479 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
28480 + h_Ad = h_TmpAd;
28481 +
28482 + p_AdNewPtr = h_Ad;
28483 + p_AdResult = h_Ad;
28484 +
28485 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
28486 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
28487 + }
28488 +
28489 + /* Create manip and return p_AdNewPtr to either a new descriptor or NULL */
28490 + if (p_CcNextEngineParams->h_Manip)
28491 + FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip,
28492 + p_CcNextEngineParams, h_Ad, &p_AdNewPtr);
28493 +
28494 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
28495 + if (p_AdNewPtr)
28496 + {
28497 + /* case (1) and (2) */
28498 + switch (p_CcNextEngineParams->nextEngine)
28499 + {
28500 + case (e_FM_PCD_DONE):
28501 + if (p_CcNextEngineParams->params.enqueueParams.action
28502 + == e_FM_PCD_ENQ_FRAME)
28503 + {
28504 + if (p_CcNextEngineParams->params.enqueueParams.overrideFqid)
28505 + {
28506 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28507 + tmp |=
28508 + p_CcNextEngineParams->params.enqueueParams.newFqid;
28509 +#if (DPAA_VERSION >= 11)
28510 + tmp |=
28511 + (p_CcNextEngineParams->params.enqueueParams.newRelativeStorageProfileId
28512 + & FM_PCD_AD_RESULT_VSP_MASK)
28513 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28514 +#endif /* (DPAA_VERSION >= 11) */
28515 + }
28516 + else
28517 + {
28518 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28519 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28520 + }
28521 + }
28522 +
28523 + if (p_CcNextEngineParams->params.enqueueParams.action
28524 + == e_FM_PCD_DROP_FRAME)
28525 + tmpNia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
28526 + else
28527 + tmpNia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
28528 + break;
28529 +
28530 + case (e_FM_PCD_KG):
28531 + if (p_CcNextEngineParams->params.kgParams.overrideFqid)
28532 + {
28533 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28534 + tmp |= p_CcNextEngineParams->params.kgParams.newFqid;
28535 +#if (DPAA_VERSION >= 11)
28536 + tmp |=
28537 + (p_CcNextEngineParams->params.kgParams.newRelativeStorageProfileId
28538 + & FM_PCD_AD_RESULT_VSP_MASK)
28539 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28540 +#endif /* (DPAA_VERSION >= 11) */
28541 + }
28542 + else
28543 + {
28544 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28545 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28546 + }
28547 + tmpNia = NIA_KG_DIRECT;
28548 + tmpNia |= NIA_ENG_KG;
28549 + tmpNia |= NIA_KG_CC_EN;
28550 + tmpNia |= FmPcdKgGetSchemeId(
28551 + p_CcNextEngineParams->params.kgParams.h_DirectScheme);
28552 + break;
28553 +
28554 + case (e_FM_PCD_PLCR):
28555 + if (p_CcNextEngineParams->params.plcrParams.overrideParams)
28556 + {
28557 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28558 +
28559 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
28560 + if (p_CcNextEngineParams->params.plcrParams.sharedProfile)
28561 + {
28562 + tmpNia |= NIA_PLCR_ABSOLUTE;
28563 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(
28564 + (t_Handle)p_FmPcd,
28565 + e_FM_PCD_PLCR_SHARED,
28566 + NULL,
28567 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId,
28568 + &profileId);
28569 +
28570 + if (err != E_OK) {
28571 + REPORT_ERROR(MAJOR, err, NO_MSG);
28572 + return;
28573 + }
28574 +
28575 + }
28576 + else
28577 + profileId =
28578 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28579 +
28580 + tmp |= p_CcNextEngineParams->params.plcrParams.newFqid;
28581 +#if (DPAA_VERSION >= 11)
28582 + tmp |=
28583 + (p_CcNextEngineParams->params.plcrParams.newRelativeStorageProfileId
28584 + & FM_PCD_AD_RESULT_VSP_MASK)
28585 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28586 +#endif /* (DPAA_VERSION >= 11) */
28587 + WRITE_UINT32(
28588 + p_AdResult->plcrProfile,
28589 + (uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT));
28590 + }
28591 + else
28592 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28593 +
28594 + tmpNia |=
28595 + NIA_ENG_PLCR
28596 + | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28597 + break;
28598 +
28599 + default:
28600 + return;
28601 + }WRITE_UINT32(p_AdResult->fqid, tmp);
28602 +
28603 + if (p_CcNextEngineParams->h_Manip)
28604 + {
28605 + tmp = GET_UINT32(p_AdResult->plcrProfile);
28606 + tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr)
28607 + - (p_FmPcd->physicalMuramBase)) >> 4;
28608 + WRITE_UINT32(p_AdResult->plcrProfile, tmp);
28609 +
28610 + tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE;
28611 + tmpNia |= FM_PCD_AD_RESULT_NADEN;
28612 + }
28613 +
28614 +#if (DPAA_VERSION >= 11)
28615 + tmpNia |= FM_PCD_AD_RESULT_NO_OM_VSPE;
28616 +#endif /* (DPAA_VERSION >= 11) */
28617 + WRITE_UINT32(p_AdResult->nia, tmpNia);
28618 + }
28619 +}
28620 +
28621 +static t_Error CcUpdateParams(t_Handle h_FmPcd, t_Handle h_PcdParams,
28622 + t_Handle h_FmPort, t_Handle h_FmTree,
28623 + bool validate)
28624 +{
28625 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
28626 +
28627 + return CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
28628 + p_CcTree->keyAndNextEngineParams,
28629 + p_CcTree->numOfEntries,
28630 + UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), validate, 0,
28631 + h_FmTree, FALSE);
28632 +}
28633 +
28634 +
28635 +static void ReleaseNewNodeCommonPart(
28636 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28637 +{
28638 + if (p_AdditionalInfo->p_AdTableNew)
28639 + FM_MURAM_FreeMem(
28640 + FmPcdGetMuramHandle(
28641 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28642 + p_AdditionalInfo->p_AdTableNew);
28643 +
28644 + if (p_AdditionalInfo->p_KeysMatchTableNew)
28645 + FM_MURAM_FreeMem(
28646 + FmPcdGetMuramHandle(
28647 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28648 + p_AdditionalInfo->p_KeysMatchTableNew);
28649 +}
28650 +
28651 +static t_Error UpdateGblMask(t_FmPcdCcNode *p_CcNode, uint8_t keySize,
28652 + uint8_t *p_Mask)
28653 +{
28654 + uint8_t prvGlblMaskSize = p_CcNode->glblMaskSize;
28655 +
28656 + if (p_Mask && !p_CcNode->glblMaskUpdated && (keySize <= 4)
28657 + && !p_CcNode->lclMask)
28658 + {
28659 + if (p_CcNode->parseCode && (p_CcNode->parseCode != CC_PC_FF_TCI1)
28660 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
28661 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
28662 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
28663 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
28664 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
28665 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
28666 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
28667 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2))
28668 + {
28669 + p_CcNode->glblMaskSize = 0;
28670 + p_CcNode->lclMask = TRUE;
28671 + }
28672 + else
28673 + {
28674 + memcpy(p_CcNode->p_GlblMask, p_Mask, (sizeof(uint8_t)) * keySize);
28675 + p_CcNode->glblMaskUpdated = TRUE;
28676 + p_CcNode->glblMaskSize = 4;
28677 + }
28678 + }
28679 + else
28680 + if (p_Mask && (keySize <= 4) && !p_CcNode->lclMask)
28681 + {
28682 + if (memcmp(p_CcNode->p_GlblMask, p_Mask, keySize) != 0)
28683 + {
28684 + p_CcNode->lclMask = TRUE;
28685 + p_CcNode->glblMaskSize = 0;
28686 + }
28687 + }
28688 + else
28689 + if (!p_Mask && p_CcNode->glblMaskUpdated && (keySize <= 4))
28690 + {
28691 + uint32_t tmpMask = 0xffffffff;
28692 + if (memcmp(p_CcNode->p_GlblMask, &tmpMask, 4) != 0)
28693 + {
28694 + p_CcNode->lclMask = TRUE;
28695 + p_CcNode->glblMaskSize = 0;
28696 + }
28697 + }
28698 + else
28699 + if (p_Mask)
28700 + {
28701 + p_CcNode->lclMask = TRUE;
28702 + p_CcNode->glblMaskSize = 0;
28703 + }
28704 +
28705 + /* In static mode (maxNumOfKeys > 0), local mask is supported
28706 + only is mask support was enabled at initialization */
28707 + if (p_CcNode->maxNumOfKeys && (!p_CcNode->maskSupport) && p_CcNode->lclMask)
28708 + {
28709 + p_CcNode->lclMask = FALSE;
28710 + p_CcNode->glblMaskSize = prvGlblMaskSize;
28711 + return ERROR_CODE(E_NOT_SUPPORTED);
28712 + }
28713 +
28714 + return E_OK;
28715 +}
28716 +
28717 +static __inline__ t_Handle GetNewAd(t_Handle h_FmPcdCcNodeOrTree, bool isTree)
28718 +{
28719 + t_FmPcd *p_FmPcd;
28720 + t_Handle h_Ad;
28721 +
28722 + if (isTree)
28723 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcTree *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28724 + else
28725 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28726 +
28727 + if ((isTree && p_FmPcd->p_CcShadow)
28728 + || (!isTree && ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->maxNumOfKeys))
28729 + {
28730 + /* The allocated shadow is divided as follows:
28731 + 0 . . . 16 . . .
28732 + ---------------------------------------------------
28733 + | Shadow | Shadow Keys | Shadow Next |
28734 + | Ad | Match Table | Engine Table |
28735 + | (16 bytes) | (maximal size) | (maximal size) |
28736 + ---------------------------------------------------
28737 + */
28738 + if (!p_FmPcd->p_CcShadow)
28739 + {
28740 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
28741 + return NULL;
28742 + }
28743 +
28744 + h_Ad = p_FmPcd->p_CcShadow;
28745 + }
28746 + else
28747 + {
28748 + h_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
28749 + FM_PCD_CC_AD_ENTRY_SIZE,
28750 + FM_PCD_CC_AD_TABLE_ALIGN);
28751 + if (!h_Ad)
28752 + {
28753 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptor"));
28754 + return NULL;
28755 + }
28756 + }
28757 +
28758 + return h_Ad;
28759 +}
28760 +
28761 +static t_Error BuildNewNodeCommonPart(
28762 + t_FmPcdCcNode *p_CcNode, int *size,
28763 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28764 +{
28765 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
28766 +
28767 + if (p_CcNode->lclMask)
28768 + *size = 2 * p_CcNode->ccKeySizeAccExtraction;
28769 + else
28770 + *size = p_CcNode->ccKeySizeAccExtraction;
28771 +
28772 + if (p_CcNode->maxNumOfKeys == 0)
28773 + {
28774 + p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(
28775 + FmPcdGetMuramHandle(p_FmPcd),
28776 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
28777 + * FM_PCD_CC_AD_ENTRY_SIZE),
28778 + FM_PCD_CC_AD_TABLE_ALIGN);
28779 + if (!p_AdditionalInfo->p_AdTableNew)
28780 + RETURN_ERROR(
28781 + MAJOR, E_NO_MEMORY,
28782 + ("MURAM allocation for CC node action descriptors table"));
28783 +
28784 + p_AdditionalInfo->p_KeysMatchTableNew = (t_Handle)FM_MURAM_AllocMem(
28785 + FmPcdGetMuramHandle(p_FmPcd),
28786 + (uint32_t)(*size * sizeof(uint8_t)
28787 + * (p_AdditionalInfo->numOfKeys + 1)),
28788 + FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
28789 + if (!p_AdditionalInfo->p_KeysMatchTableNew)
28790 + {
28791 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
28792 + p_AdditionalInfo->p_AdTableNew);
28793 + p_AdditionalInfo->p_AdTableNew = NULL;
28794 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
28795 + ("MURAM allocation for CC node key match table"));
28796 + }
28797 +
28798 + MemSet8(
28799 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
28800 + 0,
28801 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
28802 + * FM_PCD_CC_AD_ENTRY_SIZE));
28803 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
28804 + *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1));
28805 + }
28806 + else
28807 + {
28808 + /* The allocated shadow is divided as follows:
28809 + 0 . . . 16 . . .
28810 + ---------------------------------------------------
28811 + | Shadow | Shadow Keys | Shadow Next |
28812 + | Ad | Match Table | Engine Table |
28813 + | (16 bytes) | (maximal size) | (maximal size) |
28814 + ---------------------------------------------------
28815 + */
28816 +
28817 + if (!p_FmPcd->p_CcShadow)
28818 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
28819 +
28820 + p_AdditionalInfo->p_KeysMatchTableNew =
28821 + PTR_MOVE(p_FmPcd->p_CcShadow, FM_PCD_CC_AD_ENTRY_SIZE);
28822 + p_AdditionalInfo->p_AdTableNew =
28823 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, p_CcNode->keysMatchTableMaxSize);
28824 +
28825 + MemSet8(
28826 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
28827 + 0,
28828 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
28829 + * FM_PCD_CC_AD_ENTRY_SIZE));
28830 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
28831 + (*size) * sizeof(uint8_t) * (p_CcNode->maxNumOfKeys));
28832 + }
28833 +
28834 + p_AdditionalInfo->p_AdTableOld = p_CcNode->h_AdTable;
28835 + p_AdditionalInfo->p_KeysMatchTableOld = p_CcNode->h_KeysMatchTable;
28836 +
28837 + return E_OK;
28838 +}
28839 +
28840 +static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(
28841 + t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
28842 + t_FmPcdCcKeyParams *p_KeyParams,
28843 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add)
28844 +{
28845 + t_Error err = E_OK;
28846 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
28847 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
28848 + int size;
28849 + int i = 0, j = 0;
28850 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
28851 + uint32_t requiredAction = 0;
28852 + bool prvLclMask;
28853 + t_CcNodeInformation *p_CcNodeInformation;
28854 + t_FmPcdCcStatsParams statsParams = { 0 };
28855 + t_List *p_Pos;
28856 + t_FmPcdStatsObj *p_StatsObj;
28857 +
28858 + /* Check that new NIA is legal */
28859 + err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams,
28860 + p_CcNode->statisticsMode);
28861 + if (err)
28862 + RETURN_ERROR(MAJOR, err, NO_MSG);
28863 +
28864 + prvLclMask = p_CcNode->lclMask;
28865 +
28866 + /* Check that new key is not require update of localMask */
28867 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction,
28868 + p_KeyParams->p_Mask);
28869 + if (err)
28870 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28871 +
28872 + /* Update internal data structure with new next engine for the given index */
28873 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
28874 + &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
28875 +
28876 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key,
28877 + p_KeyParams->p_Key, p_CcNode->userSizeOfExtraction);
28878 +
28879 + if ((p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
28880 + == e_FM_PCD_CC)
28881 + && p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
28882 + {
28883 + err =
28884 + AllocAndFillAdForContLookupManip(
28885 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode);
28886 + if (err)
28887 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28888 + }
28889 +
28890 + if (p_KeyParams->p_Mask)
28891 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask,
28892 + p_KeyParams->p_Mask, p_CcNode->userSizeOfExtraction);
28893 + else
28894 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
28895 + p_CcNode->userSizeOfExtraction);
28896 +
28897 + /* Update numOfKeys */
28898 + if (add)
28899 + p_AdditionalInfo->numOfKeys = (uint8_t)(p_CcNode->numOfKeys + 1);
28900 + else
28901 + p_AdditionalInfo->numOfKeys = (uint8_t)p_CcNode->numOfKeys;
28902 +
28903 + /* Allocate new tables in MURAM: keys match table and action descriptors table */
28904 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
28905 + if (err)
28906 + RETURN_ERROR(MAJOR, err, NO_MSG);
28907 +
28908 + /* Check that manip is legal and what requiredAction is necessary for this manip */
28909 + if (p_KeyParams->ccNextEngineParams.h_Manip)
28910 + {
28911 + err = FmPcdManipCheckParamsForCcNextEngine(
28912 + &p_KeyParams->ccNextEngineParams, &requiredAction);
28913 + if (err)
28914 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28915 + }
28916 +
28917 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
28918 + requiredAction;
28919 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
28920 + UPDATE_CC_WITH_TREE;
28921 +
28922 + /* Update new Ad and new Key Table according to new requirement */
28923 + i = 0;
28924 + for (j = 0; j < p_AdditionalInfo->numOfKeys; j++)
28925 + {
28926 + p_AdTableNewTmp =
28927 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
28928 +
28929 + if (j == keyIndex)
28930 + {
28931 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
28932 + {
28933 + /* Allocate a statistics object that holds statistics AD and counters.
28934 + - For added key - New statistics AD and counters pointer need to be allocated
28935 + new statistics object. If statistics were enabled, we need to replace the
28936 + existing descriptor with a new descriptor with nullified counters.
28937 + */
28938 + p_StatsObj = GetStatsObj(p_CcNode);
28939 + ASSERT_COND(p_StatsObj);
28940 +
28941 + /* Store allocated statistics object */
28942 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
28943 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
28944 + p_StatsObj;
28945 +
28946 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
28947 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
28948 +#if (DPAA_VERSION >= 11)
28949 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
28950 +
28951 +#endif /* (DPAA_VERSION >= 11) */
28952 +
28953 + /* Building action descriptor for the received new key */
28954 + NextStepAd(p_AdTableNewTmp, &statsParams,
28955 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
28956 + }
28957 + else
28958 + {
28959 + /* Building action descriptor for the received new key */
28960 + NextStepAd(p_AdTableNewTmp, NULL,
28961 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
28962 + }
28963 +
28964 + /* Copy the received new key into keys match table */
28965 + p_KeysMatchTableNewTmp =
28966 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size*sizeof(uint8_t));
28967 +
28968 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key,
28969 + p_CcNode->userSizeOfExtraction);
28970 +
28971 + /* Update mask for the received new key */
28972 + if (p_CcNode->lclMask)
28973 + {
28974 + if (p_KeyParams->p_Mask)
28975 + {
28976 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
28977 + p_CcNode->ccKeySizeAccExtraction),
28978 + p_KeyParams->p_Mask,
28979 + p_CcNode->userSizeOfExtraction);
28980 + }
28981 + else
28982 + if (p_CcNode->ccKeySizeAccExtraction > 4)
28983 + {
28984 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
28985 + p_CcNode->ccKeySizeAccExtraction),
28986 + 0xff, p_CcNode->userSizeOfExtraction);
28987 + }
28988 + else
28989 + {
28990 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
28991 + p_CcNode->ccKeySizeAccExtraction),
28992 + p_CcNode->p_GlblMask,
28993 + p_CcNode->userSizeOfExtraction);
28994 + }
28995 + }
28996 +
28997 + /* If key modification requested, the old entry is omitted and replaced by the new parameters */
28998 + if (!add)
28999 + i++;
29000 + }
29001 + else
29002 + {
29003 + /* Copy existing action descriptors to the newly allocated Ad table */
29004 + p_AdTableOldTmp =
29005 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
29006 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp,
29007 + FM_PCD_CC_AD_ENTRY_SIZE);
29008 +
29009 + /* Copy existing keys and their masks to the newly allocated keys match table */
29010 + p_KeysMatchTableNewTmp =
29011 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29012 + p_KeysMatchTableOldTmp =
29013 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i * size * sizeof(uint8_t));
29014 +
29015 + if (p_CcNode->lclMask)
29016 + {
29017 + if (prvLclMask)
29018 + {
29019 + MemCpy8(
29020 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29021 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
29022 + p_CcNode->ccKeySizeAccExtraction);
29023 + }
29024 + else
29025 + {
29026 + p_KeysMatchTableOldTmp =
29027 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
29028 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
29029 +
29030 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29031 + {
29032 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29033 + p_CcNode->ccKeySizeAccExtraction),
29034 + 0xff, p_CcNode->userSizeOfExtraction);
29035 + }
29036 + else
29037 + {
29038 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29039 + p_CcNode->ccKeySizeAccExtraction),
29040 + p_CcNode->p_GlblMask,
29041 + p_CcNode->userSizeOfExtraction);
29042 + }
29043 + }
29044 + }
29045 +
29046 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29047 + p_CcNode->ccKeySizeAccExtraction);
29048 +
29049 + i++;
29050 + }
29051 + }
29052 +
29053 + /* Miss action descriptor */
29054 + p_AdTableNewTmp =
29055 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
29056 + p_AdTableOldTmp =
29057 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i * FM_PCD_CC_AD_ENTRY_SIZE);
29058 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29059 +
29060 + if (!LIST_IsEmpty(&p_CcNode->ccTreesLst))
29061 + {
29062 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
29063 + {
29064 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29065 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
29066 + /* Update the manipulation which has to be updated from parameters of the port */
29067 + /* It's has to be updated with restrictions defined in the function */
29068 + err =
29069 + SetRequiredAction(
29070 + p_CcNode->h_FmPcd,
29071 + p_CcNode->shadowAction
29072 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29073 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29074 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
29075 + 1, p_CcNodeInformation->h_CcNode);
29076 + if (err)
29077 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29078 +
29079 + err =
29080 + CcUpdateParam(
29081 + p_CcNode->h_FmPcd,
29082 + NULL,
29083 + NULL,
29084 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29085 + 1,
29086 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
29087 + TRUE, p_CcNodeInformation->index,
29088 + p_CcNodeInformation->h_CcNode, TRUE);
29089 + if (err)
29090 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29091 + }
29092 + }
29093 +
29094 + if (p_CcNode->lclMask)
29095 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
29096 +
29097 + if (p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC)
29098 + p_AdditionalInfo->h_NodeForAdd =
29099 + p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode;
29100 + if (p_KeyParams->ccNextEngineParams.h_Manip)
29101 + p_AdditionalInfo->h_ManipForAdd =
29102 + p_KeyParams->ccNextEngineParams.h_Manip;
29103 +
29104 +#if (DPAA_VERSION >= 11)
29105 + if ((p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_FR)
29106 + && (p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic))
29107 + p_AdditionalInfo->h_FrmReplicForAdd =
29108 + p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic;
29109 +#endif /* (DPAA_VERSION >= 11) */
29110 +
29111 + if (!add)
29112 + {
29113 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29114 + == e_FM_PCD_CC)
29115 + p_AdditionalInfo->h_NodeForRmv =
29116 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29117 +
29118 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29119 + p_AdditionalInfo->h_ManipForRmv =
29120 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29121 +
29122 + /* If statistics were previously enabled, store the old statistics object to be released */
29123 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29124 + {
29125 + p_AdditionalInfo->p_StatsObjForRmv =
29126 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29127 + }
29128 +
29129 +#if (DPAA_VERSION >= 11)
29130 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29131 + == e_FM_PCD_FR)
29132 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29133 + p_AdditionalInfo->h_FrmReplicForRmv =
29134 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29135 +#endif /* (DPAA_VERSION >= 11) */
29136 + }
29137 +
29138 + return E_OK;
29139 +}
29140 +
29141 +static t_Error BuildNewNodeRemoveKey(
29142 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
29143 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29144 +{
29145 + int i = 0, j = 0;
29146 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29147 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29148 + int size;
29149 + t_Error err = E_OK;
29150 +
29151 + /*save new numOfKeys*/
29152 + p_AdditionalInfo->numOfKeys = (uint16_t)(p_CcNode->numOfKeys - 1);
29153 +
29154 + /*function which allocates in the memory new KeyTbl, AdTbl*/
29155 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29156 + if (err)
29157 + RETURN_ERROR(MAJOR, err, NO_MSG);
29158 +
29159 + /*update new Ad and new Key Table according to new requirement*/
29160 + for (i = 0, j = 0; j < p_CcNode->numOfKeys; i++, j++)
29161 + {
29162 + if (j == keyIndex)
29163 + j++;
29164 +
29165 + if (j == p_CcNode->numOfKeys)
29166 + break;
29167 + p_AdTableNewTmp =
29168 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29169 + p_AdTableOldTmp =
29170 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29171 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29172 +
29173 + p_KeysMatchTableOldTmp =
29174 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j * size * sizeof(uint8_t));
29175 + p_KeysMatchTableNewTmp =
29176 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i * size * sizeof(uint8_t));
29177 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29178 + size * sizeof(uint8_t));
29179 + }
29180 +
29181 + p_AdTableNewTmp =
29182 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29183 + p_AdTableOldTmp =
29184 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29185 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29186 +
29187 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29188 + == e_FM_PCD_CC)
29189 + p_AdditionalInfo->h_NodeForRmv =
29190 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29191 +
29192 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29193 + p_AdditionalInfo->h_ManipForRmv =
29194 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29195 +
29196 + /* If statistics were previously enabled, store the old statistics object to be released */
29197 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29198 + {
29199 + p_AdditionalInfo->p_StatsObjForRmv =
29200 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29201 + }
29202 +
29203 +#if (DPAA_VERSION >= 11)
29204 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29205 + == e_FM_PCD_FR)
29206 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29207 + p_AdditionalInfo->h_FrmReplicForRmv =
29208 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29209 +#endif /* (DPAA_VERSION >= 11) */
29210 +
29211 + return E_OK;
29212 +}
29213 +
29214 +static t_Error BuildNewNodeModifyKey(
29215 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, uint8_t *p_Key,
29216 + uint8_t *p_Mask, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29217 +{
29218 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
29219 + t_Error err = E_OK;
29220 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29221 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29222 + int size;
29223 + int i = 0, j = 0;
29224 + bool prvLclMask;
29225 + t_FmPcdStatsObj *p_StatsObj, tmpStatsObj;
29226 + p_AdditionalInfo->numOfKeys = p_CcNode->numOfKeys;
29227 +
29228 + prvLclMask = p_CcNode->lclMask;
29229 +
29230 + /* Check that new key is not require update of localMask */
29231 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, p_Mask);
29232 + if (err)
29233 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29234 +
29235 + /* Update internal data structure with new next engine for the given index */
29236 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, p_Key,
29237 + p_CcNode->userSizeOfExtraction);
29238 +
29239 + if (p_Mask)
29240 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, p_Mask,
29241 + p_CcNode->userSizeOfExtraction);
29242 + else
29243 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
29244 + p_CcNode->userSizeOfExtraction);
29245 +
29246 + /*function which build in the memory new KeyTbl, AdTbl*/
29247 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29248 + if (err)
29249 + RETURN_ERROR(MAJOR, err, NO_MSG);
29250 +
29251 + /*fill the New AdTable and New KeyTable*/
29252 + for (j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++)
29253 + {
29254 + p_AdTableNewTmp =
29255 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
29256 + p_AdTableOldTmp =
29257 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
29258 +
29259 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29260 +
29261 + if (j == keyIndex)
29262 + {
29263 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
29264 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29265 + {
29266 + /* As statistics were enabled, we need to update the existing
29267 + statistics descriptor with a new nullified counters. */
29268 + p_StatsObj = GetStatsObj(p_CcNode);
29269 + ASSERT_COND(p_StatsObj);
29270 +
29271 + SetStatsCounters(
29272 + p_AdTableNewTmp,
29273 + (uint32_t)((XX_VirtToPhys(p_StatsObj->h_StatsCounters)
29274 + - p_FmPcd->physicalMuramBase)));
29275 +
29276 + tmpStatsObj.h_StatsAd = p_StatsObj->h_StatsAd;
29277 + tmpStatsObj.h_StatsCounters = p_StatsObj->h_StatsCounters;
29278 +
29279 + /* As we need to replace only the counters, we build a new statistics
29280 + object that holds the old AD and the new counters - this will be the
29281 + currently used statistics object.
29282 + The newly allocated AD is not required and may be released back to
29283 + the available objects with the previous counters pointer. */
29284 + p_StatsObj->h_StatsAd =
29285 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29286 +
29287 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd =
29288 + tmpStatsObj.h_StatsAd;
29289 +
29290 + /* Store allocated statistics object */
29291 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29292 + p_StatsObj;
29293 +
29294 + /* As statistics were previously enabled, store the old statistics object to be released */
29295 + p_AdditionalInfo->p_StatsObjForRmv =
29296 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29297 + }
29298 +
29299 + p_KeysMatchTableNewTmp =
29300 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29301 +
29302 + MemCpy8(p_KeysMatchTableNewTmp, p_Key,
29303 + p_CcNode->userSizeOfExtraction);
29304 +
29305 + if (p_CcNode->lclMask)
29306 + {
29307 + if (p_Mask)
29308 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29309 + p_CcNode->ccKeySizeAccExtraction),
29310 + p_Mask, p_CcNode->userSizeOfExtraction);
29311 + else
29312 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29313 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29314 + p_CcNode->ccKeySizeAccExtraction),
29315 + 0xff, p_CcNode->userSizeOfExtraction);
29316 + else
29317 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29318 + p_CcNode->ccKeySizeAccExtraction),
29319 + p_CcNode->p_GlblMask,
29320 + p_CcNode->userSizeOfExtraction);
29321 + }
29322 + }
29323 + else
29324 + {
29325 + p_KeysMatchTableNewTmp =
29326 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29327 + p_KeysMatchTableOldTmp =
29328 + PTR_MOVE(p_CcNode->h_KeysMatchTable, i * size * sizeof(uint8_t));
29329 +
29330 + if (p_CcNode->lclMask)
29331 + {
29332 + if (prvLclMask)
29333 + MemCpy8(
29334 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29335 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
29336 + p_CcNode->userSizeOfExtraction);
29337 + else
29338 + {
29339 + p_KeysMatchTableOldTmp =
29340 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
29341 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
29342 +
29343 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29344 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29345 + p_CcNode->ccKeySizeAccExtraction),
29346 + 0xff, p_CcNode->userSizeOfExtraction);
29347 + else
29348 + MemCpy8(
29349 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29350 + p_CcNode->p_GlblMask,
29351 + p_CcNode->userSizeOfExtraction);
29352 + }
29353 + }
29354 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29355 + p_CcNode->ccKeySizeAccExtraction);
29356 + }
29357 + }
29358 +
29359 + p_AdTableNewTmp =
29360 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
29361 + p_AdTableOldTmp = PTR_MOVE(p_CcNode->h_AdTable, i * FM_PCD_CC_AD_ENTRY_SIZE);
29362 +
29363 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29364 +
29365 + return E_OK;
29366 +}
29367 +
29368 +static t_Error BuildNewNodeModifyNextEngine(
29369 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29370 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst,
29371 + t_List *h_NewLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29372 +{
29373 + t_Error err = E_OK;
29374 + uint32_t requiredAction = 0;
29375 + t_List *p_Pos;
29376 + t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo;
29377 + t_Handle p_Ad;
29378 + t_FmPcdCcNode *p_FmPcdCcNode1 = NULL;
29379 + t_FmPcdCcTree *p_FmPcdCcTree = NULL;
29380 + t_FmPcdStatsObj *p_StatsObj;
29381 + t_FmPcdCcStatsParams statsParams = { 0 };
29382 +
29383 + ASSERT_COND(p_CcNextEngineParams);
29384 +
29385 + /* check that new NIA is legal */
29386 + if (!p_AdditionalInfo->tree)
29387 + err = ValidateNextEngineParams(
29388 + h_FmPcd, p_CcNextEngineParams,
29389 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->statisticsMode);
29390 + else
29391 + /* Statistics are not supported for CC root */
29392 + err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams,
29393 + e_FM_PCD_CC_STATS_MODE_NONE);
29394 + if (err)
29395 + RETURN_ERROR(MAJOR, err, NO_MSG);
29396 +
29397 + /* Update internal data structure for next engine per index (index - key) */
29398 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
29399 + p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
29400 +
29401 + /* Check that manip is legal and what requiredAction is necessary for this manip */
29402 + if (p_CcNextEngineParams->h_Manip)
29403 + {
29404 + err = FmPcdManipCheckParamsForCcNextEngine(p_CcNextEngineParams,
29405 + &requiredAction);
29406 + if (err)
29407 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29408 + }
29409 +
29410 + if (!p_AdditionalInfo->tree)
29411 + {
29412 + p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29413 + p_AdditionalInfo->numOfKeys = p_FmPcdCcNode1->numOfKeys;
29414 + p_Ad = p_FmPcdCcNode1->h_AdTable;
29415 +
29416 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29417 + == e_FM_PCD_CC)
29418 + p_AdditionalInfo->h_NodeForRmv =
29419 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29420 +
29421 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29422 + p_AdditionalInfo->h_ManipForRmv =
29423 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29424 +
29425 +#if (DPAA_VERSION >= 11)
29426 + if ((p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29427 + == e_FM_PCD_FR)
29428 + && (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29429 + p_AdditionalInfo->h_FrmReplicForRmv =
29430 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29431 +#endif /* (DPAA_VERSION >= 11) */
29432 + }
29433 + else
29434 + {
29435 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29436 + p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
29437 +
29438 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29439 + == e_FM_PCD_CC)
29440 + p_AdditionalInfo->h_NodeForRmv =
29441 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29442 +
29443 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29444 + p_AdditionalInfo->h_ManipForRmv =
29445 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29446 +
29447 +#if (DPAA_VERSION >= 11)
29448 + if ((p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29449 + == e_FM_PCD_FR)
29450 + && (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29451 + p_AdditionalInfo->h_FrmReplicForRmv =
29452 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29453 +#endif /* (DPAA_VERSION >= 11) */
29454 + }
29455 +
29456 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29457 + && p_CcNextEngineParams->h_Manip)
29458 + {
29459 + err = AllocAndFillAdForContLookupManip(
29460 + p_CcNextEngineParams->params.ccParams.h_CcNode);
29461 + if (err)
29462 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29463 + }
29464 +
29465 + ASSERT_COND(p_Ad);
29466 +
29467 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29468 + ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE);
29469 +
29470 + /* If statistics were enabled, this Ad is the statistics Ad. Need to follow its
29471 + nextAction to retrieve the actual Nia-Ad. If statistics should remain enabled,
29472 + only the actual Nia-Ad should be modified. */
29473 + if ((!p_AdditionalInfo->tree)
29474 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29475 + && (p_CcNextEngineParams->statisticsEn))
29476 + ccNodeInfo.h_CcNode =
29477 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29478 +
29479 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29480 +
29481 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29482 + p_Ad = GetNewAd(h_FmPcdCcNodeOrTree, p_AdditionalInfo->tree);
29483 + if (!p_Ad)
29484 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
29485 + ("MURAM allocation for CC node action descriptor"));
29486 + MemSet8((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
29487 +
29488 + /* If statistics were not enabled before, but requested now - Allocate a statistics
29489 + object that holds statistics AD and counters. */
29490 + if ((!p_AdditionalInfo->tree)
29491 + && (!((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29492 + && (p_CcNextEngineParams->statisticsEn))
29493 + {
29494 + p_StatsObj = GetStatsObj((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree);
29495 + ASSERT_COND(p_StatsObj);
29496 +
29497 + /* Store allocated statistics object */
29498 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29499 + p_StatsObj;
29500 +
29501 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
29502 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
29503 +
29504 +#if (DPAA_VERSION >= 11)
29505 + statsParams.h_StatsFLRs =
29506 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_StatsFLRs;
29507 +
29508 +#endif /* (DPAA_VERSION >= 11) */
29509 +
29510 + NextStepAd(p_Ad, &statsParams, p_CcNextEngineParams, h_FmPcd);
29511 + }
29512 + else
29513 + NextStepAd(p_Ad, NULL, p_CcNextEngineParams, h_FmPcd);
29514 +
29515 + ccNodeInfo.h_CcNode = p_Ad;
29516 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
29517 +
29518 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
29519 + requiredAction;
29520 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
29521 + UPDATE_CC_WITH_TREE;
29522 +
29523 + if (!p_AdditionalInfo->tree)
29524 + {
29525 + ASSERT_COND(p_FmPcdCcNode1);
29526 + if (!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst))
29527 + {
29528 + LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst)
29529 + {
29530 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29531 +
29532 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
29533 + /* Update the manipulation which has to be updated from parameters of the port
29534 + it's has to be updated with restrictions defined in the function */
29535 +
29536 + err =
29537 + SetRequiredAction(
29538 + p_FmPcdCcNode1->h_FmPcd,
29539 + p_FmPcdCcNode1->shadowAction
29540 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29541 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29542 + p_Ad, 1, p_CcNodeInformation->h_CcNode);
29543 + if (err)
29544 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29545 +
29546 + err = CcUpdateParam(
29547 + p_FmPcdCcNode1->h_FmPcd, NULL, NULL,
29548 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 1,
29549 + p_Ad, TRUE, p_CcNodeInformation->index,
29550 + p_CcNodeInformation->h_CcNode, TRUE);
29551 + if (err)
29552 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29553 + }
29554 + }
29555 + }
29556 + else
29557 + {
29558 + ASSERT_COND(p_FmPcdCcTree);
29559 +
29560 + err =
29561 + SetRequiredAction(
29562 + h_FmPcd,
29563 + p_FmPcdCcTree->requiredAction
29564 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29565 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29566 + p_Ad, 1, (t_Handle)p_FmPcdCcTree);
29567 + if (err)
29568 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29569 +
29570 + err = CcUpdateParam(h_FmPcd, NULL, NULL,
29571 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29572 + 1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE);
29573 + if (err)
29574 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29575 + }
29576 +
29577 + if (p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29578 + p_AdditionalInfo->h_NodeForAdd =
29579 + p_CcNextEngineParams->params.ccParams.h_CcNode;
29580 + if (p_CcNextEngineParams->h_Manip)
29581 + p_AdditionalInfo->h_ManipForAdd = p_CcNextEngineParams->h_Manip;
29582 +
29583 + /* If statistics were previously enabled, but now are disabled,
29584 + store the old statistics object to be released */
29585 + if ((!p_AdditionalInfo->tree)
29586 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29587 + && (!p_CcNextEngineParams->statisticsEn))
29588 + {
29589 + p_AdditionalInfo->p_StatsObjForRmv =
29590 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj;
29591 +
29592 +
29593 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = NULL;
29594 + }
29595 +#if (DPAA_VERSION >= 11)
29596 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_FR)
29597 + && (p_CcNextEngineParams->params.frParams.h_FrmReplic))
29598 + p_AdditionalInfo->h_FrmReplicForAdd =
29599 + p_CcNextEngineParams->params.frParams.h_FrmReplic;
29600 +#endif /* (DPAA_VERSION >= 11) */
29601 +
29602 + return E_OK;
29603 +}
29604 +
29605 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(
29606 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29607 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29608 +{
29609 + t_CcNodeInformation *p_CcNodeInformation;
29610 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL;
29611 + t_List *p_Pos;
29612 + int i = 0;
29613 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
29614 + t_CcNodeInformation ccNodeInfo;
29615 +
29616 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst)
29617 + {
29618 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29619 + p_NodePtrOnCurrentMdfNode =
29620 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
29621 +
29622 + ASSERT_COND(p_NodePtrOnCurrentMdfNode);
29623 +
29624 + /* Search in the previous node which exact index points on this current modified node for getting AD */
29625 + for (i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++)
29626 + {
29627 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29628 + == e_FM_PCD_CC)
29629 + {
29630 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29631 + == (t_Handle)p_CrntMdfNode)
29632 + {
29633 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
29634 + p_AdTablePtOnCrntCurrentMdfNode = p_CrntMdfNode->h_Ad;
29635 + else
29636 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj)
29637 + p_AdTablePtOnCrntCurrentMdfNode =
29638 + p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
29639 + else
29640 + p_AdTablePtOnCrntCurrentMdfNode =
29641 + PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
29642 +
29643 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29644 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
29645 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29646 +
29647 + if (!(*p_NextEngineParams))
29648 + *p_NextEngineParams =
29649 + &p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29650 + }
29651 + }
29652 + }
29653 +
29654 + ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys);
29655 + }
29656 +}
29657 +
29658 +static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(
29659 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29660 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29661 +{
29662 + t_CcNodeInformation *p_CcNodeInformation;
29663 + t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL;
29664 + t_List *p_Pos;
29665 + int i = 0;
29666 + t_Handle p_AdTableTmp;
29667 + t_CcNodeInformation ccNodeInfo;
29668 +
29669 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst)
29670 + {
29671 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29672 + p_TreePtrOnCurrentMdfNode =
29673 + (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode;
29674 +
29675 + ASSERT_COND(p_TreePtrOnCurrentMdfNode);
29676 +
29677 + /*search in the trees which exact index points on this current modified node for getting AD */
29678 + for (i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++)
29679 + {
29680 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29681 + == e_FM_PCD_CC)
29682 + {
29683 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29684 + == (t_Handle)p_CrntMdfNode)
29685 + {
29686 + p_AdTableTmp =
29687 + UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE);
29688 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29689 + ccNodeInfo.h_CcNode = p_AdTableTmp;
29690 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29691 +
29692 + if (!(*p_NextEngineParams))
29693 + *p_NextEngineParams =
29694 + &p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29695 + }
29696 + }
29697 + }
29698 +
29699 + ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries);
29700 + }
29701 +}
29702 +
29703 +static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart(
29704 + t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29705 + e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree)
29706 +{
29707 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams;
29708 + int i = 0, j = 0;
29709 + bool wasUpdate = FALSE;
29710 + t_FmPcdCcNode *p_CcNode = NULL;
29711 + t_FmPcdCcTree *p_FmPcdCcTree;
29712 + uint16_t numOfKeys;
29713 + t_FmPcdCcKeyAndNextEngineParams *p_KeyAndNextEngineParams;
29714 +
29715 + SANITY_CHECK_RETURN_VALUE(h_FmPcdCcNodeOrTree, E_INVALID_HANDLE, NULL);
29716 +
29717 + if (!tree)
29718 + {
29719 + p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29720 + numOfKeys = p_CcNode->numOfKeys;
29721 +
29722 + /* node has to be pointed by another node or tree */
29723 +
29724 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29725 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (numOfKeys + 1));
29726 + if (!p_KeyAndNextEngineParams)
29727 + {
29728 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29729 + return NULL;
29730 + }
29731 + memcpy(p_KeyAndNextEngineParams, p_CcNode->keyAndNextEngineParams,
29732 + (numOfKeys + 1) * sizeof(t_FmPcdCcKeyAndNextEngineParams));
29733 +
29734 + if (ttlCheck)
29735 + {
29736 + if ((p_CcNode->parseCode == CC_PC_FF_IPV4TTL)
29737 + || (p_CcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT))
29738 + {
29739 + XX_Free(p_KeyAndNextEngineParams);
29740 + 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"));
29741 + return NULL;
29742 + }
29743 + }
29744 +
29745 + if (hashCheck)
29746 + {
29747 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
29748 + {
29749 + XX_Free(p_KeyAndNextEngineParams);
29750 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_GENERIC_IC_HASH_INDEXED can not be used for this operation"));
29751 + return NULL;
29752 + }
29753 + }
29754 + }
29755 + else
29756 + {
29757 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29758 + numOfKeys = p_FmPcdCcTree->numOfEntries;
29759 +
29760 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29761 + sizeof(t_FmPcdCcKeyAndNextEngineParams)
29762 + * FM_PCD_MAX_NUM_OF_CC_GROUPS);
29763 + if (!p_KeyAndNextEngineParams)
29764 + {
29765 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29766 + return NULL;
29767 + }
29768 + memcpy(p_KeyAndNextEngineParams,
29769 + p_FmPcdCcTree->keyAndNextEngineParams,
29770 + FM_PCD_MAX_NUM_OF_CC_GROUPS
29771 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
29772 + }
29773 +
29774 + p_FmPcdModifyCcKeyAdditionalParams =
29775 + (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(
29776 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
29777 + if (!p_FmPcdModifyCcKeyAdditionalParams)
29778 + {
29779 + XX_Free(p_KeyAndNextEngineParams);
29780 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED"));
29781 + return NULL;
29782 + }
29783 + memset(p_FmPcdModifyCcKeyAdditionalParams, 0,
29784 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
29785 +
29786 + p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree;
29787 + p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex;
29788 +
29789 + while (i < numOfKeys)
29790 + {
29791 + if ((j == keyIndex) && !wasUpdate)
29792 + {
29793 + if (modifyState == e_MODIFY_STATE_ADD)
29794 + j++;
29795 + else
29796 + if (modifyState == e_MODIFY_STATE_REMOVE)
29797 + i++;
29798 + wasUpdate = TRUE;
29799 + }
29800 + else
29801 + {
29802 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
29803 + p_KeyAndNextEngineParams + i,
29804 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
29805 + i++;
29806 + j++;
29807 + }
29808 + }
29809 +
29810 + if (keyIndex == numOfKeys)
29811 + {
29812 + if (modifyState == e_MODIFY_STATE_ADD)
29813 + j++;
29814 + }
29815 +
29816 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
29817 + p_KeyAndNextEngineParams + numOfKeys,
29818 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
29819 +
29820 + XX_Free(p_KeyAndNextEngineParams);
29821 +
29822 + return p_FmPcdModifyCcKeyAdditionalParams;
29823 +}
29824 +
29825 +static t_Error UpdatePtrWhichPointOnCrntMdfNode(
29826 + t_FmPcdCcNode *p_CcNode,
29827 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
29828 + t_List *h_OldLst, t_List *h_NewLst)
29829 +{
29830 + t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL;
29831 + t_CcNodeInformation ccNodeInfo = { 0 };
29832 + t_Handle h_NewAd;
29833 + t_Handle h_OrigAd = NULL;
29834 +
29835 + /* Building a list of all action descriptors that point to the previous node */
29836 + if (!LIST_IsEmpty(&p_CcNode->ccPrevNodesLst))
29837 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
29838 + &p_NextEngineParams);
29839 +
29840 + if (!LIST_IsEmpty(&p_CcNode->ccTreeIdLst))
29841 + UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
29842 + &p_NextEngineParams);
29843 +
29844 + /* This node must be found as next engine of one of its previous nodes or trees*/
29845 + if (p_NextEngineParams)
29846 + {
29847 + /* Building a new action descriptor that points to the modified node */
29848 + h_NewAd = GetNewAd(p_CcNode, FALSE);
29849 + if (!h_NewAd)
29850 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
29851 + MemSet8(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
29852 +
29853 + h_OrigAd = p_CcNode->h_Ad;
29854 + BuildNewAd(h_NewAd, p_FmPcdModifyCcKeyAdditionalParams, p_CcNode,
29855 + p_NextEngineParams);
29856 +
29857 + ccNodeInfo.h_CcNode = h_NewAd;
29858 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
29859 +
29860 + if (p_NextEngineParams->h_Manip && !h_OrigAd)
29861 + FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE);
29862 + }
29863 + return E_OK;
29864 +}
29865 +
29866 +static void UpdateCcRootOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add)
29867 +{
29868 + ASSERT_COND(p_FmPcdCcTree);
29869 +
29870 + /* this routine must be protected by the calling routine! */
29871 +
29872 + if (add)
29873 + p_FmPcdCcTree->owners++;
29874 + else
29875 + {
29876 + ASSERT_COND(p_FmPcdCcTree->owners);
29877 + p_FmPcdCcTree->owners--;
29878 + }
29879 +}
29880 +
29881 +static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_CcNode)
29882 +{
29883 + t_Error err = E_OK;
29884 + int i = 0;
29885 +
29886 + for (i = 0; i < p_CcNode->numOfKeys; i++)
29887 + {
29888 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
29889 + {
29890 + err =
29891 + FmPcdManipCheckParamsWithCcNodeParams(
29892 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
29893 + (t_Handle)p_CcNode);
29894 + if (err)
29895 + return err;
29896 + }
29897 + }
29898 +
29899 + return err;
29900 +}
29901 +static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode,
29902 + t_FmPcdCcNodeParams *p_CcNodeParam,
29903 + uint32_t *p_NumOfRanges,
29904 + uint32_t *p_CountersArraySize)
29905 +{
29906 + e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode;
29907 + uint32_t i;
29908 +
29909 + UNUSED(p_CcNodeParam);
29910 +
29911 + switch (statisticsMode)
29912 + {
29913 + case e_FM_PCD_CC_STATS_MODE_NONE:
29914 + for (i = 0; i < p_CcNode->numOfKeys; i++)
29915 + if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn)
29916 + RETURN_ERROR(
29917 + MAJOR,
29918 + E_INVALID_VALUE,
29919 + ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i));
29920 + return E_OK;
29921 +
29922 + case e_FM_PCD_CC_STATS_MODE_FRAME:
29923 + case e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME:
29924 + *p_NumOfRanges = 1;
29925 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
29926 + return E_OK;
29927 +
29928 +#if (DPAA_VERSION >= 11)
29929 + case e_FM_PCD_CC_STATS_MODE_RMON:
29930 + {
29931 + uint16_t *p_FrameLengthRanges =
29932 + p_CcNodeParam->keysParams.frameLengthRanges;
29933 + uint32_t i;
29934 +
29935 + if (p_FrameLengthRanges[0] <= 0)
29936 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
29937 +
29938 + if (p_FrameLengthRanges[0] == 0xFFFF)
29939 + {
29940 + *p_NumOfRanges = 1;
29941 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
29942 + return E_OK;
29943 + }
29944 +
29945 + for (i = 1; i < FM_PCD_CC_STATS_MAX_NUM_OF_FLR; i++)
29946 + {
29947 + if (p_FrameLengthRanges[i - 1] >= p_FrameLengthRanges[i])
29948 + RETURN_ERROR(
29949 + MAJOR,
29950 + E_INVALID_VALUE,
29951 + ("Frame length range must be larger at least by 1 from preceding range"));
29952 +
29953 + /* Stop when last range is reached */
29954 + if (p_FrameLengthRanges[i] == 0xFFFF)
29955 + break;
29956 + }
29957 +
29958 + if ((i >= FM_PCD_CC_STATS_MAX_NUM_OF_FLR)
29959 + || (p_FrameLengthRanges[i] != 0xFFFF))
29960 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
29961 + ("Last Frame length range must be 0xFFFF"));
29962 +
29963 + *p_NumOfRanges = i + 1;
29964 +
29965 + /* Allocate an extra counter for byte count, as counters
29966 + array always begins with byte count */
29967 + *p_CountersArraySize = (*p_NumOfRanges + 1)
29968 + * FM_PCD_CC_STATS_COUNTER_SIZE;
29969 +
29970 + }
29971 + return E_OK;
29972 +#endif /* (DPAA_VERSION >= 11) */
29973 +
29974 + default:
29975 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
29976 + }
29977 +}
29978 +
29979 +static t_Error CheckParams(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
29980 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
29981 +{
29982 + int tmp = 0;
29983 + t_FmPcdCcKeyParams *p_KeyParams;
29984 + t_Error err;
29985 + uint32_t requiredAction = 0;
29986 +
29987 + /* Validate statistics parameters */
29988 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
29989 + &(p_CcNode->numOfStatsFLRs),
29990 + &(p_CcNode->countersArraySize));
29991 + if (err)
29992 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
29993 +
29994 + /* Validate next engine parameters on Miss */
29995 + err = ValidateNextEngineParams(
29996 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
29997 + p_CcNode->statisticsMode);
29998 + if (err)
29999 + RETURN_ERROR(MAJOR, err,
30000 + ("For this node MissNextEngineParams are not valid"));
30001 +
30002 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
30003 + {
30004 + err = FmPcdManipCheckParamsForCcNextEngine(
30005 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30006 + &requiredAction);
30007 + if (err)
30008 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30009 + }
30010 +
30011 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
30012 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30013 + sizeof(t_FmPcdCcNextEngineParams));
30014 +
30015 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
30016 + requiredAction;
30017 +
30018 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
30019 + == e_FM_PCD_CC)
30020 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
30021 + {
30022 + err =
30023 + AllocAndFillAdForContLookupManip(
30024 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
30025 + if (err)
30026 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30027 + }
30028 +
30029 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30030 + {
30031 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30032 +
30033 + if (!p_KeyParams->p_Key)
30034 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized"));
30035 +
30036 + err = ValidateNextEngineParams(h_FmPcd,
30037 + &p_KeyParams->ccNextEngineParams,
30038 + p_CcNode->statisticsMode);
30039 + if (err)
30040 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30041 +
30042 + err = UpdateGblMask(p_CcNode, p_CcNodeParam->keysParams.keySize,
30043 + p_KeyParams->p_Mask);
30044 + if (err)
30045 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30046 +
30047 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30048 + {
30049 + err = FmPcdManipCheckParamsForCcNextEngine(
30050 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30051 + if (err)
30052 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30053 + }
30054 +
30055 + /* Store 'key' parameters - key, mask (if passed by the user) */
30056 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].key, p_KeyParams->p_Key,
30057 + p_CcNodeParam->keysParams.keySize);
30058 +
30059 + if (p_KeyParams->p_Mask)
30060 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].mask,
30061 + p_KeyParams->p_Mask, p_CcNodeParam->keysParams.keySize);
30062 + else
30063 + memset((void *)(p_CcNode->keyAndNextEngineParams[tmp].mask), 0xFF,
30064 + p_CcNodeParam->keysParams.keySize);
30065 +
30066 + /* Store next engine parameters */
30067 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30068 + &p_KeyParams->ccNextEngineParams,
30069 + sizeof(t_FmPcdCcNextEngineParams));
30070 +
30071 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
30072 +
30073 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30074 + == e_FM_PCD_CC)
30075 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30076 + {
30077 + err =
30078 + AllocAndFillAdForContLookupManip(
30079 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30080 + if (err)
30081 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30082 + }
30083 + }
30084 +
30085 + if (p_CcNode->maxNumOfKeys)
30086 + {
30087 + if (p_CcNode->maxNumOfKeys < p_CcNode->numOfKeys)
30088 + RETURN_ERROR(
30089 + MAJOR,
30090 + E_INVALID_VALUE,
30091 + ("Number of keys exceed the provided maximal number of keys"));
30092 + }
30093 +
30094 + *isKeyTblAlloc = TRUE;
30095 +
30096 + return E_OK;
30097 +}
30098 +
30099 +static t_Error Ipv4TtlOrIpv6HopLimitCheckParams(
30100 + t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
30101 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
30102 +{
30103 + int tmp = 0;
30104 + t_FmPcdCcKeyParams *p_KeyParams;
30105 + t_Error err;
30106 + uint8_t key = 0x01;
30107 + uint32_t requiredAction = 0;
30108 +
30109 + if (p_CcNode->numOfKeys != 1)
30110 + RETURN_ERROR(
30111 + MAJOR,
30112 + E_INVALID_VALUE,
30113 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'numOfKeys' is 1"));
30114 +
30115 + if ((p_CcNodeParam->keysParams.maxNumOfKeys)
30116 + && (p_CcNodeParam->keysParams.maxNumOfKeys != 1))
30117 + RETURN_ERROR(
30118 + MAJOR,
30119 + E_INVALID_VALUE,
30120 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'maxNumOfKeys' is 1"));
30121 +
30122 + /* Validate statistics parameters */
30123 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30124 + &(p_CcNode->numOfStatsFLRs),
30125 + &(p_CcNode->countersArraySize));
30126 + if (err)
30127 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30128 +
30129 + err = ValidateNextEngineParams(
30130 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30131 + p_CcNodeParam->keysParams.statisticsMode);
30132 + if (err)
30133 + RETURN_ERROR(MAJOR, err,
30134 + ("For this node MissNextEngineParams are not valid"));
30135 +
30136 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
30137 + {
30138 + err = FmPcdManipCheckParamsForCcNextEngine(
30139 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30140 + &requiredAction);
30141 + if (err)
30142 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30143 + }
30144 +
30145 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
30146 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30147 + sizeof(t_FmPcdCcNextEngineParams));
30148 +
30149 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
30150 + requiredAction;
30151 +
30152 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
30153 + == e_FM_PCD_CC)
30154 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
30155 + {
30156 + err =
30157 + AllocAndFillAdForContLookupManip(
30158 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
30159 + if (err)
30160 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30161 + }
30162 +
30163 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30164 + {
30165 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30166 +
30167 + if (p_KeyParams->p_Mask)
30168 + RETURN_ERROR(
30169 + MAJOR,
30170 + E_INVALID_VALUE,
30171 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized"));
30172 +
30173 + if (memcmp(p_KeyParams->p_Key, &key, 1) != 0)
30174 + RETURN_ERROR(
30175 + MAJOR,
30176 + E_INVALID_VALUE,
30177 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1"));
30178 +
30179 + err = ValidateNextEngineParams(h_FmPcd,
30180 + &p_KeyParams->ccNextEngineParams,
30181 + p_CcNode->statisticsMode);
30182 + if (err)
30183 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30184 +
30185 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30186 + {
30187 + err = FmPcdManipCheckParamsForCcNextEngine(
30188 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30189 + if (err)
30190 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30191 + }
30192 +
30193 + /* Store 'key' parameters - key (fixed to 0x01), key size of 1 byte and full mask */
30194 + p_CcNode->keyAndNextEngineParams[tmp].key[0] = key;
30195 + p_CcNode->keyAndNextEngineParams[tmp].mask[0] = 0xFF;
30196 +
30197 + /* Store NextEngine parameters */
30198 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30199 + &p_KeyParams->ccNextEngineParams,
30200 + sizeof(t_FmPcdCcNextEngineParams));
30201 +
30202 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30203 + == e_FM_PCD_CC)
30204 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30205 + {
30206 + err =
30207 + AllocAndFillAdForContLookupManip(
30208 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30209 + if (err)
30210 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30211 + }
30212 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
30213 + }
30214 +
30215 + *isKeyTblAlloc = FALSE;
30216 +
30217 + return E_OK;
30218 +}
30219 +
30220 +static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd,
30221 + t_FmPcdCcNodeParams *p_CcNodeParam,
30222 + t_FmPcdCcNode *p_CcNode,
30223 + bool *isKeyTblAlloc)
30224 +{
30225 + int tmp = 0, countOnes = 0;
30226 + t_FmPcdCcKeyParams *p_KeyParams;
30227 + t_Error err;
30228 + uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask;
30229 + uint16_t countMask = (uint16_t)(glblMask >> 4);
30230 + uint32_t requiredAction = 0;
30231 +
30232 + if (glblMask & 0x000f)
30233 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30234 + ("icIndxMask has to be with last nibble 0"));
30235 +
30236 + while (countMask)
30237 + {
30238 + countOnes++;
30239 + countMask = (uint16_t)(countMask >> 1);
30240 + }
30241 +
30242 + if (!POWER_OF_2(p_CcNode->numOfKeys))
30243 + RETURN_ERROR(
30244 + MAJOR,
30245 + E_INVALID_VALUE,
30246 + ("For Node of the type INDEXED numOfKeys has to be powerOfTwo"));
30247 +
30248 + if (p_CcNode->numOfKeys != ((uint32_t)1 << countOnes))
30249 + RETURN_ERROR(
30250 + MAJOR,
30251 + E_INVALID_VALUE,
30252 + ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo"));
30253 +
30254 + if (p_CcNodeParam->keysParams.maxNumOfKeys
30255 + && (p_CcNodeParam->keysParams.maxNumOfKeys != p_CcNode->numOfKeys))
30256 + RETURN_ERROR(
30257 + MAJOR,
30258 + E_INVALID_VALUE,
30259 + ("For Node of the type INDEXED 'maxNumOfKeys' should be 0 or equal 'numOfKeys'"));
30260 +
30261 + /* Validate statistics parameters */
30262 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30263 + &(p_CcNode->numOfStatsFLRs),
30264 + &(p_CcNode->countersArraySize));
30265 + if (err)
30266 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30267 +
30268 + err = ValidateNextEngineParams(
30269 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30270 + p_CcNode->statisticsMode);
30271 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30272 + RETURN_ERROR(
30273 + MAJOR,
30274 + err,
30275 + ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized"));
30276 +
30277 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30278 + {
30279 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30280 +
30281 + if (p_KeyParams->p_Mask || p_KeyParams->p_Key)
30282 + RETURN_ERROR(
30283 + MAJOR,
30284 + E_INVALID_VALUE,
30285 + ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL"));
30286 +
30287 + if ((glblMask & (tmp * 16)) == (tmp * 16))
30288 + {
30289 + err = ValidateNextEngineParams(h_FmPcd,
30290 + &p_KeyParams->ccNextEngineParams,
30291 + p_CcNode->statisticsMode);
30292 + if (err)
30293 + RETURN_ERROR(
30294 + MAJOR,
30295 + err,
30296 + ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask "));
30297 +
30298 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30299 + {
30300 + err = FmPcdManipCheckParamsForCcNextEngine(
30301 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30302 + if (err)
30303 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30304 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction =
30305 + requiredAction;
30306 + }
30307 +
30308 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30309 + &p_KeyParams->ccNextEngineParams,
30310 + sizeof(t_FmPcdCcNextEngineParams));
30311 +
30312 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30313 + == e_FM_PCD_CC)
30314 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30315 + {
30316 + err =
30317 + AllocAndFillAdForContLookupManip(
30318 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30319 + if (err)
30320 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30321 + }
30322 + }
30323 + else
30324 + {
30325 + err = ValidateNextEngineParams(h_FmPcd,
30326 + &p_KeyParams->ccNextEngineParams,
30327 + p_CcNode->statisticsMode);
30328 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30329 + RETURN_ERROR(
30330 + MAJOR,
30331 + err,
30332 + ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask"));
30333 + }
30334 + }
30335 +
30336 + *isKeyTblAlloc = FALSE;
30337 + cpu_to_be16s(&glblMask);
30338 + memcpy(PTR_MOVE(p_CcNode->p_GlblMask, 2), &glblMask, 2);
30339 +
30340 + return E_OK;
30341 +}
30342 +
30343 +static t_Error ModifyNextEngineParamNode(
30344 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex,
30345 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
30346 +{
30347 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
30348 + t_FmPcd *p_FmPcd;
30349 + t_List h_OldPointersLst, h_NewPointersLst;
30350 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
30351 + t_Error err = E_OK;
30352 +
30353 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_VALUE);
30354 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
30355 +
30356 + if (keyIndex >= p_CcNode->numOfKeys)
30357 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30358 + ("keyIndex > previously cleared last index + 1"));
30359 +
30360 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
30361 +
30362 + INIT_LIST(&h_OldPointersLst);
30363 + INIT_LIST(&h_NewPointersLst);
30364 +
30365 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
30366 + e_MODIFY_STATE_CHANGE, FALSE,
30367 + FALSE, FALSE);
30368 + if (!p_ModifyKeyParams)
30369 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
30370 +
30371 + if (p_CcNode->maxNumOfKeys
30372 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
30373 + {
30374 + XX_Free(p_ModifyKeyParams);
30375 + return ERROR_CODE(E_BUSY);
30376 + }
30377 +
30378 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
30379 + p_FmPcdCcNextEngineParams,
30380 + &h_OldPointersLst, &h_NewPointersLst,
30381 + p_ModifyKeyParams);
30382 + if (err)
30383 + {
30384 + XX_Free(p_ModifyKeyParams);
30385 + if (p_CcNode->maxNumOfKeys)
30386 + RELEASE_LOCK(p_FmPcd->shadowLock);
30387 + RETURN_ERROR(MAJOR, err, NO_MSG);
30388 + }
30389 +
30390 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
30391 + p_ModifyKeyParams, FALSE);
30392 +
30393 + if (p_CcNode->maxNumOfKeys)
30394 + RELEASE_LOCK(p_FmPcd->shadowLock);
30395 +
30396 + ReleaseLst(&h_OldPointersLst);
30397 + ReleaseLst(&h_NewPointersLst);
30398 +
30399 + return err;
30400 +}
30401 +
30402 +static t_Error FindKeyIndex(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key,
30403 + uint8_t *p_Mask, uint16_t *p_KeyIndex)
30404 +{
30405 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
30406 + uint8_t tmpMask[FM_PCD_MAX_SIZE_OF_KEY];
30407 + uint16_t i;
30408 +
30409 + ASSERT_COND(p_Key);
30410 + ASSERT_COND(p_KeyIndex);
30411 + ASSERT_COND(keySize < FM_PCD_MAX_SIZE_OF_KEY);
30412 +
30413 + if (keySize != p_CcNode->userSizeOfExtraction)
30414 + RETURN_ERROR(
30415 + MINOR, E_INVALID_VALUE,
30416 + ("Key size doesn't match the extraction size of the node"));
30417 +
30418 + /* If user didn't pass a mask for this key, we'll look for full extraction mask */
30419 + if (!p_Mask)
30420 + memset(tmpMask, 0xFF, keySize);
30421 +
30422 + for (i = 0; i < p_CcNode->numOfKeys; i++)
30423 + {
30424 + /* Comparing received key */
30425 + if (memcmp(p_Key, p_CcNode->keyAndNextEngineParams[i].key, keySize)
30426 + == 0)
30427 + {
30428 + if (p_Mask)
30429 + {
30430 + /* If a user passed a mask for this key, it must match to the existing key's mask for a correct match */
30431 + if (memcmp(p_Mask, p_CcNode->keyAndNextEngineParams[i].mask,
30432 + keySize) == 0)
30433 + {
30434 + *p_KeyIndex = i;
30435 + return E_OK;
30436 + }
30437 + }
30438 + else
30439 + {
30440 + /* If user didn't pass a mask for this key, check if the existing key mask is full extraction */
30441 + if (memcmp(tmpMask, p_CcNode->keyAndNextEngineParams[i].mask,
30442 + keySize) == 0)
30443 + {
30444 + *p_KeyIndex = i;
30445 + return E_OK;
30446 + }
30447 + }
30448 + }
30449 + }
30450 +
30451 + return ERROR_CODE(E_NOT_FOUND);
30452 +}
30453 +
30454 +static t_Error CalcAndUpdateCcShadow(t_FmPcdCcNode *p_CcNode,
30455 + bool isKeyTblAlloc,
30456 + uint32_t *p_MatchTableSize,
30457 + uint32_t *p_AdTableSize)
30458 +{
30459 + uint32_t shadowSize;
30460 + t_Error err;
30461 +
30462 + /* Calculate keys table maximal size - each entry consists of a key and a mask,
30463 + (if local mask support is requested) */
30464 + *p_MatchTableSize = p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)
30465 + * p_CcNode->maxNumOfKeys;
30466 +
30467 + if (p_CcNode->maskSupport)
30468 + *p_MatchTableSize *= 2;
30469 +
30470 + /* Calculate next action descriptors table, including one more entry for miss */
30471 + *p_AdTableSize = (uint32_t)((p_CcNode->maxNumOfKeys + 1)
30472 + * FM_PCD_CC_AD_ENTRY_SIZE);
30473 +
30474 + /* Calculate maximal shadow size of this node.
30475 + All shadow structures will be used for runtime modifications host command. If
30476 + keys table was allocated for this node, the keys table and next engines table may
30477 + be modified in run time (entries added or removed), so shadow tables are requires.
30478 + Otherwise, the only supported runtime modification is a specific next engine update
30479 + and this requires shadow memory of a single AD */
30480 +
30481 + /* Shadow size should be enough to hold the following 3 structures:
30482 + * 1 - an action descriptor */
30483 + shadowSize = FM_PCD_CC_AD_ENTRY_SIZE;
30484 +
30485 + /* 2 - keys match table, if was allocated for the current node */
30486 + if (isKeyTblAlloc)
30487 + shadowSize += *p_MatchTableSize;
30488 +
30489 + /* 3 - next action descriptors table */
30490 + shadowSize += *p_AdTableSize;
30491 +
30492 + /* Update shadow to the calculated size */
30493 + err = FmPcdUpdateCcShadow(p_CcNode->h_FmPcd, (uint32_t)shadowSize,
30494 + FM_PCD_CC_AD_TABLE_ALIGN);
30495 + if (err != E_OK)
30496 + {
30497 + DeleteNode(p_CcNode);
30498 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node shadow"));
30499 + }
30500 +
30501 + return E_OK;
30502 +}
30503 +
30504 +static t_Error AllocStatsObjs(t_FmPcdCcNode *p_CcNode)
30505 +{
30506 + t_FmPcdStatsObj *p_StatsObj;
30507 + t_Handle h_FmMuram, h_StatsAd, h_StatsCounters;
30508 + uint32_t i;
30509 +
30510 + h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
30511 + if (!h_FmMuram)
30512 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30513 +
30514 + /* Allocate statistics ADs and statistics counter. An extra pair (AD + counters)
30515 + will be allocated to support runtime modifications */
30516 + for (i = 0; i < p_CcNode->maxNumOfKeys + 2; i++)
30517 + {
30518 + /* Allocate list object structure */
30519 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
30520 + if (!p_StatsObj)
30521 + {
30522 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30523 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Statistics object"));
30524 + }
30525 + memset(p_StatsObj, 0, sizeof(t_FmPcdStatsObj));
30526 +
30527 + /* Allocate statistics AD from MURAM */
30528 + h_StatsAd = (t_Handle)FM_MURAM_AllocMem(h_FmMuram,
30529 + FM_PCD_CC_AD_ENTRY_SIZE,
30530 + FM_PCD_CC_AD_TABLE_ALIGN);
30531 + if (!h_StatsAd)
30532 + {
30533 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30534 + XX_Free(p_StatsObj);
30535 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30536 + ("MURAM allocation for statistics ADs"));
30537 + }
30538 + MemSet8(h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
30539 +
30540 + /* Allocate statistics counters from MURAM */
30541 + h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
30542 + h_FmMuram, p_CcNode->countersArraySize,
30543 + FM_PCD_CC_AD_TABLE_ALIGN);
30544 + if (!h_StatsCounters)
30545 + {
30546 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30547 + FM_MURAM_FreeMem(h_FmMuram, h_StatsAd);
30548 + XX_Free(p_StatsObj);
30549 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30550 + ("MURAM allocation for statistics counters"));
30551 + }
30552 + MemSet8(h_StatsCounters, 0, p_CcNode->countersArraySize);
30553 +
30554 + p_StatsObj->h_StatsAd = h_StatsAd;
30555 + p_StatsObj->h_StatsCounters = h_StatsCounters;
30556 +
30557 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
30558 + }
30559 +
30560 + return E_OK;
30561 +}
30562 +
30563 +static t_Error MatchTableGetKeyStatistics(
30564 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
30565 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
30566 +{
30567 + uint32_t *p_StatsCounters, i;
30568 +
30569 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
30570 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30571 + ("Statistics were not enabled for this match table"));
30572 +
30573 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
30574 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30575 + ("Statistics were not enabled for this key"));
30576 +
30577 + memset(p_KeyStatistics, 0, sizeof(t_FmPcdCcKeyStatistics));
30578 +
30579 + p_StatsCounters =
30580 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
30581 + ASSERT_COND(p_StatsCounters);
30582 +
30583 + p_KeyStatistics->byteCount = GET_UINT32(*p_StatsCounters);
30584 +
30585 + for (i = 1; i <= p_CcNode->numOfStatsFLRs; i++)
30586 + {
30587 + p_StatsCounters =
30588 + PTR_MOVE(p_StatsCounters, FM_PCD_CC_STATS_COUNTER_SIZE);
30589 +
30590 + p_KeyStatistics->frameCount += GET_UINT32(*p_StatsCounters);
30591 +
30592 +#if (DPAA_VERSION >= 11)
30593 + p_KeyStatistics->frameLengthRangeCount[i - 1] =
30594 + GET_UINT32(*p_StatsCounters);
30595 +#endif /* (DPAA_VERSION >= 11) */
30596 + }
30597 +
30598 + return E_OK;
30599 +}
30600 +
30601 +static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode,
30602 + t_FmPcdCcNodeParams *p_CcNodeParam)
30603 +{
30604 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
30605 + t_FmPcdCcNode *p_FmPcdCcNextNode;
30606 + t_Error err = E_OK;
30607 + uint32_t tmp, keySize;
30608 + bool glblMask = FALSE;
30609 + t_FmPcdCcKeyParams *p_KeyParams;
30610 + t_Handle h_FmMuram, p_KeysMatchTblTmp, p_AdTableTmp;
30611 +#if (DPAA_VERSION >= 11)
30612 + t_Handle h_StatsFLRs;
30613 +#endif /* (DPAA_VERSION >= 11) */
30614 + bool fullField = FALSE;
30615 + ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE;
30616 + bool isKeyTblAlloc, fromIc = FALSE;
30617 + uint32_t matchTableSize, adTableSize;
30618 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
30619 + t_FmPcdStatsObj *p_StatsObj;
30620 + t_FmPcdCcStatsParams statsParams = { 0 };
30621 + t_Handle h_Manip;
30622 +
30623 + ASSERT_COND(h_FmPcd);
30624 + ASSERT_COND(p_CcNode);
30625 + ASSERT_COND(p_CcNodeParam);
30626 +
30627 + p_CcNode->p_GlblMask = (t_Handle)XX_Malloc(
30628 + CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30629 + memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30630 +
30631 + p_CcNode->h_FmPcd = h_FmPcd;
30632 + p_CcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys;
30633 + p_CcNode->maxNumOfKeys = p_CcNodeParam->keysParams.maxNumOfKeys;
30634 + p_CcNode->maskSupport = p_CcNodeParam->keysParams.maskSupport;
30635 + p_CcNode->statisticsMode = p_CcNodeParam->keysParams.statisticsMode;
30636 +
30637 + /* For backward compatibility - even if statistics mode is nullified,
30638 + we'll fix it to frame mode so we can support per-key request for
30639 + statistics using 'statisticsEn' in next engine parameters */
30640 + if (!p_CcNode->maxNumOfKeys
30641 + && (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE))
30642 + p_CcNode->statisticsMode = e_FM_PCD_CC_STATS_MODE_FRAME;
30643 +
30644 + h_FmMuram = FmPcdGetMuramHandle(h_FmPcd);
30645 + if (!h_FmMuram)
30646 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30647 +
30648 + INIT_LIST(&p_CcNode->ccPrevNodesLst);
30649 + INIT_LIST(&p_CcNode->ccTreeIdLst);
30650 + INIT_LIST(&p_CcNode->ccTreesLst);
30651 + INIT_LIST(&p_CcNode->availableStatsLst);
30652 +
30653 + p_CcNode->h_Spinlock = XX_InitSpinlock();
30654 + if (!p_CcNode->h_Spinlock)
30655 + {
30656 + DeleteNode(p_CcNode);
30657 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock"));
30658 + }
30659 +
30660 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR)
30661 + && ((p_CcNodeParam->extractCcParams.extractByHdr.hdr
30662 + == HEADER_TYPE_IPv4)
30663 + || (p_CcNodeParam->extractCcParams.extractByHdr.hdr
30664 + == HEADER_TYPE_IPv6))
30665 + && (p_CcNodeParam->extractCcParams.extractByHdr.type
30666 + == e_FM_PCD_EXTRACT_FULL_FIELD)
30667 + && ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6
30668 + == NET_HEADER_FIELD_IPv6_HOP_LIMIT)
30669 + || (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4
30670 + == NET_HEADER_FIELD_IPv4_TTL)))
30671 + {
30672 + err = Ipv4TtlOrIpv6HopLimitCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30673 + &isKeyTblAlloc);
30674 + glblMask = FALSE;
30675 + }
30676 + else
30677 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR)
30678 + && ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30679 + == e_FM_PCD_EXTRACT_FROM_KEY)
30680 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30681 + == e_FM_PCD_EXTRACT_FROM_HASH)
30682 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30683 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)))
30684 + {
30685 + if ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30686 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)
30687 + && (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0))
30688 + {
30689 + DeleteNode(p_CcNode);
30690 + RETURN_ERROR(
30691 + MAJOR,
30692 + E_INVALID_VALUE,
30693 + ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0"));
30694 + }
30695 +
30696 + icCode = IcDefineCode(p_CcNodeParam);
30697 + fromIc = TRUE;
30698 + if (icCode == CC_PRIVATE_INFO_NONE)
30699 + {
30700 + DeleteNode(p_CcNode);
30701 + RETURN_ERROR(
30702 + MAJOR,
30703 + E_INVALID_STATE,
30704 + ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way"));
30705 + }
30706 +
30707 + if ((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP)
30708 + || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP))
30709 + {
30710 + err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30711 + &isKeyTblAlloc);
30712 + glblMask = TRUE;
30713 + }
30714 + else
30715 + {
30716 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30717 + &isKeyTblAlloc);
30718 + if (p_CcNode->glblMaskSize)
30719 + glblMask = TRUE;
30720 + }
30721 + }
30722 + else
30723 + {
30724 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, &isKeyTblAlloc);
30725 + if (p_CcNode->glblMaskSize)
30726 + glblMask = TRUE;
30727 + }
30728 +
30729 + if (err)
30730 + {
30731 + DeleteNode(p_CcNode);
30732 + RETURN_ERROR(MAJOR, err, NO_MSG);
30733 + }
30734 +
30735 + switch (p_CcNodeParam->extractCcParams.type)
30736 + {
30737 + case (e_FM_PCD_EXTRACT_BY_HDR):
30738 + switch (p_CcNodeParam->extractCcParams.extractByHdr.type)
30739 + {
30740 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
30741 + p_CcNode->parseCode =
30742 + GetFullFieldParseCode(
30743 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30744 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
30745 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField);
30746 + GetSizeHeaderField(
30747 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30748 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField,
30749 + &p_CcNode->sizeOfExtraction);
30750 + fullField = TRUE;
30751 + if ((p_CcNode->parseCode != CC_PC_FF_TCI1)
30752 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
30753 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
30754 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
30755 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
30756 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
30757 + && (p_CcNode->parseCode
30758 + != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
30759 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
30760 + && (p_CcNode->parseCode
30761 + != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2)
30762 + && glblMask)
30763 + {
30764 + glblMask = FALSE;
30765 + p_CcNode->glblMaskSize = 4;
30766 + p_CcNode->lclMask = TRUE;
30767 + }
30768 + break;
30769 +
30770 + case (e_FM_PCD_EXTRACT_FROM_HDR):
30771 + p_CcNode->sizeOfExtraction =
30772 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size;
30773 + p_CcNode->offset =
30774 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
30775 + p_CcNode->userOffset =
30776 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
30777 + p_CcNode->parseCode =
30778 + GetPrParseCode(
30779 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30780 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
30781 + p_CcNode->offset, glblMask,
30782 + &p_CcNode->prsArrayOffset);
30783 + break;
30784 +
30785 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
30786 + p_CcNode->offset =
30787 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
30788 + p_CcNode->userOffset =
30789 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
30790 + p_CcNode->sizeOfExtraction =
30791 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size;
30792 + p_CcNode->parseCode =
30793 + GetFieldParseCode(
30794 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30795 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field,
30796 + p_CcNode->offset,
30797 + &p_CcNode->prsArrayOffset,
30798 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex);
30799 + break;
30800 +
30801 + default:
30802 + DeleteNode(p_CcNode);
30803 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
30804 + }
30805 + break;
30806 +
30807 + case (e_FM_PCD_EXTRACT_NON_HDR):
30808 + /* get the field code for the generic extract */
30809 + p_CcNode->sizeOfExtraction =
30810 + p_CcNodeParam->extractCcParams.extractNonHdr.size;
30811 + p_CcNode->offset =
30812 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
30813 + p_CcNode->userOffset =
30814 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
30815 + p_CcNode->parseCode = GetGenParseCode(
30816 + p_CcNodeParam->extractCcParams.extractNonHdr.src,
30817 + p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset,
30818 + fromIc, icCode);
30819 +
30820 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
30821 + {
30822 + if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8)
30823 + {
30824 + DeleteNode(p_CcNode);
30825 + RETURN_ERROR(
30826 + MAJOR,
30827 + E_INVALID_SELECTION,
30828 + ("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)"));
30829 + }
30830 + }
30831 + if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK)
30832 + || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
30833 + {
30834 + p_CcNode->offset += p_CcNode->prsArrayOffset;
30835 + p_CcNode->prsArrayOffset = 0;
30836 + }
30837 + break;
30838 +
30839 + default:
30840 + DeleteNode(p_CcNode);
30841 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
30842 + }
30843 +
30844 + if (p_CcNode->parseCode == CC_PC_ILLEGAL)
30845 + {
30846 + DeleteNode(p_CcNode);
30847 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type"));
30848 + }
30849 +
30850 + if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY)
30851 + || !p_CcNode->sizeOfExtraction)
30852 + {
30853 + DeleteNode(p_CcNode);
30854 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30855 + ("sizeOfExatrction can not be greater than 56 and not 0"));
30856 + }
30857 +
30858 + if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction)
30859 + {
30860 + DeleteNode(p_CcNode);
30861 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30862 + ("keySize has to be equal to sizeOfExtraction"));
30863 + }
30864 +
30865 + p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction;
30866 +
30867 + if (!glblMask)
30868 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30869 +
30870 + err = CheckAndSetManipParamsWithCcNodeParams(p_CcNode);
30871 + if (err != E_OK)
30872 + {
30873 + DeleteNode(p_CcNode);
30874 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30875 + ("keySize has to be equal to sizeOfExtraction"));
30876 + }
30877 +
30878 + /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */
30879 + GetCcExtractKeySize(p_CcNode->sizeOfExtraction,
30880 + &p_CcNode->ccKeySizeAccExtraction);
30881 +
30882 + /* If local mask is used, it is stored next to each key in the keys match table */
30883 + if (p_CcNode->lclMask)
30884 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
30885 + else
30886 + keySize = p_CcNode->ccKeySizeAccExtraction;
30887 +
30888 + /* Update CC shadow with maximal size required by this node */
30889 + if (p_CcNode->maxNumOfKeys)
30890 + {
30891 + err = CalcAndUpdateCcShadow(p_CcNode, isKeyTblAlloc, &matchTableSize,
30892 + &adTableSize);
30893 + if (err != E_OK)
30894 + {
30895 + DeleteNode(p_CcNode);
30896 + RETURN_ERROR(MAJOR, err, NO_MSG);
30897 + }
30898 +
30899 + p_CcNode->keysMatchTableMaxSize = matchTableSize;
30900 +
30901 + if (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)
30902 + {
30903 + err = AllocStatsObjs(p_CcNode);
30904 + if (err != E_OK)
30905 + {
30906 + DeleteNode(p_CcNode);
30907 + RETURN_ERROR(MAJOR, err, NO_MSG);
30908 + }
30909 + }
30910 +
30911 + /* If manipulation will be initialized before this node, it will use the table
30912 + descriptor in the AD table of previous node and this node will need an extra
30913 + AD as his table descriptor. */
30914 + p_CcNode->h_TmpAd = (t_Handle)FM_MURAM_AllocMem(
30915 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
30916 + if (!p_CcNode->h_TmpAd)
30917 + {
30918 + DeleteNode(p_CcNode);
30919 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30920 + ("MURAM allocation for CC action descriptor"));
30921 + }
30922 + }
30923 + else
30924 + {
30925 + matchTableSize = (uint32_t)(keySize * sizeof(uint8_t)
30926 + * (p_CcNode->numOfKeys + 1));
30927 + adTableSize = (uint32_t)(FM_PCD_CC_AD_ENTRY_SIZE
30928 + * (p_CcNode->numOfKeys + 1));
30929 + }
30930 +
30931 +#if (DPAA_VERSION >= 11)
30932 + switch (p_CcNode->statisticsMode)
30933 + {
30934 +
30935 + case e_FM_PCD_CC_STATS_MODE_RMON:
30936 + /* If RMON statistics or RMON conditional statistics modes are requested,
30937 + allocate frame length ranges array */
30938 + p_CcNode->h_StatsFLRs = FM_MURAM_AllocMem(
30939 + h_FmMuram,
30940 + (uint32_t)(p_CcNode->numOfStatsFLRs)
30941 + * FM_PCD_CC_STATS_FLR_SIZE,
30942 + FM_PCD_CC_AD_TABLE_ALIGN);
30943 +
30944 + if (!p_CcNode->h_StatsFLRs)
30945 + {
30946 + DeleteNode(p_CcNode);
30947 + RETURN_ERROR(
30948 + MAJOR, E_NO_MEMORY,
30949 + ("MURAM allocation for CC frame length ranges array"));
30950 + }
30951 +
30952 + /* Initialize using value received from the user */
30953 + for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++)
30954 + {
30955 + uint16_t flr =
30956 + cpu_to_be16(p_CcNodeParam->keysParams.frameLengthRanges[tmp]);
30957 +
30958 + h_StatsFLRs =
30959 + PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE);
30960 +
30961 + MemCpy8(h_StatsFLRs,
30962 + &flr,
30963 + FM_PCD_CC_STATS_FLR_SIZE);
30964 + }
30965 + break;
30966 +
30967 + default:
30968 + break;
30969 + }
30970 +#endif /* (DPAA_VERSION >= 11) */
30971 +
30972 + /* Allocate keys match table. Not required for some CC nodes, for example for IPv4 TTL
30973 + identification, IPv6 hop count identification, etc. */
30974 + if (isKeyTblAlloc)
30975 + {
30976 + p_CcNode->h_KeysMatchTable = (t_Handle)FM_MURAM_AllocMem(
30977 + h_FmMuram, matchTableSize, FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
30978 + if (!p_CcNode->h_KeysMatchTable)
30979 + {
30980 + DeleteNode(p_CcNode);
30981 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30982 + ("MURAM allocation for CC node key match table"));
30983 + }
30984 + MemSet8((uint8_t *)p_CcNode->h_KeysMatchTable, 0, matchTableSize);
30985 + }
30986 +
30987 + /* Allocate action descriptors table */
30988 + p_CcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, adTableSize,
30989 + FM_PCD_CC_AD_TABLE_ALIGN);
30990 + if (!p_CcNode->h_AdTable)
30991 + {
30992 + DeleteNode(p_CcNode);
30993 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30994 + ("MURAM allocation for CC node action descriptors table"));
30995 + }
30996 + MemSet8((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize);
30997 +
30998 + p_KeysMatchTblTmp = p_CcNode->h_KeysMatchTable;
30999 + p_AdTableTmp = p_CcNode->h_AdTable;
31000 +
31001 + /* For each key, create the key and the next step AD */
31002 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
31003 + {
31004 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
31005 +
31006 + if (p_KeysMatchTblTmp)
31007 + {
31008 + /* Copy the key */
31009 + MemCpy8((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key,
31010 + p_CcNode->sizeOfExtraction);
31011 +
31012 + /* Copy the key mask or initialize it to 0xFF..F */
31013 + if (p_CcNode->lclMask && p_KeyParams->p_Mask)
31014 + {
31015 + MemCpy8(PTR_MOVE(p_KeysMatchTblTmp,
31016 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
31017 + p_KeyParams->p_Mask, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
31018 + }
31019 + else
31020 + if (p_CcNode->lclMask)
31021 + {
31022 + MemSet8(PTR_MOVE(p_KeysMatchTblTmp,
31023 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
31024 + 0xff, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
31025 + }
31026 +
31027 + p_KeysMatchTblTmp =
31028 + PTR_MOVE(p_KeysMatchTblTmp, keySize * sizeof(uint8_t));
31029 + }
31030 +
31031 + /* Create the next action descriptor in the match table */
31032 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
31033 + {
31034 + p_StatsObj = GetStatsObj(p_CcNode);
31035 + ASSERT_COND(p_StatsObj);
31036 +
31037 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31038 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31039 +#if (DPAA_VERSION >= 11)
31040 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
31041 +
31042 +#endif /* (DPAA_VERSION >= 11) */
31043 + NextStepAd(p_AdTableTmp, &statsParams,
31044 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
31045 +
31046 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
31047 + }
31048 + else
31049 + {
31050 + NextStepAd(p_AdTableTmp, NULL, &p_KeyParams->ccNextEngineParams,
31051 + p_FmPcd);
31052 +
31053 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
31054 + }
31055 +
31056 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31057 + }
31058 +
31059 + /* Update next engine for the 'miss' entry */
31060 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.statisticsEn)
31061 + {
31062 + p_StatsObj = GetStatsObj(p_CcNode);
31063 + ASSERT_COND(p_StatsObj);
31064 +
31065 + /* All 'bucket' nodes of a hash table should share the same statistics counters,
31066 + allocated by the hash table. So, if this node is a bucket of a hash table,
31067 + we'll replace the locally allocated counters with the shared counters. */
31068 + if (p_CcNode->isHashBucket)
31069 + {
31070 + ASSERT_COND(p_CcNode->h_MissStatsCounters);
31071 +
31072 + /* Store original counters pointer and replace it with mutual preallocated pointer */
31073 + p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters;
31074 + p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters;
31075 + }
31076 +
31077 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31078 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31079 +#if (DPAA_VERSION >= 11)
31080 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
31081 +
31082 +#endif /* (DPAA_VERSION >= 11) */
31083 +
31084 + NextStepAd(p_AdTableTmp, &statsParams,
31085 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31086 + p_FmPcd);
31087 +
31088 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
31089 + }
31090 + else
31091 + {
31092 + NextStepAd(p_AdTableTmp, NULL,
31093 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31094 + p_FmPcd);
31095 +
31096 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
31097 + }
31098 +
31099 + /* This parameter will be used to initialize the "key length" field in the action descriptor
31100 + that points to this node and it should be 0 for full field extraction */
31101 + if (fullField == TRUE)
31102 + p_CcNode->sizeOfExtraction = 0;
31103 +
31104 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
31105 + {
31106 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
31107 + == e_FM_PCD_CC)
31108 + {
31109 + p_FmPcdCcNextNode =
31110 + (t_FmPcdCcNode*)p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode;
31111 + p_CcInformation = FindNodeInfoInReleventLst(
31112 + &p_FmPcdCcNextNode->ccPrevNodesLst, (t_Handle)p_CcNode,
31113 + p_FmPcdCcNextNode->h_Spinlock);
31114 + if (!p_CcInformation)
31115 + {
31116 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31117 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
31118 + ccNodeInfo.index = 1;
31119 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst,
31120 + &ccNodeInfo,
31121 + p_FmPcdCcNextNode->h_Spinlock);
31122 + }
31123 + else
31124 + p_CcInformation->index++;
31125 +
31126 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
31127 + {
31128 + h_Manip =
31129 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip;
31130 + p_CcInformation = FindNodeInfoInReleventLst(
31131 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31132 + (t_Handle)p_CcNode, FmPcdManipGetSpinlock(h_Manip));
31133 + if (!p_CcInformation)
31134 + {
31135 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31136 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
31137 + ccNodeInfo.index = 1;
31138 + EnqueueNodeInfoToRelevantLst(
31139 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31140 + &ccNodeInfo, FmPcdManipGetSpinlock(h_Manip));
31141 + }
31142 + else
31143 + p_CcInformation->index++;
31144 + }
31145 + }
31146 + }
31147 +
31148 + p_AdTableTmp = p_CcNode->h_AdTable;
31149 +
31150 + if (!FmPcdLockTryLockAll(h_FmPcd))
31151 + {
31152 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31153 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
31154 + return ERROR_CODE(E_BUSY);
31155 + }
31156 +
31157 + /* Required action for each next engine */
31158 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
31159 + {
31160 + if (p_CcNode->keyAndNextEngineParams[tmp].requiredAction)
31161 + {
31162 + err = SetRequiredAction(
31163 + h_FmPcd,
31164 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction,
31165 + &p_CcNode->keyAndNextEngineParams[tmp], p_AdTableTmp, 1,
31166 + NULL);
31167 + if (err)
31168 + {
31169 + FmPcdLockUnlockAll(h_FmPcd);
31170 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31171 + RETURN_ERROR(MAJOR, err, NO_MSG);
31172 + }
31173 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31174 + }
31175 + }
31176 +
31177 + FmPcdLockUnlockAll(h_FmPcd);
31178 +
31179 + return E_OK;
31180 +}
31181 +/************************** End of static functions **************************/
31182 +
31183 +/*****************************************************************************/
31184 +/* Inter-module API routines */
31185 +/*****************************************************************************/
31186 +
31187 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info,
31188 + t_Handle h_Spinlock)
31189 +{
31190 + t_CcNodeInformation *p_CcInformation;
31191 + t_List *p_Pos;
31192 + uint32_t intFlags;
31193 +
31194 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31195 +
31196 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31197 + p_Pos = LIST_NEXT(p_Pos))
31198 + {
31199 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31200 +
31201 + ASSERT_COND(p_CcInformation->h_CcNode);
31202 +
31203 + if (p_CcInformation->h_CcNode == h_Info)
31204 + {
31205 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31206 + return p_CcInformation;
31207 + }
31208 + }
31209 +
31210 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31211 +
31212 + return NULL;
31213 +}
31214 +
31215 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo,
31216 + t_Handle h_Spinlock)
31217 +{
31218 + t_CcNodeInformation *p_CcInformation;
31219 + uint32_t intFlags = 0;
31220 +
31221 + p_CcInformation = (t_CcNodeInformation *)XX_Malloc(
31222 + sizeof(t_CcNodeInformation));
31223 +
31224 + if (p_CcInformation)
31225 + {
31226 + memset(p_CcInformation, 0, sizeof(t_CcNodeInformation));
31227 + memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation));
31228 + INIT_LIST(&p_CcInformation->node);
31229 +
31230 + if (h_Spinlock)
31231 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31232 +
31233 + LIST_AddToTail(&p_CcInformation->node, p_List);
31234 +
31235 + if (h_Spinlock)
31236 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31237 + }
31238 + else
31239 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information"));
31240 +}
31241 +
31242 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info,
31243 + t_Handle h_Spinlock)
31244 +{
31245 + t_CcNodeInformation *p_CcInformation = NULL;
31246 + uint32_t intFlags = 0;
31247 + t_List *p_Pos;
31248 +
31249 + if (h_Spinlock)
31250 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31251 +
31252 + if (LIST_IsEmpty(p_List))
31253 + {
31254 + XX_RestoreAllIntr(intFlags);
31255 + return;
31256 + }
31257 +
31258 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31259 + p_Pos = LIST_NEXT(p_Pos))
31260 + {
31261 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31262 + ASSERT_COND(p_CcInformation);
31263 + ASSERT_COND(p_CcInformation->h_CcNode);
31264 + if (p_CcInformation->h_CcNode == h_Info)
31265 + break;
31266 + }
31267 +
31268 + if (p_CcInformation)
31269 + {
31270 + LIST_DelAndInit(&p_CcInformation->node);
31271 + XX_Free(p_CcInformation);
31272 + }
31273 +
31274 + if (h_Spinlock)
31275 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31276 +}
31277 +
31278 +void NextStepAd(t_Handle h_Ad, t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
31279 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
31280 + t_FmPcd *p_FmPcd)
31281 +{
31282 + switch (p_FmPcdCcNextEngineParams->nextEngine)
31283 + {
31284 + case (e_FM_PCD_KG):
31285 + case (e_FM_PCD_PLCR):
31286 + case (e_FM_PCD_DONE):
31287 + /* if NIA is not CC, create a "result" type AD */
31288 + FillAdOfTypeResult(h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31289 + p_FmPcdCcNextEngineParams);
31290 + break;
31291 +#if (DPAA_VERSION >= 11)
31292 + case (e_FM_PCD_FR):
31293 + if (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
31294 + {
31295 + FillAdOfTypeContLookup(
31296 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31297 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31298 + p_FmPcdCcNextEngineParams->h_Manip,
31299 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
31300 + FrmReplicGroupUpdateOwner(
31301 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic,
31302 + TRUE/* add */);
31303 + }
31304 + break;
31305 +#endif /* (DPAA_VERSION >= 11) */
31306 +
31307 + case (e_FM_PCD_CC):
31308 + /* if NIA is not CC, create a TD to continue the CC lookup */
31309 + FillAdOfTypeContLookup(
31310 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31311 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31312 + p_FmPcdCcNextEngineParams->h_Manip, NULL);
31313 +
31314 + UpdateNodeOwner(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31315 + TRUE);
31316 + break;
31317 +
31318 + default:
31319 + return;
31320 + }
31321 +}
31322 +
31323 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31324 + t_Handle h_NetEnv, t_Handle h_IpReassemblyManip,
31325 + bool createSchemes)
31326 +{
31327 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31328 + t_FmPcdCcNextEngineParams nextEngineParams;
31329 + t_NetEnvParams netEnvParams;
31330 + t_Handle h_Ad;
31331 + bool isIpv6Present;
31332 + uint8_t ipv4GroupId, ipv6GroupId;
31333 + t_Error err;
31334 +
31335 + ASSERT_COND(p_FmPcdCcTree);
31336 +
31337 + /* this routine must be protected by the calling routine! */
31338 +
31339 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31340 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31341 +
31342 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31343 +
31344 + isIpv6Present = FmPcdManipIpReassmIsIpv6Hdr(h_IpReassemblyManip);
31345 +
31346 + if (isIpv6Present
31347 + && (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2)))
31348 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31349 +
31350 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31351 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31352 +
31353 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31354 + nextEngineParams.h_Manip = h_IpReassemblyManip;
31355 +
31356 + /* Lock tree */
31357 + err = CcRootTryLock(p_FmPcdCcTree);
31358 + if (err)
31359 + return ERROR_CODE(E_BUSY);
31360 +
31361 + if (p_FmPcdCcTree->h_IpReassemblyManip == h_IpReassemblyManip)
31362 + {
31363 + CcRootReleaseLock(p_FmPcdCcTree);
31364 + return E_OK;
31365 + }
31366 +
31367 + if ((p_FmPcdCcTree->h_IpReassemblyManip)
31368 + && (p_FmPcdCcTree->h_IpReassemblyManip != h_IpReassemblyManip))
31369 + {
31370 + CcRootReleaseLock(p_FmPcdCcTree);
31371 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31372 + ("This tree was previously updated with different IPR"));
31373 + }
31374 +
31375 + /* Initialize IPR for the first time for this tree */
31376 + if (isIpv6Present)
31377 + {
31378 + ipv6GroupId = p_FmPcdCcTree->numOfGrps++;
31379 + p_FmPcdCcTree->fmPcdGroupParam[ipv6GroupId].baseGroupEntry =
31380 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2);
31381 +
31382 + if (createSchemes)
31383 + {
31384 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv,
31385 + p_FmPcdCcTree,
31386 + h_IpReassemblyManip, FALSE,
31387 + ipv6GroupId);
31388 + if (err)
31389 + {
31390 + p_FmPcdCcTree->numOfGrps--;
31391 + CcRootReleaseLock(p_FmPcdCcTree);
31392 + RETURN_ERROR(MAJOR, err, NO_MSG);
31393 + }
31394 + }
31395 +
31396 + NextStepAd(
31397 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-2) * FM_PCD_CC_AD_ENTRY_SIZE),
31398 + NULL, &nextEngineParams, h_FmPcd);
31399 + }
31400 +
31401 + ipv4GroupId = p_FmPcdCcTree->numOfGrps++;
31402 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].totalBitsMask = 0;
31403 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].baseGroupEntry =
31404 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31405 +
31406 + if (createSchemes)
31407 + {
31408 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, p_FmPcdCcTree,
31409 + h_IpReassemblyManip, TRUE,
31410 + ipv4GroupId);
31411 + if (err)
31412 + {
31413 + p_FmPcdCcTree->numOfGrps--;
31414 + if (isIpv6Present)
31415 + {
31416 + p_FmPcdCcTree->numOfGrps--;
31417 + FmPcdManipDeleteIpReassmSchemes(h_IpReassemblyManip);
31418 + }
31419 + CcRootReleaseLock(p_FmPcdCcTree);
31420 + RETURN_ERROR(MAJOR, err, NO_MSG);
31421 + }
31422 + }
31423 +
31424 + NextStepAd(
31425 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31426 + NULL, &nextEngineParams, h_FmPcd);
31427 +
31428 + p_FmPcdCcTree->h_IpReassemblyManip = h_IpReassemblyManip;
31429 +
31430 + CcRootReleaseLock(p_FmPcdCcTree);
31431 +
31432 + return E_OK;
31433 +}
31434 +
31435 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31436 + t_Handle h_NetEnv, t_Handle h_ReassemblyManip,
31437 + bool createSchemes)
31438 +{
31439 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31440 + t_FmPcdCcNextEngineParams nextEngineParams;
31441 + t_NetEnvParams netEnvParams;
31442 + t_Handle h_Ad;
31443 + uint8_t groupId;
31444 + t_Error err;
31445 +
31446 + ASSERT_COND(p_FmPcdCcTree);
31447 +
31448 + /* this routine must be protected by the calling routine! */
31449 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31450 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31451 +
31452 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31453 +
31454 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31455 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need one free entries for CPR"));
31456 +
31457 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31458 + nextEngineParams.h_Manip = h_ReassemblyManip;
31459 +
31460 + /* Lock tree */
31461 + err = CcRootTryLock(p_FmPcdCcTree);
31462 + if (err)
31463 + return ERROR_CODE(E_BUSY);
31464 +
31465 + if (p_FmPcdCcTree->h_CapwapReassemblyManip == h_ReassemblyManip)
31466 + {
31467 + CcRootReleaseLock(p_FmPcdCcTree);
31468 + return E_OK;
31469 + }
31470 +
31471 + if ((p_FmPcdCcTree->h_CapwapReassemblyManip)
31472 + && (p_FmPcdCcTree->h_CapwapReassemblyManip != h_ReassemblyManip))
31473 + {
31474 + CcRootReleaseLock(p_FmPcdCcTree);
31475 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31476 + ("This tree was previously updated with different CPR"));
31477 + }
31478 +
31479 + groupId = p_FmPcdCcTree->numOfGrps++;
31480 + p_FmPcdCcTree->fmPcdGroupParam[groupId].baseGroupEntry =
31481 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31482 +
31483 + if (createSchemes)
31484 + {
31485 + err = FmPcdManipBuildCapwapReassmScheme(h_FmPcd, h_NetEnv,
31486 + p_FmPcdCcTree,
31487 + h_ReassemblyManip, groupId);
31488 + if (err)
31489 + {
31490 + p_FmPcdCcTree->numOfGrps--;
31491 + CcRootReleaseLock(p_FmPcdCcTree);
31492 + RETURN_ERROR(MAJOR, err, NO_MSG);
31493 + }
31494 + }
31495 +
31496 + NextStepAd(
31497 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31498 + NULL, &nextEngineParams, h_FmPcd);
31499 +
31500 + p_FmPcdCcTree->h_CapwapReassemblyManip = h_ReassemblyManip;
31501 +
31502 + CcRootReleaseLock(p_FmPcdCcTree);
31503 +
31504 + return E_OK;
31505 +}
31506 +
31507 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree)
31508 +{
31509 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31510 +
31511 + ASSERT_COND(p_FmPcdCcTree);
31512 +
31513 + return p_FmPcdCcTree->h_FmPcdCcSavedManipParams;
31514 +}
31515 +
31516 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree,
31517 + t_Handle h_SavedManipParams)
31518 +{
31519 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31520 +
31521 + ASSERT_COND(p_FmPcdCcTree);
31522 +
31523 + p_FmPcdCcTree->h_FmPcdCcSavedManipParams = h_SavedManipParams;
31524 +}
31525 +
31526 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode)
31527 +{
31528 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31529 +
31530 + ASSERT_COND(p_CcNode);
31531 +
31532 + return p_CcNode->parseCode;
31533 +}
31534 +
31535 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode)
31536 +{
31537 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31538 +
31539 + ASSERT_COND(p_CcNode);
31540 +
31541 + return p_CcNode->offset;
31542 +}
31543 +
31544 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode)
31545 +{
31546 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31547 +
31548 + ASSERT_COND(p_CcNode);
31549 +
31550 + return p_CcNode->numOfKeys;
31551 +}
31552 +
31553 +t_Error FmPcdCcModifyNextEngineParamTree(
31554 + t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index,
31555 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31556 +{
31557 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
31558 + t_FmPcd *p_FmPcd;
31559 + t_List h_OldPointersLst, h_NewPointersLst;
31560 + uint16_t keyIndex;
31561 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31562 + t_Error err = E_OK;
31563 +
31564 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
31565 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
31566 + SANITY_CHECK_RETURN_ERROR((grpId <= 7), E_INVALID_VALUE);
31567 +
31568 + if (grpId >= p_FmPcdCcTree->numOfGrps)
31569 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
31570 + ("grpId you asked > numOfGroup of relevant tree"));
31571 +
31572 + if (index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup)
31573 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup"));
31574 +
31575 + p_FmPcd = (t_FmPcd *)h_FmPcd;
31576 +
31577 + INIT_LIST(&h_OldPointersLst);
31578 + INIT_LIST(&h_NewPointersLst);
31579 +
31580 + keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry
31581 + + index);
31582 +
31583 + p_ModifyKeyParams = ModifyNodeCommonPart(p_FmPcdCcTree, keyIndex,
31584 + e_MODIFY_STATE_CHANGE, FALSE,
31585 + FALSE, TRUE);
31586 + if (!p_ModifyKeyParams)
31587 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31588 +
31589 + p_ModifyKeyParams->tree = TRUE;
31590 +
31591 + if (p_FmPcd->p_CcShadow
31592 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31593 + {
31594 + XX_Free(p_ModifyKeyParams);
31595 + return ERROR_CODE(E_BUSY);
31596 + }
31597 +
31598 + err = BuildNewNodeModifyNextEngine(p_FmPcd, p_FmPcdCcTree, keyIndex,
31599 + p_FmPcdCcNextEngineParams,
31600 + &h_OldPointersLst, &h_NewPointersLst,
31601 + p_ModifyKeyParams);
31602 + if (err)
31603 + {
31604 + XX_Free(p_ModifyKeyParams);
31605 + RETURN_ERROR(MAJOR, err, NO_MSG);
31606 + }
31607 +
31608 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31609 + p_ModifyKeyParams, FALSE);
31610 +
31611 + if (p_FmPcd->p_CcShadow)
31612 + RELEASE_LOCK(p_FmPcd->shadowLock);
31613 +
31614 + ReleaseLst(&h_OldPointersLst);
31615 + ReleaseLst(&h_NewPointersLst);
31616 +
31617 + return err;
31618 +
31619 +}
31620 +
31621 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31622 + uint16_t keyIndex)
31623 +{
31624 +
31625 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31626 + t_FmPcd *p_FmPcd;
31627 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31628 + t_List h_OldPointersLst, h_NewPointersLst;
31629 + bool useShadowStructs = FALSE;
31630 + t_Error err = E_OK;
31631 +
31632 + if (keyIndex >= p_CcNode->numOfKeys)
31633 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31634 + ("impossible to remove key when numOfKeys <= keyIndex"));
31635 +
31636 + if (p_CcNode->h_FmPcd != h_FmPcd)
31637 + RETURN_ERROR(
31638 + MAJOR,
31639 + E_INVALID_VALUE,
31640 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31641 +
31642 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31643 +
31644 + INIT_LIST(&h_OldPointersLst);
31645 + INIT_LIST(&h_NewPointersLst);
31646 +
31647 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31648 + e_MODIFY_STATE_REMOVE, TRUE, TRUE,
31649 + FALSE);
31650 + if (!p_ModifyKeyParams)
31651 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31652 +
31653 + if (p_CcNode->maxNumOfKeys)
31654 + {
31655 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31656 + {
31657 + XX_Free(p_ModifyKeyParams);
31658 + return ERROR_CODE(E_BUSY);
31659 + }
31660 +
31661 + useShadowStructs = TRUE;
31662 + }
31663 +
31664 + err = BuildNewNodeRemoveKey(p_CcNode, keyIndex, p_ModifyKeyParams);
31665 + if (err)
31666 + {
31667 + XX_Free(p_ModifyKeyParams);
31668 + if (p_CcNode->maxNumOfKeys)
31669 + RELEASE_LOCK(p_FmPcd->shadowLock);
31670 + RETURN_ERROR(MAJOR, err, NO_MSG);
31671 + }
31672 +
31673 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31674 + &h_OldPointersLst,
31675 + &h_NewPointersLst);
31676 + if (err)
31677 + {
31678 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31679 + XX_Free(p_ModifyKeyParams);
31680 + if (p_CcNode->maxNumOfKeys)
31681 + RELEASE_LOCK(p_FmPcd->shadowLock);
31682 + RETURN_ERROR(MAJOR, err, NO_MSG);
31683 + }
31684 +
31685 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31686 + p_ModifyKeyParams, useShadowStructs);
31687 +
31688 + if (p_CcNode->maxNumOfKeys)
31689 + RELEASE_LOCK(p_FmPcd->shadowLock);
31690 +
31691 + ReleaseLst(&h_OldPointersLst);
31692 + ReleaseLst(&h_NewPointersLst);
31693 +
31694 + return err;
31695 +}
31696 +
31697 +t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31698 + uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key,
31699 + uint8_t *p_Mask)
31700 +{
31701 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31702 + t_FmPcd *p_FmPcd;
31703 + t_List h_OldPointersLst, h_NewPointersLst;
31704 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31705 + uint16_t tmpKeyIndex;
31706 + bool useShadowStructs = FALSE;
31707 + t_Error err = E_OK;
31708 +
31709 + if (keyIndex >= p_CcNode->numOfKeys)
31710 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31711 + ("keyIndex > previously cleared last index + 1"));
31712 +
31713 + if (keySize != p_CcNode->userSizeOfExtraction)
31714 + RETURN_ERROR(
31715 + MAJOR,
31716 + E_INVALID_VALUE,
31717 + ("size for ModifyKey has to be the same as defined in SetNode"));
31718 +
31719 + if (p_CcNode->h_FmPcd != h_FmPcd)
31720 + RETURN_ERROR(
31721 + MAJOR,
31722 + E_INVALID_VALUE,
31723 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31724 +
31725 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_Key, p_Mask, &tmpKeyIndex);
31726 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31727 + RETURN_ERROR(
31728 + MINOR,
31729 + E_ALREADY_EXISTS,
31730 + ("The received key and mask pair was already found in the match table of the provided node"));
31731 +
31732 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31733 +
31734 + INIT_LIST(&h_OldPointersLst);
31735 + INIT_LIST(&h_NewPointersLst);
31736 +
31737 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31738 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
31739 + FALSE);
31740 + if (!p_ModifyKeyParams)
31741 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31742 +
31743 + if (p_CcNode->maxNumOfKeys)
31744 + {
31745 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31746 + {
31747 + XX_Free(p_ModifyKeyParams);
31748 + return ERROR_CODE(E_BUSY);
31749 + }
31750 +
31751 + useShadowStructs = TRUE;
31752 + }
31753 +
31754 + err = BuildNewNodeModifyKey(p_CcNode, keyIndex, p_Key, p_Mask,
31755 + p_ModifyKeyParams);
31756 + if (err)
31757 + {
31758 + XX_Free(p_ModifyKeyParams);
31759 + if (p_CcNode->maxNumOfKeys)
31760 + RELEASE_LOCK(p_FmPcd->shadowLock);
31761 + RETURN_ERROR(MAJOR, err, NO_MSG);
31762 + }
31763 +
31764 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31765 + &h_OldPointersLst,
31766 + &h_NewPointersLst);
31767 + if (err)
31768 + {
31769 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31770 + XX_Free(p_ModifyKeyParams);
31771 + if (p_CcNode->maxNumOfKeys)
31772 + RELEASE_LOCK(p_FmPcd->shadowLock);
31773 + RETURN_ERROR(MAJOR, err, NO_MSG);
31774 + }
31775 +
31776 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31777 + p_ModifyKeyParams, useShadowStructs);
31778 +
31779 + if (p_CcNode->maxNumOfKeys)
31780 + RELEASE_LOCK(p_FmPcd->shadowLock);
31781 +
31782 + ReleaseLst(&h_OldPointersLst);
31783 + ReleaseLst(&h_NewPointersLst);
31784 +
31785 + return err;
31786 +}
31787 +
31788 +t_Error FmPcdCcModifyMissNextEngineParamNode(
31789 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31790 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31791 +{
31792 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31793 + t_FmPcd *p_FmPcd;
31794 + t_List h_OldPointersLst, h_NewPointersLst;
31795 + uint16_t keyIndex;
31796 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31797 + t_Error err = E_OK;
31798 +
31799 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_VALUE);
31800 +
31801 + keyIndex = p_CcNode->numOfKeys;
31802 +
31803 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31804 +
31805 + INIT_LIST(&h_OldPointersLst);
31806 + INIT_LIST(&h_NewPointersLst);
31807 +
31808 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31809 + e_MODIFY_STATE_CHANGE, FALSE, TRUE,
31810 + FALSE);
31811 + if (!p_ModifyKeyParams)
31812 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31813 +
31814 + if (p_CcNode->maxNumOfKeys
31815 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31816 + {
31817 + XX_Free(p_ModifyKeyParams);
31818 + return ERROR_CODE(E_BUSY);
31819 + }
31820 +
31821 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
31822 + p_FmPcdCcNextEngineParams,
31823 + &h_OldPointersLst, &h_NewPointersLst,
31824 + p_ModifyKeyParams);
31825 + if (err)
31826 + {
31827 + XX_Free(p_ModifyKeyParams);
31828 + if (p_CcNode->maxNumOfKeys)
31829 + RELEASE_LOCK(p_FmPcd->shadowLock);
31830 + RETURN_ERROR(MAJOR, err, NO_MSG);
31831 + }
31832 +
31833 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31834 + p_ModifyKeyParams, FALSE);
31835 +
31836 + if (p_CcNode->maxNumOfKeys)
31837 + RELEASE_LOCK(p_FmPcd->shadowLock);
31838 +
31839 + ReleaseLst(&h_OldPointersLst);
31840 + ReleaseLst(&h_NewPointersLst);
31841 +
31842 + return err;
31843 +}
31844 +
31845 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31846 + uint16_t keyIndex, uint8_t keySize,
31847 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
31848 +{
31849 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31850 + t_FmPcd *p_FmPcd;
31851 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31852 + t_List h_OldPointersLst, h_NewPointersLst;
31853 + bool useShadowStructs = FALSE;
31854 + uint16_t tmpKeyIndex;
31855 + t_Error err = E_OK;
31856 +
31857 + if (keyIndex > p_CcNode->numOfKeys)
31858 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
31859 + ("keyIndex > previously cleared last index + 1"));
31860 +
31861 + if (keySize != p_CcNode->userSizeOfExtraction)
31862 + RETURN_ERROR(
31863 + MAJOR,
31864 + E_INVALID_VALUE,
31865 + ("keySize has to be defined as it was defined in initialization step"));
31866 +
31867 + if (p_CcNode->h_FmPcd != h_FmPcd)
31868 + RETURN_ERROR(
31869 + MAJOR,
31870 + E_INVALID_VALUE,
31871 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31872 +
31873 + if (p_CcNode->maxNumOfKeys)
31874 + {
31875 + if (p_CcNode->numOfKeys == p_CcNode->maxNumOfKeys)
31876 + RETURN_ERROR(
31877 + MAJOR,
31878 + E_FULL,
31879 + ("number of keys exceeds the maximal number of keys provided at node initialization time"));
31880 + }
31881 + else
31882 + if (p_CcNode->numOfKeys == FM_PCD_MAX_NUM_OF_KEYS)
31883 + RETURN_ERROR(
31884 + MAJOR,
31885 + E_INVALID_VALUE,
31886 + ("number of keys can not be larger than %d", FM_PCD_MAX_NUM_OF_KEYS));
31887 +
31888 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
31889 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
31890 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31891 + RETURN_ERROR(
31892 + MAJOR,
31893 + E_ALREADY_EXISTS,
31894 + ("The received key and mask pair was already found in the match table of the provided node"));
31895 +
31896 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31897 +
31898 + INIT_LIST(&h_OldPointersLst);
31899 + INIT_LIST(&h_NewPointersLst);
31900 +
31901 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31902 + e_MODIFY_STATE_ADD, TRUE, TRUE,
31903 + FALSE);
31904 + if (!p_ModifyKeyParams)
31905 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31906 +
31907 + if (p_CcNode->maxNumOfKeys)
31908 + {
31909 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31910 + {
31911 + XX_Free(p_ModifyKeyParams);
31912 + return ERROR_CODE(E_BUSY);
31913 + }
31914 +
31915 + useShadowStructs = TRUE;
31916 + }
31917 +
31918 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
31919 + p_FmPcdCcKeyParams,
31920 + p_ModifyKeyParams, TRUE);
31921 + if (err)
31922 + {
31923 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31924 + XX_Free(p_ModifyKeyParams);
31925 + if (p_CcNode->maxNumOfKeys)
31926 + RELEASE_LOCK(p_FmPcd->shadowLock);
31927 + RETURN_ERROR(MAJOR, err, NO_MSG);
31928 + }
31929 +
31930 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31931 + &h_OldPointersLst,
31932 + &h_NewPointersLst);
31933 + if (err)
31934 + {
31935 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31936 + XX_Free(p_ModifyKeyParams);
31937 + if (p_CcNode->maxNumOfKeys)
31938 + RELEASE_LOCK(p_FmPcd->shadowLock);
31939 + RETURN_ERROR(MAJOR, err, NO_MSG);
31940 + }
31941 +
31942 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31943 + p_ModifyKeyParams, useShadowStructs);
31944 + if (p_CcNode->maxNumOfKeys)
31945 + RELEASE_LOCK(p_FmPcd->shadowLock);
31946 +
31947 + ReleaseLst(&h_OldPointersLst);
31948 + ReleaseLst(&h_NewPointersLst);
31949 +
31950 + return err;
31951 +}
31952 +
31953 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31954 + uint16_t keyIndex, uint8_t keySize,
31955 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
31956 +{
31957 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31958 + t_FmPcd *p_FmPcd;
31959 + t_List h_OldPointersLst, h_NewPointersLst;
31960 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31961 + uint16_t tmpKeyIndex;
31962 + bool useShadowStructs = FALSE;
31963 + t_Error err = E_OK;
31964 +
31965 + if (keyIndex > p_CcNode->numOfKeys)
31966 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31967 + ("keyIndex > previously cleared last index + 1"));
31968 +
31969 + if (keySize != p_CcNode->userSizeOfExtraction)
31970 + RETURN_ERROR(
31971 + MAJOR,
31972 + E_INVALID_VALUE,
31973 + ("keySize has to be defined as it was defined in initialization step"));
31974 +
31975 + if (p_CcNode->h_FmPcd != h_FmPcd)
31976 + RETURN_ERROR(
31977 + MAJOR,
31978 + E_INVALID_VALUE,
31979 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31980 +
31981 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
31982 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
31983 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31984 + RETURN_ERROR(
31985 + MINOR,
31986 + E_ALREADY_EXISTS,
31987 + ("The received key and mask pair was already found in the match table of the provided node"));
31988 +
31989 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31990 +
31991 + INIT_LIST(&h_OldPointersLst);
31992 + INIT_LIST(&h_NewPointersLst);
31993 +
31994 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31995 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
31996 + FALSE);
31997 + if (!p_ModifyKeyParams)
31998 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31999 +
32000 + if (p_CcNode->maxNumOfKeys)
32001 + {
32002 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
32003 + {
32004 + XX_Free(p_ModifyKeyParams);
32005 + return ERROR_CODE(E_BUSY);
32006 + }
32007 +
32008 + useShadowStructs = TRUE;
32009 + }
32010 +
32011 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
32012 + p_FmPcdCcKeyParams,
32013 + p_ModifyKeyParams, FALSE);
32014 + if (err)
32015 + {
32016 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32017 + XX_Free(p_ModifyKeyParams);
32018 + if (p_CcNode->maxNumOfKeys)
32019 + RELEASE_LOCK(p_FmPcd->shadowLock);
32020 + RETURN_ERROR(MAJOR, err, NO_MSG);
32021 + }
32022 +
32023 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
32024 + &h_OldPointersLst,
32025 + &h_NewPointersLst);
32026 + if (err)
32027 + {
32028 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32029 + XX_Free(p_ModifyKeyParams);
32030 + if (p_CcNode->maxNumOfKeys)
32031 + RELEASE_LOCK(p_FmPcd->shadowLock);
32032 + RETURN_ERROR(MAJOR, err, NO_MSG);
32033 + }
32034 +
32035 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32036 + p_ModifyKeyParams, useShadowStructs);
32037 +
32038 + if (p_CcNode->maxNumOfKeys)
32039 + RELEASE_LOCK(p_FmPcd->shadowLock);
32040 +
32041 + ReleaseLst(&h_OldPointersLst);
32042 + ReleaseLst(&h_NewPointersLst);
32043 +
32044 + return err;
32045 +}
32046 +
32047 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd,
32048 + t_Handle h_Pointer)
32049 +{
32050 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32051 + t_CcNodeInformation *p_CcNodeInfo;
32052 +
32053 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE,
32054 + (uint32_t)ILLEGAL_BASE);
32055 +
32056 + p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer);
32057 +
32058 + return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode)
32059 + - p_FmPcd->physicalMuramBase);
32060 +}
32061 +
32062 +t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId,
32063 + uint32_t *p_GrpBits, uint8_t *p_GrpBase)
32064 +{
32065 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32066 +
32067 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32068 +
32069 + if (grpId >= p_FmPcdCcTree->numOfGrps)
32070 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
32071 + ("grpId you asked > numOfGroup of relevant tree"));
32072 +
32073 + *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask;
32074 + *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry;
32075 +
32076 + return E_OK;
32077 +}
32078 +
32079 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams,
32080 + t_Handle h_FmPcdCcTree, uint32_t *p_Offset,
32081 + t_Handle h_FmPort)
32082 +{
32083 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
32084 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32085 + t_Error err = E_OK;
32086 +
32087 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
32088 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32089 +
32090 + /* this routine must be protected by the calling routine by locking all PCD modules! */
32091 +
32092 + err = CcUpdateParams(h_FmPcd, h_PcdParams, h_FmPort, h_FmPcdCcTree, TRUE);
32093 +
32094 + if (err == E_OK)
32095 + UpdateCcRootOwner(p_FmPcdCcTree, TRUE);
32096 +
32097 + *p_Offset = (uint32_t)(XX_VirtToPhys(
32098 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr))
32099 + - p_FmPcd->physicalMuramBase);
32100 +
32101 + return err;
32102 +}
32103 +
32104 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree)
32105 +{
32106 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32107 +
32108 + /* this routine must be protected by the calling routine by locking all PCD modules! */
32109 +
32110 + UNUSED(h_FmPcd);
32111 +
32112 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32113 +
32114 + UpdateCcRootOwner(p_FmPcdCcTree, FALSE);
32115 +
32116 + return E_OK;
32117 +}
32118 +
32119 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
32120 + t_List *p_List)
32121 +{
32122 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32123 + t_List *p_Pos, *p_Tmp;
32124 + t_CcNodeInformation *p_CcNodeInfo, nodeInfo;
32125 + uint32_t intFlags;
32126 + t_Error err = E_OK;
32127 +
32128 + intFlags = FmPcdLock(h_FmPcd);
32129 +
32130 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
32131 + {
32132 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32133 + ASSERT_COND(p_CcNodeInfo->h_CcNode);
32134 +
32135 + err = CcRootTryLock(p_CcNodeInfo->h_CcNode);
32136 +
32137 + if (err)
32138 + {
32139 + LIST_FOR_EACH(p_Tmp, &p_CcNode->ccTreesLst)
32140 + {
32141 + if (p_Tmp == p_Pos)
32142 + break;
32143 +
32144 + CcRootReleaseLock(p_CcNodeInfo->h_CcNode);
32145 + }
32146 + break;
32147 + }
32148 +
32149 + memset(&nodeInfo, 0, sizeof(t_CcNodeInformation));
32150 + nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode;
32151 + EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo, NULL);
32152 + }
32153 +
32154 + FmPcdUnlock(h_FmPcd, intFlags);
32155 + CORE_MemoryBarrier();
32156 +
32157 + return err;
32158 +}
32159 +
32160 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List)
32161 +{
32162 + t_List *p_Pos;
32163 + t_CcNodeInformation *p_CcNodeInfo;
32164 + t_Handle h_FmPcdCcTree;
32165 + uint32_t intFlags;
32166 +
32167 + intFlags = FmPcdLock(h_FmPcd);
32168 +
32169 + LIST_FOR_EACH(p_Pos, p_List)
32170 + {
32171 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32172 + h_FmPcdCcTree = p_CcNodeInfo->h_CcNode;
32173 + CcRootReleaseLock(h_FmPcdCcTree);
32174 + }
32175 +
32176 + ReleaseLst(p_List);
32177 +
32178 + FmPcdUnlock(h_FmPcd, intFlags);
32179 + CORE_MemoryBarrier();
32180 +}
32181 +
32182 +t_Error FmPcdUpdateCcShadow(t_FmPcd *p_FmPcd, uint32_t size, uint32_t align)
32183 +{
32184 + uint32_t intFlags;
32185 + uint32_t newSize = 0, newAlign = 0;
32186 + bool allocFail = FALSE;
32187 +
32188 + ASSERT_COND(p_FmPcd);
32189 +
32190 + if (!size)
32191 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size must be larger then 0"));
32192 +
32193 + if (!POWER_OF_2(align))
32194 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("alignment must be power of 2"));
32195 +
32196 + newSize = p_FmPcd->ccShadowSize;
32197 + newAlign = p_FmPcd->ccShadowAlign;
32198 +
32199 + /* Check if current shadow is large enough to hold the requested size */
32200 + if (size > p_FmPcd->ccShadowSize)
32201 + newSize = size;
32202 +
32203 + /* Check if current shadow matches the requested alignment */
32204 + if (align > p_FmPcd->ccShadowAlign)
32205 + newAlign = align;
32206 +
32207 + /* If a bigger shadow size or bigger shadow alignment are required,
32208 + a new shadow will be allocated */
32209 + if ((newSize != p_FmPcd->ccShadowSize)
32210 + || (newAlign != p_FmPcd->ccShadowAlign))
32211 + {
32212 + intFlags = FmPcdLock(p_FmPcd);
32213 +
32214 + if (p_FmPcd->p_CcShadow)
32215 + {
32216 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->p_CcShadow);
32217 + p_FmPcd->ccShadowSize = 0;
32218 + p_FmPcd->ccShadowAlign = 0;
32219 + }
32220 +
32221 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
32222 + newSize, newAlign);
32223 + if (!p_FmPcd->p_CcShadow)
32224 + {
32225 + allocFail = TRUE;
32226 +
32227 + /* If new shadow size allocation failed,
32228 + re-allocate with previous parameters */
32229 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(
32230 + FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->ccShadowSize,
32231 + p_FmPcd->ccShadowAlign);
32232 + }
32233 +
32234 + FmPcdUnlock(p_FmPcd, intFlags);
32235 +
32236 + if (allocFail)
32237 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32238 + ("MURAM allocation for CC Shadow memory"));
32239 +
32240 + p_FmPcd->ccShadowSize = newSize;
32241 + p_FmPcd->ccShadowAlign = newAlign;
32242 + }
32243 +
32244 + return E_OK;
32245 +}
32246 +
32247 +#if (DPAA_VERSION >= 11)
32248 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
32249 + t_Handle h_ReplicGroup,
32250 + t_List *p_AdTables,
32251 + uint32_t *p_NumOfAdTables)
32252 +{
32253 + t_FmPcdCcNode *p_CurrentNode = (t_FmPcdCcNode *)h_Node;
32254 + int i = 0;
32255 + void * p_AdTable;
32256 + t_CcNodeInformation ccNodeInfo;
32257 +
32258 + ASSERT_COND(h_Node);
32259 + *p_NumOfAdTables = 0;
32260 +
32261 + /* search in the current node which exact index points on this current replicator group for getting AD */
32262 + for (i = 0; i < p_CurrentNode->numOfKeys + 1; i++)
32263 + {
32264 + if ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32265 + == e_FM_PCD_FR)
32266 + && ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic
32267 + == (t_Handle)h_ReplicGroup)))
32268 + {
32269 + /* save the current ad table in the list */
32270 + /* this entry uses the input replicator group */
32271 + p_AdTable =
32272 + PTR_MOVE(p_CurrentNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
32273 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32274 + ccNodeInfo.h_CcNode = p_AdTable;
32275 + EnqueueNodeInfoToRelevantLst(p_AdTables, &ccNodeInfo, NULL);
32276 + (*p_NumOfAdTables)++;
32277 + }
32278 + }
32279 +
32280 + ASSERT_COND(i != p_CurrentNode->numOfKeys);
32281 +}
32282 +#endif /* (DPAA_VERSION >= 11) */
32283 +/*********************** End of inter-module routines ************************/
32284 +
32285 +/****************************************/
32286 +/* API Init unit functions */
32287 +/****************************************/
32288 +
32289 +t_Handle FM_PCD_CcRootBuild(t_Handle h_FmPcd,
32290 + t_FmPcdCcTreeParams *p_PcdGroupsParam)
32291 +{
32292 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32293 + t_Error err = E_OK;
32294 + int i = 0, j = 0, k = 0;
32295 + t_FmPcdCcTree *p_FmPcdCcTree;
32296 + uint8_t numOfEntries;
32297 + t_Handle p_CcTreeTmp;
32298 + t_FmPcdCcGrpParams *p_FmPcdCcGroupParams;
32299 + t_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams;
32300 + t_NetEnvParams netEnvParams;
32301 + uint8_t lastOne = 0;
32302 + uint32_t requiredAction = 0;
32303 + t_FmPcdCcNode *p_FmPcdCcNextNode;
32304 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
32305 +
32306 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32307 + SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam, E_INVALID_HANDLE, NULL);
32308 +
32309 + if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32310 + {
32311 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32312 + return NULL;
32313 + }
32314 +
32315 + p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree));
32316 + if (!p_FmPcdCcTree)
32317 + {
32318 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure"));
32319 + return NULL;
32320 + }
32321 + memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree));
32322 + p_FmPcdCcTree->h_FmPcd = h_FmPcd;
32323 +
32324 + p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc(
32325 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32326 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32327 + memset(p_Params,
32328 + 0,
32329 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32330 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32331 +
32332 + INIT_LIST(&p_FmPcdCcTree->fmPortsLst);
32333 +
32334 +#ifdef FM_CAPWAP_SUPPORT
32335 + if ((p_PcdGroupsParam->numOfGrps == 1) &&
32336 + (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) &&
32337 + (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) &&
32338 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode &&
32339 + IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode))
32340 + {
32341 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild();
32342 + if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip)
32343 + {
32344 + DeleteTree(p_FmPcdCcTree,p_FmPcd);
32345 + XX_Free(p_Params);
32346 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32347 + return NULL;
32348 + }
32349 + }
32350 +#endif /* FM_CAPWAP_SUPPORT */
32351 +
32352 + numOfEntries = 0;
32353 + p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv);
32354 +
32355 + for (i = 0; i < p_PcdGroupsParam->numOfGrps; i++)
32356 + {
32357 + p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i];
32358 +
32359 + if (p_FmPcdCcGroupParams->numOfDistinctionUnits
32360 + > FM_PCD_MAX_NUM_OF_CC_UNITS)
32361 + {
32362 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32363 + XX_Free(p_Params);
32364 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
32365 + ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS));
32366 + return NULL;
32367 + }
32368 +
32369 + p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries;
32370 + p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup = (uint8_t)(0x01
32371 + << p_FmPcdCcGroupParams->numOfDistinctionUnits);
32372 + numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32373 + if (numOfEntries > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32374 + {
32375 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32376 + XX_Free(p_Params);
32377 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32378 + return NULL;
32379 + }
32380 +
32381 + if (lastOne)
32382 + {
32383 + if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne)
32384 + {
32385 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32386 + XX_Free(p_Params);
32387 + REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order"));
32388 + return NULL;
32389 + }
32390 + }
32391 +
32392 + lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32393 +
32394 + netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId;
32395 + netEnvParams.numOfDistinctionUnits =
32396 + p_FmPcdCcGroupParams->numOfDistinctionUnits;
32397 +
32398 + memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds,
32399 + (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits);
32400 +
32401 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
32402 + if (err)
32403 + {
32404 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32405 + XX_Free(p_Params);
32406 + REPORT_ERROR(MAJOR, err, NO_MSG);
32407 + return NULL;
32408 + }
32409 +
32410 + p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector;
32411 + for (j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32412 + j++)
32413 + {
32414 + err = ValidateNextEngineParams(
32415 + h_FmPcd,
32416 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32417 + e_FM_PCD_CC_STATS_MODE_NONE);
32418 + if (err)
32419 + {
32420 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32421 + XX_Free(p_Params);
32422 + REPORT_ERROR(MAJOR, err, (NO_MSG));
32423 + return NULL;
32424 + }
32425 +
32426 + if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip)
32427 + {
32428 + err = FmPcdManipCheckParamsForCcNextEngine(
32429 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32430 + &requiredAction);
32431 + if (err)
32432 + {
32433 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32434 + XX_Free(p_Params);
32435 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32436 + return NULL;
32437 + }
32438 + }
32439 + p_KeyAndNextEngineParams = p_Params + k;
32440 +
32441 + memcpy(&p_KeyAndNextEngineParams->nextEngineParams,
32442 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32443 + sizeof(t_FmPcdCcNextEngineParams));
32444 +
32445 + if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine
32446 + == e_FM_PCD_CC)
32447 + && p_KeyAndNextEngineParams->nextEngineParams.h_Manip)
32448 + {
32449 + err =
32450 + AllocAndFillAdForContLookupManip(
32451 + p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode);
32452 + if (err)
32453 + {
32454 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32455 + XX_Free(p_Params);
32456 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32457 + return NULL;
32458 + }
32459 + }
32460 +
32461 + requiredAction |= UPDATE_CC_WITH_TREE;
32462 + p_KeyAndNextEngineParams->requiredAction = requiredAction;
32463 +
32464 + k++;
32465 + }
32466 + }
32467 +
32468 + p_FmPcdCcTree->numOfEntries = (uint8_t)k;
32469 + p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps;
32470 +
32471 + p_FmPcdCcTree->ccTreeBaseAddr =
32472 + PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
32473 + (uint32_t)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE),
32474 + FM_PCD_CC_TREE_ADDR_ALIGN));
32475 + if (!p_FmPcdCcTree->ccTreeBaseAddr)
32476 + {
32477 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32478 + XX_Free(p_Params);
32479 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32480 + return NULL;
32481 + }
32482 + MemSet8(
32483 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0,
32484 + (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE));
32485 +
32486 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32487 +
32488 + for (i = 0; i < numOfEntries; i++)
32489 + {
32490 + p_KeyAndNextEngineParams = p_Params + i;
32491 +
32492 + NextStepAd(p_CcTreeTmp, NULL,
32493 + &p_KeyAndNextEngineParams->nextEngineParams, p_FmPcd);
32494 +
32495 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32496 +
32497 + memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i],
32498 + p_KeyAndNextEngineParams,
32499 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
32500 +
32501 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32502 + == e_FM_PCD_CC)
32503 + {
32504 + p_FmPcdCcNextNode =
32505 + (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
32506 + p_CcInformation = FindNodeInfoInReleventLst(
32507 + &p_FmPcdCcNextNode->ccTreeIdLst, (t_Handle)p_FmPcdCcTree,
32508 + p_FmPcdCcNextNode->h_Spinlock);
32509 +
32510 + if (!p_CcInformation)
32511 + {
32512 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32513 + ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree;
32514 + ccNodeInfo.index = 1;
32515 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst,
32516 + &ccNodeInfo,
32517 + p_FmPcdCcNextNode->h_Spinlock);
32518 + }
32519 + else
32520 + p_CcInformation->index++;
32521 + }
32522 + }
32523 +
32524 + FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId);
32525 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32526 +
32527 + if (!FmPcdLockTryLockAll(p_FmPcd))
32528 + {
32529 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32530 + XX_Free(p_Params);
32531 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32532 + return NULL;
32533 + }
32534 +
32535 + for (i = 0; i < numOfEntries; i++)
32536 + {
32537 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction)
32538 + {
32539 + err = SetRequiredAction(
32540 + h_FmPcd,
32541 + p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction,
32542 + &p_FmPcdCcTree->keyAndNextEngineParams[i], p_CcTreeTmp, 1,
32543 + p_FmPcdCcTree);
32544 + if (err)
32545 + {
32546 + FmPcdLockUnlockAll(p_FmPcd);
32547 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32548 + XX_Free(p_Params);
32549 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32550 + return NULL;
32551 + }
32552 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32553 + }
32554 + }
32555 +
32556 + FmPcdLockUnlockAll(p_FmPcd);
32557 + p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd);
32558 + if (!p_FmPcdCcTree->p_Lock)
32559 + {
32560 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32561 + XX_Free(p_Params);
32562 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock"));
32563 + return NULL;
32564 + }
32565 +
32566 + XX_Free(p_Params);
32567 +
32568 + return p_FmPcdCcTree;
32569 +}
32570 +
32571 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree)
32572 +{
32573 + t_FmPcd *p_FmPcd;
32574 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32575 + int i = 0;
32576 +
32577 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32578 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32579 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32580 +
32581 + FmPcdDecNetEnvOwners(p_FmPcd, p_CcTree->netEnvId);
32582 +
32583 + if (p_CcTree->owners)
32584 + RETURN_ERROR(
32585 + MAJOR,
32586 + E_INVALID_SELECTION,
32587 + ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree"));
32588 +
32589 + /* Delete ip-reassembly schemes if exist */
32590 + if (p_CcTree->h_IpReassemblyManip)
32591 + {
32592 + FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip);
32593 + FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE);
32594 + }
32595 +
32596 + /* Delete capwap-reassembly schemes if exist */
32597 + if (p_CcTree->h_CapwapReassemblyManip)
32598 + {
32599 + FmPcdManipDeleteCapwapReassmSchemes(p_CcTree->h_CapwapReassemblyManip);
32600 + FmPcdManipUpdateOwner(p_CcTree->h_CapwapReassemblyManip, FALSE);
32601 + }
32602 +
32603 + for (i = 0; i < p_CcTree->numOfEntries; i++)
32604 + {
32605 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32606 + == e_FM_PCD_CC)
32607 + UpdateNodeOwner(
32608 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32609 + FALSE);
32610 +
32611 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32612 + FmPcdManipUpdateOwner(
32613 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32614 + FALSE);
32615 +
32616 +#ifdef FM_CAPWAP_SUPPORT
32617 + if ((p_CcTree->numOfGrps == 1) &&
32618 + (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) &&
32619 + (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) &&
32620 + p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode &&
32621 + IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode))
32622 + {
32623 + if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK)
32624 + return E_INVALID_STATE;
32625 + }
32626 +#endif /* FM_CAPWAP_SUPPORT */
32627 +
32628 +#if (DPAA_VERSION >= 11)
32629 + if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32630 + == e_FM_PCD_FR)
32631 + && (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32632 + FrmReplicGroupUpdateOwner(
32633 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32634 + FALSE);
32635 +#endif /* (DPAA_VERSION >= 11) */
32636 + }
32637 +
32638 + if (p_CcTree->p_Lock)
32639 + FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock);
32640 +
32641 + DeleteTree(p_CcTree, p_FmPcd);
32642 +
32643 + return E_OK;
32644 +}
32645 +
32646 +t_Error FM_PCD_CcRootModifyNextEngine(
32647 + t_Handle h_CcTree, uint8_t grpId, uint8_t index,
32648 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32649 +{
32650 + t_FmPcd *p_FmPcd;
32651 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32652 + t_Error err = E_OK;
32653 +
32654 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32655 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32656 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32657 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32658 +
32659 + if (!FmPcdLockTryLockAll(p_FmPcd))
32660 + {
32661 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32662 + return ERROR_CODE(E_BUSY);
32663 + }
32664 +
32665 + err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, p_CcTree, grpId, index,
32666 + p_FmPcdCcNextEngineParams);
32667 + FmPcdLockUnlockAll(p_FmPcd);
32668 +
32669 + if (err)
32670 + {
32671 + RETURN_ERROR(MAJOR, err, NO_MSG);
32672 + }
32673 +
32674 + return E_OK;
32675 +}
32676 +
32677 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd,
32678 + t_FmPcdCcNodeParams *p_CcNodeParam)
32679 +{
32680 + t_FmPcdCcNode *p_CcNode;
32681 + t_Error err;
32682 +
32683 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32684 + SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL);
32685 +
32686 + p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
32687 + if (!p_CcNode)
32688 + {
32689 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32690 + return NULL;
32691 + }
32692 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
32693 +
32694 + err = MatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam);
32695 +
32696 + switch(GET_ERROR_TYPE(err)
32697 +) {
32698 + case E_OK:
32699 + break;
32700 +
32701 + case E_BUSY:
32702 + DBG(TRACE, ("E_BUSY error"));
32703 + return NULL;
32704 +
32705 + default:
32706 + REPORT_ERROR(MAJOR, err, NO_MSG);
32707 + return NULL;
32708 + }
32709 +
32710 + return p_CcNode;
32711 +}
32712 +
32713 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode)
32714 +{
32715 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32716 + int i = 0;
32717 +
32718 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32719 + SANITY_CHECK_RETURN_ERROR(p_CcNode->h_FmPcd, E_INVALID_HANDLE);
32720 +
32721 + if (p_CcNode->owners)
32722 + RETURN_ERROR(
32723 + MAJOR,
32724 + E_INVALID_STATE,
32725 + ("This node cannot be removed because it is occupied; first unbind this node"));
32726 +
32727 + for (i = 0; i < p_CcNode->numOfKeys; i++)
32728 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32729 + == e_FM_PCD_CC)
32730 + UpdateNodeOwner(
32731 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32732 + FALSE);
32733 +
32734 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32735 + == e_FM_PCD_CC)
32736 + UpdateNodeOwner(
32737 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32738 + FALSE);
32739 +
32740 + /* Handle also Miss entry */
32741 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
32742 + {
32743 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32744 + FmPcdManipUpdateOwner(
32745 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32746 + FALSE);
32747 +
32748 +#if (DPAA_VERSION >= 11)
32749 + if ((p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32750 + == e_FM_PCD_FR)
32751 + && (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32752 + {
32753 + FrmReplicGroupUpdateOwner(
32754 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32755 + FALSE);
32756 + }
32757 +#endif /* (DPAA_VERSION >= 11) */
32758 + }
32759 +
32760 + DeleteNode(p_CcNode);
32761 +
32762 + return E_OK;
32763 +}
32764 +
32765 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, uint16_t keyIndex,
32766 + uint8_t keySize,
32767 + t_FmPcdCcKeyParams *p_KeyParams)
32768 +{
32769 + t_FmPcd *p_FmPcd;
32770 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32771 + t_Error err = E_OK;
32772 +
32773 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
32774 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32775 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32776 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32777 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32778 +
32779 + if (keyIndex == FM_PCD_LAST_KEY_INDEX)
32780 + keyIndex = p_CcNode->numOfKeys;
32781 +
32782 + if (!FmPcdLockTryLockAll(p_FmPcd))
32783 + {
32784 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32785 + return ERROR_CODE(E_BUSY);
32786 + }
32787 +
32788 + err = FmPcdCcAddKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_KeyParams);
32789 +
32790 + FmPcdLockUnlockAll(p_FmPcd);
32791 +
32792 + switch(GET_ERROR_TYPE(err)
32793 +) {
32794 + case E_OK:
32795 + return E_OK;
32796 +
32797 + case E_BUSY:
32798 + DBG(TRACE, ("E_BUSY error"));
32799 + return ERROR_CODE(E_BUSY);
32800 +
32801 + default:
32802 + RETURN_ERROR(MAJOR, err, NO_MSG);
32803 + }
32804 +}
32805 +
32806 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex)
32807 +{
32808 + t_FmPcd *p_FmPcd;
32809 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32810 + t_Error err = E_OK;
32811 +
32812 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32813 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32814 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32815 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32816 +
32817 + if (!FmPcdLockTryLockAll(p_FmPcd))
32818 + {
32819 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32820 + return ERROR_CODE(E_BUSY);
32821 + }
32822 +
32823 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
32824 +
32825 + FmPcdLockUnlockAll(p_FmPcd);
32826 +
32827 + switch(GET_ERROR_TYPE(err)
32828 +) {
32829 + case E_OK:
32830 + return E_OK;
32831 +
32832 + case E_BUSY:
32833 + DBG(TRACE, ("E_BUSY error"));
32834 + return ERROR_CODE(E_BUSY);
32835 +
32836 + default:
32837 + RETURN_ERROR(MAJOR, err, NO_MSG);
32838 + }
32839 +
32840 + return E_OK;
32841 +}
32842 +
32843 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, uint16_t keyIndex,
32844 + uint8_t keySize, uint8_t *p_Key,
32845 + uint8_t *p_Mask)
32846 +{
32847 + t_FmPcd *p_FmPcd;
32848 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32849 + t_Error err = E_OK;
32850 +
32851 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32852 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
32853 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32854 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32855 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32856 +
32857 +
32858 + if (!FmPcdLockTryLockAll(p_FmPcd))
32859 + {
32860 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32861 + return ERROR_CODE(E_BUSY);
32862 + }
32863 +
32864 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_Key, p_Mask);
32865 +
32866 + FmPcdLockUnlockAll(p_FmPcd);
32867 +
32868 + switch(GET_ERROR_TYPE(err)
32869 +) {
32870 + case E_OK:
32871 + return E_OK;
32872 +
32873 + case E_BUSY:
32874 + DBG(TRACE, ("E_BUSY error"));
32875 + return ERROR_CODE(E_BUSY);
32876 +
32877 + default:
32878 + RETURN_ERROR(MAJOR, err, NO_MSG);
32879 + }
32880 +}
32881 +
32882 +t_Error FM_PCD_MatchTableModifyNextEngine(
32883 + t_Handle h_CcNode, uint16_t keyIndex,
32884 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32885 +{
32886 + t_FmPcd *p_FmPcd;
32887 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32888 + t_Error err = E_OK;
32889 +
32890 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32891 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32892 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32893 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32894 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32895 +
32896 + if (!FmPcdLockTryLockAll(p_FmPcd))
32897 + {
32898 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32899 + return ERROR_CODE(E_BUSY);
32900 + }
32901 +
32902 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
32903 + p_FmPcdCcNextEngineParams);
32904 +
32905 + FmPcdLockUnlockAll(p_FmPcd);
32906 +
32907 + switch(GET_ERROR_TYPE(err)
32908 +) {
32909 + case E_OK:
32910 + return E_OK;
32911 +
32912 + case E_BUSY:
32913 + DBG(TRACE, ("E_BUSY error"));
32914 + return ERROR_CODE(E_BUSY);
32915 +
32916 + default:
32917 + RETURN_ERROR(MAJOR, err, NO_MSG);
32918 + }
32919 +}
32920 +
32921 +t_Error FM_PCD_MatchTableModifyMissNextEngine(
32922 + t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32923 +{
32924 + t_FmPcd *p_FmPcd;
32925 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32926 + t_Error err = E_OK;
32927 +
32928 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32929 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32930 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32931 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32932 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32933 +
32934 + if (!FmPcdLockTryLockAll(p_FmPcd))
32935 + {
32936 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32937 + return ERROR_CODE(E_BUSY);
32938 + }
32939 +
32940 + err = FmPcdCcModifyMissNextEngineParamNode(p_FmPcd, p_CcNode,
32941 + p_FmPcdCcNextEngineParams);
32942 +
32943 + FmPcdLockUnlockAll(p_FmPcd);
32944 +
32945 + switch(GET_ERROR_TYPE(err)
32946 +) {
32947 + case E_OK:
32948 + return E_OK;
32949 +
32950 + case E_BUSY:
32951 + DBG(TRACE, ("E_BUSY error"));
32952 + return ERROR_CODE(E_BUSY);
32953 +
32954 + default:
32955 + RETURN_ERROR(MAJOR, err, NO_MSG);
32956 + }
32957 +}
32958 +
32959 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
32960 + uint16_t keyIndex,
32961 + uint8_t keySize,
32962 + t_FmPcdCcKeyParams *p_KeyParams)
32963 +{
32964 + t_FmPcd *p_FmPcd;
32965 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32966 + t_Error err = E_OK;
32967 +
32968 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
32969 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32970 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32971 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32972 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32973 +
32974 + if (!FmPcdLockTryLockAll(p_FmPcd))
32975 + {
32976 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32977 + return ERROR_CODE(E_BUSY);
32978 + }
32979 +
32980 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, p_CcNode, keyIndex, keySize,
32981 + p_KeyParams);
32982 +
32983 + FmPcdLockUnlockAll(p_FmPcd);
32984 +
32985 + switch(GET_ERROR_TYPE(err)
32986 +) {
32987 + case E_OK:
32988 + return E_OK;
32989 +
32990 + case E_BUSY:
32991 + DBG(TRACE, ("E_BUSY error"));
32992 + return ERROR_CODE(E_BUSY);
32993 +
32994 + default:
32995 + RETURN_ERROR(MAJOR, err, NO_MSG);
32996 + }
32997 +}
32998 +
32999 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, uint8_t keySize,
33000 + uint8_t *p_Key, uint8_t *p_Mask)
33001 +{
33002 + t_FmPcd *p_FmPcd;
33003 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33004 + uint16_t keyIndex;
33005 + t_Error err;
33006 +
33007 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33008 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33009 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33010 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33011 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33012 +
33013 + if (!FmPcdLockTryLockAll(p_FmPcd))
33014 + {
33015 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33016 + return ERROR_CODE(E_BUSY);
33017 + }
33018 +
33019 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33020 + if (GET_ERROR_TYPE(err) != E_OK)
33021 + {
33022 + FmPcdLockUnlockAll(p_FmPcd);
33023 + RETURN_ERROR(
33024 + MAJOR,
33025 + err,
33026 + ("The received key and mask pair was not found in the match table of the provided node"));
33027 + }
33028 +
33029 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
33030 +
33031 + FmPcdLockUnlockAll(p_FmPcd);
33032 +
33033 + switch(GET_ERROR_TYPE(err)
33034 +) {
33035 + case E_OK:
33036 + return E_OK;
33037 +
33038 + case E_BUSY:
33039 + DBG(TRACE, ("E_BUSY error"));
33040 + return ERROR_CODE(E_BUSY);
33041 +
33042 + default:
33043 + RETURN_ERROR(MAJOR, err, NO_MSG);
33044 + }
33045 +}
33046 +
33047 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(
33048 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33049 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33050 +{
33051 + t_FmPcd *p_FmPcd;
33052 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33053 + uint16_t keyIndex;
33054 + t_Error err;
33055 +
33056 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33057 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33058 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33059 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33060 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33061 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33062 +
33063 + if (!FmPcdLockTryLockAll(p_FmPcd))
33064 + {
33065 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33066 + return ERROR_CODE(E_BUSY);
33067 + }
33068 +
33069 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33070 + if (GET_ERROR_TYPE(err) != E_OK)
33071 + {
33072 + FmPcdLockUnlockAll(p_FmPcd);
33073 + RETURN_ERROR(
33074 + MAJOR,
33075 + err,
33076 + ("The received key and mask pair was not found in the match table of the provided node"));
33077 + }
33078 +
33079 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
33080 + p_FmPcdCcNextEngineParams);
33081 +
33082 + FmPcdLockUnlockAll(p_FmPcd);
33083 +
33084 + switch(GET_ERROR_TYPE(err)
33085 +) {
33086 + case E_OK:
33087 + return E_OK;
33088 +
33089 + case E_BUSY:
33090 + DBG(TRACE, ("E_BUSY error"));
33091 + return ERROR_CODE(E_BUSY);
33092 +
33093 + default:
33094 + RETURN_ERROR(MAJOR, err, NO_MSG);
33095 + }
33096 +}
33097 +
33098 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(
33099 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33100 + t_FmPcdCcKeyParams *p_KeyParams)
33101 +{
33102 + t_FmPcd *p_FmPcd;
33103 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33104 + uint16_t keyIndex;
33105 + t_Error err;
33106 +
33107 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33108 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33109 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33110 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33111 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33112 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33113 +
33114 + if (!FmPcdLockTryLockAll(p_FmPcd))
33115 + {
33116 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33117 + return ERROR_CODE(E_BUSY);
33118 + }
33119 +
33120 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33121 + if (GET_ERROR_TYPE(err) != E_OK)
33122 + {
33123 + FmPcdLockUnlockAll(p_FmPcd);
33124 + RETURN_ERROR(
33125 + MAJOR,
33126 + err,
33127 + ("The received key and mask pair was not found in the match table of the provided node"));
33128 + }
33129 +
33130 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, h_CcNode, keyIndex, keySize,
33131 + p_KeyParams);
33132 +
33133 + FmPcdLockUnlockAll(p_FmPcd);
33134 +
33135 + switch(GET_ERROR_TYPE(err)
33136 +) {
33137 + case E_OK:
33138 + return E_OK;
33139 +
33140 + case E_BUSY:
33141 + DBG(TRACE, ("E_BUSY error"));
33142 + return ERROR_CODE(E_BUSY);
33143 +
33144 + default:
33145 + RETURN_ERROR(MAJOR, err, NO_MSG);
33146 + }
33147 +}
33148 +
33149 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, uint8_t keySize,
33150 + uint8_t *p_Key, uint8_t *p_Mask,
33151 + uint8_t *p_NewKey, uint8_t *p_NewMask)
33152 +{
33153 + t_FmPcd *p_FmPcd;
33154 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33155 + t_List h_List;
33156 + uint16_t keyIndex;
33157 + t_Error err;
33158 +
33159 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33160 + SANITY_CHECK_RETURN_ERROR(p_NewKey, E_NULL_POINTER);
33161 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33162 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33163 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33164 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33165 +
33166 + INIT_LIST(&h_List);
33167 +
33168 + err = FmPcdCcNodeTreeTryLock(p_FmPcd, p_CcNode, &h_List);
33169 + if (err)
33170 + {
33171 + DBG(TRACE, ("Node's trees lock failed"));
33172 + return ERROR_CODE(E_BUSY);
33173 + }
33174 +
33175 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33176 + if (GET_ERROR_TYPE(err) != E_OK)
33177 + {
33178 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33179 + RETURN_ERROR(MAJOR, err,
33180 + ("The received key and mask pair was not found in the "
33181 + "match table of the provided node"));
33182 + }
33183 +
33184 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_NewKey,
33185 + p_NewMask);
33186 +
33187 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33188 +
33189 + switch(GET_ERROR_TYPE(err)
33190 +) {
33191 + case E_OK:
33192 + return E_OK;
33193 +
33194 + case E_BUSY:
33195 + DBG(TRACE, ("E_BUSY error"));
33196 + return ERROR_CODE(E_BUSY);
33197 +
33198 + default:
33199 + RETURN_ERROR(MAJOR, err, NO_MSG);
33200 + }
33201 +}
33202 +
33203 +t_Error FM_PCD_MatchTableGetNextEngine(
33204 + t_Handle h_CcNode, uint16_t keyIndex,
33205 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33206 +{
33207 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33208 +
33209 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33210 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33211 +
33212 + if (keyIndex >= p_CcNode->numOfKeys)
33213 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33214 + ("keyIndex exceeds current number of keys"));
33215 +
33216 + if (keyIndex > (FM_PCD_MAX_NUM_OF_KEYS - 1))
33217 + RETURN_ERROR(
33218 + MAJOR,
33219 + E_INVALID_VALUE,
33220 + ("keyIndex can not be larger than %d", (FM_PCD_MAX_NUM_OF_KEYS - 1)));
33221 +
33222 + memcpy(p_FmPcdCcNextEngineParams,
33223 + &p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams,
33224 + sizeof(t_FmPcdCcNextEngineParams));
33225 +
33226 + return E_OK;
33227 +}
33228 +
33229 +
33230 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex)
33231 +{
33232 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33233 + uint32_t *p_StatsCounters, frameCount;
33234 + uint32_t intFlags;
33235 +
33236 + SANITY_CHECK_RETURN_VALUE(p_CcNode, E_INVALID_HANDLE, 0);
33237 +
33238 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
33239 + {
33240 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table"));
33241 + return 0;
33242 + }
33243 +
33244 + if ((p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_FRAME)
33245 + && (p_CcNode->statisticsMode
33246 + != e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33247 + {
33248 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Frame count is not supported in the statistics mode of this match table"));
33249 + return 0;
33250 + }
33251 +
33252 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33253 +
33254 + if (keyIndex >= p_CcNode->numOfKeys)
33255 + {
33256 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33257 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table"));
33258 + return 0;
33259 + }
33260 +
33261 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
33262 + {
33263 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33264 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key"));
33265 + return 0;
33266 + }
33267 +
33268 + p_StatsCounters =
33269 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
33270 + ASSERT_COND(p_StatsCounters);
33271 +
33272 + /* The first counter is byte counter, so we need to advance to the next counter */
33273 + frameCount = GET_UINT32(*(uint32_t *)(PTR_MOVE(p_StatsCounters,
33274 + FM_PCD_CC_STATS_COUNTER_SIZE)));
33275 +
33276 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33277 +
33278 + return frameCount;
33279 +}
33280 +
33281 +t_Error FM_PCD_MatchTableGetKeyStatistics(
33282 + t_Handle h_CcNode, uint16_t keyIndex,
33283 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33284 +{
33285 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33286 + uint32_t intFlags;
33287 + t_Error err;
33288 +
33289 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33290 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33291 +
33292 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33293 +
33294 + if (keyIndex >= p_CcNode->numOfKeys)
33295 + RETURN_ERROR(
33296 + MAJOR,
33297 + E_INVALID_STATE,
33298 + ("The provided keyIndex exceeds the number of keys in this match table"));
33299 +
33300 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33301 +
33302 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33303 +
33304 + if (err != E_OK)
33305 + RETURN_ERROR(MAJOR, err, NO_MSG);
33306 +
33307 + return E_OK;
33308 +}
33309 +
33310 +t_Error FM_PCD_MatchTableGetMissStatistics(
33311 + t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_MissStatistics)
33312 +{
33313 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33314 + uint32_t intFlags;
33315 + t_Error err;
33316 +
33317 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33318 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
33319 +
33320 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33321 +
33322 + err = MatchTableGetKeyStatistics(p_CcNode, p_CcNode->numOfKeys,
33323 + p_MissStatistics);
33324 +
33325 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33326 +
33327 + if (err != E_OK)
33328 + RETURN_ERROR(MAJOR, err, NO_MSG);
33329 +
33330 + return E_OK;
33331 +}
33332 +
33333 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(
33334 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33335 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33336 +{
33337 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33338 + uint16_t keyIndex;
33339 + uint32_t intFlags;
33340 + t_Error err;
33341 +
33342 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33343 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33344 +
33345 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33346 +
33347 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33348 + if (GET_ERROR_TYPE(err) != E_OK)
33349 + {
33350 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33351 + RETURN_ERROR(MAJOR, err,
33352 + ("The received key and mask pair was not found in the "
33353 + "match table of the provided node"));
33354 + }
33355 +
33356 + ASSERT_COND(keyIndex < p_CcNode->numOfKeys);
33357 +
33358 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33359 +
33360 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33361 +
33362 + if (err != E_OK)
33363 + RETURN_ERROR(MAJOR, err, NO_MSG);
33364 +
33365 + return E_OK;
33366 +}
33367 +
33368 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
33369 + uint8_t keySize, uint8_t *p_Key,
33370 + uint8_t hashShift,
33371 + t_Handle *p_CcNodeBucketHandle,
33372 + uint8_t *p_BucketIndex,
33373 + uint16_t *p_LastIndex)
33374 +{
33375 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33376 + uint16_t glblMask;
33377 + uint64_t crc64 = 0;
33378 +
33379 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33380 + SANITY_CHECK_RETURN_ERROR(
33381 + p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED,
33382 + E_INVALID_STATE);
33383 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33384 + SANITY_CHECK_RETURN_ERROR(p_CcNodeBucketHandle, E_NULL_POINTER);
33385 +
33386 + memcpy(&glblMask, PTR_MOVE(p_CcNode->p_GlblMask, 2), 2);
33387 + be16_to_cpus(&glblMask);
33388 +
33389 + crc64 = crc64_init();
33390 + crc64 = crc64_compute(p_Key, keySize, crc64);
33391 + crc64 >>= hashShift;
33392 +
33393 + *p_BucketIndex = (uint8_t)(((crc64 >> (8 * (6 - p_CcNode->userOffset)))
33394 + & glblMask) >> 4);
33395 + if (*p_BucketIndex >= p_CcNode->numOfKeys)
33396 + RETURN_ERROR(MINOR, E_NOT_IN_RANGE, ("bucket index!"));
33397 +
33398 + *p_CcNodeBucketHandle =
33399 + p_CcNode->keyAndNextEngineParams[*p_BucketIndex].nextEngineParams.params.ccParams.h_CcNode;
33400 + if (!*p_CcNodeBucketHandle)
33401 + RETURN_ERROR(MINOR, E_NOT_FOUND, ("bucket!"));
33402 +
33403 + *p_LastIndex = ((t_FmPcdCcNode *)*p_CcNodeBucketHandle)->numOfKeys;
33404 +
33405 + return E_OK;
33406 +}
33407 +
33408 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param)
33409 +{
33410 + t_FmPcdCcNode *p_CcNodeHashTbl;
33411 + t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam;
33412 + t_FmPcdCcNode *p_CcNode;
33413 + t_Handle h_MissStatsCounters = NULL;
33414 + t_FmPcdCcKeyParams *p_HashKeyParams;
33415 + int i;
33416 + uint16_t numOfSets, numOfWays, countMask, onesCount = 0;
33417 + bool statsEnForMiss = FALSE;
33418 + t_Error err;
33419 +
33420 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
33421 + SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL);
33422 +
33423 + if (p_Param->maxNumOfKeys == 0)
33424 + {
33425 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Max number of keys must be higher then 0"));
33426 + return NULL;
33427 + }
33428 +
33429 + if (p_Param->hashResMask == 0)
33430 + {
33431 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Hash result mask must differ from 0"));
33432 + return NULL;
33433 + }
33434 +
33435 + /*Fix: QorIQ SDK / QSDK-2131*/
33436 + if (p_Param->ccNextEngineParamsForMiss.nextEngine == e_FM_PCD_INVALID)
33437 + {
33438 + 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."));
33439 + return NULL;
33440 + }
33441 +
33442 +#if (DPAA_VERSION >= 11)
33443 + if (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_RMON)
33444 + {
33445 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
33446 + ("RMON statistics mode is not supported for hash table"));
33447 + return NULL;
33448 + }
33449 +#endif /* (DPAA_VERSION >= 11) */
33450 +
33451 + p_ExactMatchCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33452 + sizeof(t_FmPcdCcNodeParams));
33453 + if (!p_ExactMatchCcNodeParam)
33454 + {
33455 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_ExactMatchCcNodeParam"));
33456 + return NULL;
33457 + }
33458 + memset(p_ExactMatchCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33459 +
33460 + p_IndxHashCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33461 + sizeof(t_FmPcdCcNodeParams));
33462 + if (!p_IndxHashCcNodeParam)
33463 + {
33464 + XX_Free(p_ExactMatchCcNodeParam);
33465 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_IndxHashCcNodeParam"));
33466 + return NULL;
33467 + }
33468 + memset(p_IndxHashCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33469 +
33470 + /* Calculate number of sets and number of ways of the hash table */
33471 + countMask = (uint16_t)(p_Param->hashResMask >> 4);
33472 + while (countMask)
33473 + {
33474 + onesCount++;
33475 + countMask = (uint16_t)(countMask >> 1);
33476 + }
33477 +
33478 + numOfSets = (uint16_t)(1 << onesCount);
33479 + numOfWays = (uint16_t)DIV_CEIL(p_Param->maxNumOfKeys, numOfSets);
33480 +
33481 + if (p_Param->maxNumOfKeys % numOfSets)
33482 + DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up"));
33483 +
33484 + if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME)
33485 + || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33486 + {
33487 + /* Allocating a statistics counters table that will be used by all
33488 + 'miss' entries of the hash table */
33489 + h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem(
33490 + FmPcdGetMuramHandle(h_FmPcd), 2 * FM_PCD_CC_STATS_COUNTER_SIZE,
33491 + FM_PCD_CC_AD_TABLE_ALIGN);
33492 + if (!h_MissStatsCounters)
33493 + {
33494 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss"));
33495 + XX_Free(p_IndxHashCcNodeParam);
33496 + XX_Free(p_ExactMatchCcNodeParam);
33497 + return NULL;
33498 + }
33499 + memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33500 +
33501 + /* Always enable statistics for 'miss', so that a statistics AD will be
33502 + initialized from the start. We'll store the requested 'statistics enable'
33503 + value and it will be used when statistics are read by the user. */
33504 + statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn;
33505 + p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE;
33506 + }
33507 +
33508 + /* Building exact-match node params, will be used to create the hash buckets */
33509 + p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33510 +
33511 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.src =
33512 + e_FM_PCD_EXTRACT_FROM_KEY;
33513 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.action =
33514 + e_FM_PCD_ACTION_EXACT_MATCH;
33515 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.offset = 0;
33516 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.size =
33517 + p_Param->matchKeySize;
33518 +
33519 + p_ExactMatchCcNodeParam->keysParams.maxNumOfKeys = numOfWays;
33520 + p_ExactMatchCcNodeParam->keysParams.maskSupport = FALSE;
33521 + p_ExactMatchCcNodeParam->keysParams.statisticsMode =
33522 + p_Param->statisticsMode;
33523 + p_ExactMatchCcNodeParam->keysParams.numOfKeys = 0;
33524 + p_ExactMatchCcNodeParam->keysParams.keySize = p_Param->matchKeySize;
33525 + p_ExactMatchCcNodeParam->keysParams.ccNextEngineParamsForMiss =
33526 + p_Param->ccNextEngineParamsForMiss;
33527 +
33528 + p_HashKeyParams = p_IndxHashCcNodeParam->keysParams.keyParams;
33529 +
33530 + for (i = 0; i < numOfSets; i++)
33531 + {
33532 + /* Each exact-match node will be marked as a 'bucket' and provided with
33533 + a pointer to statistics counters, to be used for 'miss' entry
33534 + statistics */
33535 + p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode));
33536 + if (!p_CcNode)
33537 + break;
33538 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
33539 +
33540 + p_CcNode->isHashBucket = TRUE;
33541 + p_CcNode->h_MissStatsCounters = h_MissStatsCounters;
33542 +
33543 + err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam);
33544 + if (err)
33545 + break;
33546 +
33547 + p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC;
33548 + p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE;
33549 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode =
33550 + p_CcNode;
33551 + }
33552 +
33553 + if (i < numOfSets)
33554 + {
33555 + for (i = i - 1; i >= 0; i--)
33556 + FM_PCD_MatchTableDelete(
33557 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode);
33558 +
33559 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33560 +
33561 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
33562 + XX_Free(p_IndxHashCcNodeParam);
33563 + XX_Free(p_ExactMatchCcNodeParam);
33564 + return NULL;
33565 + }
33566 +
33567 + /* Creating indexed-hash CC node */
33568 + p_IndxHashCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33569 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.src =
33570 + e_FM_PCD_EXTRACT_FROM_HASH;
33571 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.action =
33572 + e_FM_PCD_ACTION_INDEXED_LOOKUP;
33573 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.icIndxMask =
33574 + p_Param->hashResMask;
33575 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.offset =
33576 + p_Param->hashShift;
33577 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.size = 2;
33578 +
33579 + p_IndxHashCcNodeParam->keysParams.maxNumOfKeys = numOfSets;
33580 + p_IndxHashCcNodeParam->keysParams.maskSupport = FALSE;
33581 + p_IndxHashCcNodeParam->keysParams.statisticsMode =
33582 + e_FM_PCD_CC_STATS_MODE_NONE;
33583 + /* Number of keys of this node is number of sets of the hash */
33584 + p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets;
33585 + p_IndxHashCcNodeParam->keysParams.keySize = 2;
33586 +
33587 + p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam);
33588 +
33589 + if (p_CcNodeHashTbl)
33590 + {
33591 + p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift;
33592 +
33593 + /* Storing the allocated counters for buckets 'miss' in the hash table
33594 + and if statistics for miss were enabled. */
33595 + p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters;
33596 + p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss;
33597 + }
33598 +
33599 + XX_Free(p_IndxHashCcNodeParam);
33600 + XX_Free(p_ExactMatchCcNodeParam);
33601 +
33602 + return p_CcNodeHashTbl;
33603 +}
33604 +
33605 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl)
33606 +{
33607 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33608 + t_Handle h_FmPcd;
33609 + t_Handle *p_HashBuckets, h_MissStatsCounters;
33610 + uint16_t i, numOfBuckets;
33611 + t_Error err;
33612 +
33613 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33614 +
33615 + /* Store all hash buckets before the hash is freed */
33616 + numOfBuckets = p_HashTbl->numOfKeys;
33617 +
33618 + p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle));
33619 + if (!p_HashBuckets)
33620 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
33621 +
33622 + for (i = 0; i < numOfBuckets; i++)
33623 + p_HashBuckets[i] =
33624 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33625 +
33626 + h_FmPcd = p_HashTbl->h_FmPcd;
33627 + h_MissStatsCounters = p_HashTbl->h_MissStatsCounters;
33628 +
33629 + /* Free the hash */
33630 + err = FM_PCD_MatchTableDelete(p_HashTbl);
33631 +
33632 + /* Free each hash bucket */
33633 + for (i = 0; i < numOfBuckets; i++)
33634 + err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]);
33635 +
33636 + XX_Free(p_HashBuckets);
33637 +
33638 + /* Free statistics counters for 'miss', if these were allocated */
33639 + if (h_MissStatsCounters)
33640 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33641 +
33642 + if (err)
33643 + RETURN_ERROR(MAJOR, err, NO_MSG);
33644 +
33645 + return E_OK;
33646 +}
33647 +
33648 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, uint8_t keySize,
33649 + t_FmPcdCcKeyParams *p_KeyParams)
33650 +{
33651 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33652 + t_Handle h_HashBucket;
33653 + uint8_t bucketIndex;
33654 + uint16_t lastIndex;
33655 + t_Error err;
33656 +
33657 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33658 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33659 + SANITY_CHECK_RETURN_ERROR(p_KeyParams->p_Key, E_NULL_POINTER);
33660 +
33661 + if (p_KeyParams->p_Mask)
33662 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
33663 + ("Keys masks not supported for hash table"));
33664 +
33665 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize,
33666 + p_KeyParams->p_Key,
33667 + p_HashTbl->kgHashShift,
33668 + &h_HashBucket, &bucketIndex,
33669 + &lastIndex);
33670 + if (err)
33671 + RETURN_ERROR(MAJOR, err, NO_MSG);
33672 +
33673 + return FM_PCD_MatchTableAddKey(h_HashBucket, FM_PCD_LAST_KEY_INDEX, keySize,
33674 + p_KeyParams);
33675 +}
33676 +
33677 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, uint8_t keySize,
33678 + uint8_t *p_Key)
33679 +{
33680 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33681 + t_Handle h_HashBucket;
33682 + uint8_t bucketIndex;
33683 + uint16_t lastIndex;
33684 + t_Error err;
33685 +
33686 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33687 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33688 +
33689 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33690 + p_HashTbl->kgHashShift,
33691 + &h_HashBucket, &bucketIndex,
33692 + &lastIndex);
33693 + if (err)
33694 + RETURN_ERROR(MAJOR, err, NO_MSG);
33695 +
33696 + return FM_PCD_MatchTableFindNRemoveKey(h_HashBucket, keySize, p_Key, NULL);
33697 +}
33698 +
33699 +t_Error FM_PCD_HashTableModifyNextEngine(
33700 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
33701 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33702 +{
33703 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33704 + t_Handle h_HashBucket;
33705 + uint8_t bucketIndex;
33706 + uint16_t lastIndex;
33707 + t_Error err;
33708 +
33709 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33710 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33711 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33712 +
33713 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33714 + p_HashTbl->kgHashShift,
33715 + &h_HashBucket, &bucketIndex,
33716 + &lastIndex);
33717 + if (err)
33718 + RETURN_ERROR(MAJOR, err, NO_MSG);
33719 +
33720 + return FM_PCD_MatchTableFindNModifyNextEngine(h_HashBucket, keySize, p_Key,
33721 + NULL,
33722 + p_FmPcdCcNextEngineParams);
33723 +}
33724 +
33725 +t_Error FM_PCD_HashTableModifyMissNextEngine(
33726 + t_Handle h_HashTbl,
33727 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33728 +{
33729 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33730 + t_Handle h_HashBucket;
33731 + uint8_t i;
33732 + bool nullifyMissStats = FALSE;
33733 + t_Error err;
33734 +
33735 + SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE);
33736 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33737 +
33738 + if ((!p_HashTbl->h_MissStatsCounters)
33739 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33740 + RETURN_ERROR(
33741 + MAJOR,
33742 + E_CONFLICT,
33743 + ("Statistics are requested for a key, but statistics mode was set"
33744 + "to 'NONE' upon initialization"));
33745 +
33746 + if (p_HashTbl->h_MissStatsCounters)
33747 + {
33748 + if ((!p_HashTbl->statsEnForMiss)
33749 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33750 + nullifyMissStats = TRUE;
33751 +
33752 + if ((p_HashTbl->statsEnForMiss)
33753 + && (!p_FmPcdCcNextEngineParams->statisticsEn))
33754 + {
33755 + p_HashTbl->statsEnForMiss = FALSE;
33756 + p_FmPcdCcNextEngineParams->statisticsEn = TRUE;
33757 + }
33758 + }
33759 +
33760 + for (i = 0; i < p_HashTbl->numOfKeys; i++)
33761 + {
33762 + h_HashBucket =
33763 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33764 +
33765 + err = FM_PCD_MatchTableModifyMissNextEngine(h_HashBucket,
33766 + p_FmPcdCcNextEngineParams);
33767 + if (err)
33768 + RETURN_ERROR(MAJOR, err, NO_MSG);
33769 + }
33770 +
33771 + if (nullifyMissStats)
33772 + {
33773 + memset(p_HashTbl->h_MissStatsCounters, 0,
33774 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33775 + memset(p_HashTbl->h_MissStatsCounters, 0,
33776 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33777 + p_HashTbl->statsEnForMiss = TRUE;
33778 + }
33779 +
33780 + return E_OK;
33781 +}
33782 +
33783 +
33784 +t_Error FM_PCD_HashTableGetMissNextEngine(
33785 + t_Handle h_HashTbl,
33786 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33787 +{
33788 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33789 + t_FmPcdCcNode *p_HashBucket;
33790 +
33791 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33792 +
33793 + /* Miss next engine of each bucket was initialized with the next engine of the hash table */
33794 + p_HashBucket =
33795 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
33796 +
33797 + memcpy(p_FmPcdCcNextEngineParams,
33798 + &p_HashBucket->keyAndNextEngineParams[p_HashBucket->numOfKeys].nextEngineParams,
33799 + sizeof(t_FmPcdCcNextEngineParams));
33800 +
33801 + return E_OK;
33802 +}
33803 +
33804 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(
33805 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
33806 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33807 +{
33808 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33809 + t_Handle h_HashBucket;
33810 + uint8_t bucketIndex;
33811 + uint16_t lastIndex;
33812 + t_Error err;
33813 +
33814 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33815 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33816 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33817 +
33818 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33819 + p_HashTbl->kgHashShift,
33820 + &h_HashBucket, &bucketIndex,
33821 + &lastIndex);
33822 + if (err)
33823 + RETURN_ERROR(MAJOR, err, NO_MSG);
33824 +
33825 + return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, keySize, p_Key,
33826 + NULL, p_KeyStatistics);
33827 +}
33828 +
33829 +t_Error FM_PCD_HashTableGetMissStatistics(
33830 + t_Handle h_HashTbl, t_FmPcdCcKeyStatistics *p_MissStatistics)
33831 +{
33832 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33833 + t_Handle h_HashBucket;
33834 +
33835 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33836 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
33837 +
33838 + if (!p_HashTbl->statsEnForMiss)
33839 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33840 + ("Statistics were not enabled for miss"));
33841 +
33842 + h_HashBucket =
33843 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
33844 +
33845 + return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics);
33846 +}
33847 --- /dev/null
33848 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
33849 @@ -0,0 +1,399 @@
33850 +/*
33851 + * Copyright 2008-2012 Freescale Semiconductor Inc.
33852 + *
33853 + * Redistribution and use in source and binary forms, with or without
33854 + * modification, are permitted provided that the following conditions are met:
33855 + * * Redistributions of source code must retain the above copyright
33856 + * notice, this list of conditions and the following disclaimer.
33857 + * * Redistributions in binary form must reproduce the above copyright
33858 + * notice, this list of conditions and the following disclaimer in the
33859 + * documentation and/or other materials provided with the distribution.
33860 + * * Neither the name of Freescale Semiconductor nor the
33861 + * names of its contributors may be used to endorse or promote products
33862 + * derived from this software without specific prior written permission.
33863 + *
33864 + *
33865 + * ALTERNATIVELY, this software may be distributed under the terms of the
33866 + * GNU General Public License ("GPL") as published by the Free Software
33867 + * Foundation, either version 2 of that License or (at your option) any
33868 + * later version.
33869 + *
33870 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
33871 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33872 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33873 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
33874 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33875 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33876 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33877 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33878 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33879 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33880 + */
33881 +
33882 +
33883 +/******************************************************************************
33884 + @File fm_cc.h
33885 +
33886 + @Description FM PCD CC ...
33887 +*//***************************************************************************/
33888 +#ifndef __FM_CC_H
33889 +#define __FM_CC_H
33890 +
33891 +#include "std_ext.h"
33892 +#include "error_ext.h"
33893 +#include "list_ext.h"
33894 +
33895 +#include "fm_pcd.h"
33896 +
33897 +
33898 +/***********************************************************************/
33899 +/* Coarse classification defines */
33900 +/***********************************************************************/
33901 +
33902 +#define CC_MAX_NUM_OF_KEYS (FM_PCD_MAX_NUM_OF_KEYS + 1)
33903 +
33904 +#define CC_PC_FF_MACDST 0x00
33905 +#define CC_PC_FF_MACSRC 0x01
33906 +#define CC_PC_FF_ETYPE 0x02
33907 +
33908 +#define CC_PC_FF_TCI1 0x03
33909 +#define CC_PC_FF_TCI2 0x04
33910 +
33911 +#define CC_PC_FF_MPLS1 0x06
33912 +#define CC_PC_FF_MPLS_LAST 0x07
33913 +
33914 +#define CC_PC_FF_IPV4DST1 0x08
33915 +#define CC_PC_FF_IPV4DST2 0x16
33916 +#define CC_PC_FF_IPV4IPTOS_TC1 0x09
33917 +#define CC_PC_FF_IPV4IPTOS_TC2 0x17
33918 +#define CC_PC_FF_IPV4PTYPE1 0x0A
33919 +#define CC_PC_FF_IPV4PTYPE2 0x18
33920 +#define CC_PC_FF_IPV4SRC1 0x0b
33921 +#define CC_PC_FF_IPV4SRC2 0x19
33922 +#define CC_PC_FF_IPV4SRC1_IPV4DST1 0x0c
33923 +#define CC_PC_FF_IPV4SRC2_IPV4DST2 0x1a
33924 +#define CC_PC_FF_IPV4TTL 0x29
33925 +
33926 +
33927 +#define CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1 0x0d /*TODO - CLASS - what is it? TOS*/
33928 +#define CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2 0x1b
33929 +#define CC_PC_FF_IPV6PTYPE1 0x0e
33930 +#define CC_PC_FF_IPV6PTYPE2 0x1c
33931 +#define CC_PC_FF_IPV6DST1 0x0f
33932 +#define CC_PC_FF_IPV6DST2 0x1d
33933 +#define CC_PC_FF_IPV6SRC1 0x10
33934 +#define CC_PC_FF_IPV6SRC2 0x1e
33935 +#define CC_PC_FF_IPV6HOP_LIMIT 0x2a
33936 +#define CC_PC_FF_IPPID 0x24
33937 +#define CC_PC_FF_IPDSCP 0x76
33938 +
33939 +#define CC_PC_FF_GREPTYPE 0x11
33940 +
33941 +#define CC_PC_FF_MINENCAP_PTYPE 0x12
33942 +#define CC_PC_FF_MINENCAP_IPDST 0x13
33943 +#define CC_PC_FF_MINENCAP_IPSRC 0x14
33944 +#define CC_PC_FF_MINENCAP_IPSRC_IPDST 0x15
33945 +
33946 +#define CC_PC_FF_L4PSRC 0x1f
33947 +#define CC_PC_FF_L4PDST 0x20
33948 +#define CC_PC_FF_L4PSRC_L4PDST 0x21
33949 +
33950 +#define CC_PC_FF_PPPPID 0x05
33951 +
33952 +#define CC_PC_PR_SHIM1 0x22
33953 +#define CC_PC_PR_SHIM2 0x23
33954 +
33955 +#define CC_PC_GENERIC_WITHOUT_MASK 0x27
33956 +#define CC_PC_GENERIC_WITH_MASK 0x28
33957 +#define CC_PC_GENERIC_IC_GMASK 0x2B
33958 +#define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C
33959 +#define CC_PC_GENERIC_IC_AGING_MASK 0x2D
33960 +
33961 +#define CC_PR_OFFSET 0x25
33962 +#define CC_PR_WITHOUT_OFFSET 0x26
33963 +
33964 +#define CC_PC_PR_ETH_OFFSET 19
33965 +#define CC_PC_PR_USER_DEFINED_SHIM1_OFFSET 16
33966 +#define CC_PC_PR_USER_DEFINED_SHIM2_OFFSET 17
33967 +#define CC_PC_PR_USER_LLC_SNAP_OFFSET 20
33968 +#define CC_PC_PR_VLAN1_OFFSET 21
33969 +#define CC_PC_PR_VLAN2_OFFSET 22
33970 +#define CC_PC_PR_PPPOE_OFFSET 24
33971 +#define CC_PC_PR_MPLS1_OFFSET 25
33972 +#define CC_PC_PR_MPLS_LAST_OFFSET 26
33973 +#define CC_PC_PR_IP1_OFFSET 27
33974 +#define CC_PC_PR_IP_LAST_OFFSET 28
33975 +#define CC_PC_PR_MINENC_OFFSET 28
33976 +#define CC_PC_PR_L4_OFFSET 30
33977 +#define CC_PC_PR_GRE_OFFSET 29
33978 +#define CC_PC_PR_ETYPE_LAST_OFFSET 23
33979 +#define CC_PC_PR_NEXT_HEADER_OFFSET 31
33980 +
33981 +#define CC_PC_ILLEGAL 0xff
33982 +#define CC_SIZE_ILLEGAL 0
33983 +
33984 +#define FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN 16
33985 +#define FM_PCD_CC_AD_TABLE_ALIGN 16
33986 +#define FM_PCD_CC_AD_ENTRY_SIZE 16
33987 +#define FM_PCD_CC_NUM_OF_KEYS 255
33988 +#define FM_PCD_CC_TREE_ADDR_ALIGN 256
33989 +
33990 +#define FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE 0x00000000
33991 +#define FM_PCD_AD_RESULT_DATA_FLOW_TYPE 0x80000000
33992 +#define FM_PCD_AD_RESULT_PLCR_DIS 0x20000000
33993 +#define FM_PCD_AD_RESULT_EXTENDED_MODE 0x80000000
33994 +#define FM_PCD_AD_RESULT_NADEN 0x20000000
33995 +#define FM_PCD_AD_RESULT_STATISTICS_EN 0x40000000
33996 +
33997 +#define FM_PCD_AD_CONT_LOOKUP_TYPE 0x40000000
33998 +#define FM_PCD_AD_CONT_LOOKUP_LCL_MASK 0x00800000
33999 +
34000 +#define FM_PCD_AD_STATS_TYPE 0x40000000
34001 +#define FM_PCD_AD_STATS_FLR_ADDR_MASK 0x00FFFFFF
34002 +#define FM_PCD_AD_STATS_COUNTERS_ADDR_MASK 0x00FFFFFF
34003 +#define FM_PCD_AD_STATS_NEXT_ACTION_MASK 0xFFFF0000
34004 +#define FM_PCD_AD_STATS_NEXT_ACTION_SHIFT 12
34005 +#define FM_PCD_AD_STATS_NAD_EN 0x00008000
34006 +#define FM_PCD_AD_STATS_OP_CODE 0x00000036
34007 +#define FM_PCD_AD_STATS_FLR_EN 0x00004000
34008 +#define FM_PCD_AD_STATS_COND_EN 0x00002000
34009 +
34010 +
34011 +
34012 +#define FM_PCD_AD_BYPASS_TYPE 0xc0000000
34013 +
34014 +#define FM_PCD_AD_TYPE_MASK 0xc0000000
34015 +#define FM_PCD_AD_OPCODE_MASK 0x0000000f
34016 +
34017 +#define FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT 16
34018 +#if (DPAA_VERSION >= 11)
34019 +#define FM_PCD_AD_RESULT_VSP_SHIFT 24
34020 +#define FM_PCD_AD_RESULT_NO_OM_VSPE 0x02000000
34021 +#define FM_PCD_AD_RESULT_VSP_MASK 0x3f
34022 +#define FM_PCD_AD_NCSPFQIDM_MASK 0x80000000
34023 +#endif /* (DPAA_VERSION >= 11) */
34024 +
34025 +#define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000
34026 +#define CC_GLBL_MASK_SIZE 4
34027 +#define CC_AGING_MASK_SIZE 4
34028 +
34029 +typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */
34030 +
34031 +#define CC_PRIVATE_INFO_NONE 0
34032 +#define CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP 0x80000000
34033 +#define CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH 0x40000000
34034 +#define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000
34035 +#define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000
34036 +
34037 +#define CC_BUILD_AGING_MASK(numOfKeys) ((((1LL << ((numOfKeys) + 1)) - 1)) << (31 - (numOfKeys)))
34038 +/***********************************************************************/
34039 +/* Memory map */
34040 +/***********************************************************************/
34041 +#if defined(__MWERKS__) && !defined(__GNUC__)
34042 +#pragma pack(push,1)
34043 +#endif /* defined(__MWERKS__) && ... */
34044 +
34045 +typedef struct
34046 +{
34047 + volatile uint32_t fqid;
34048 + volatile uint32_t plcrProfile;
34049 + volatile uint32_t nia;
34050 + volatile uint32_t res;
34051 +} t_AdOfTypeResult;
34052 +
34053 +typedef struct
34054 +{
34055 + volatile uint32_t ccAdBase;
34056 + volatile uint32_t matchTblPtr;
34057 + volatile uint32_t pcAndOffsets;
34058 + volatile uint32_t gmask;
34059 +} t_AdOfTypeContLookup;
34060 +
34061 +typedef struct
34062 +{
34063 + volatile uint32_t profileTableAddr;
34064 + volatile uint32_t reserved;
34065 + volatile uint32_t nextActionIndx;
34066 + volatile uint32_t statsTableAddr;
34067 +} t_AdOfTypeStats;
34068 +
34069 +typedef union
34070 +{
34071 + volatile t_AdOfTypeResult adResult;
34072 + volatile t_AdOfTypeContLookup adContLookup;
34073 +} t_Ad;
34074 +
34075 +#if defined(__MWERKS__) && !defined(__GNUC__)
34076 +#pragma pack(pop)
34077 +#endif /* defined(__MWERKS__) && ... */
34078 +
34079 +
34080 +/***********************************************************************/
34081 +/* Driver's internal structures */
34082 +/***********************************************************************/
34083 +
34084 +typedef struct t_FmPcdStatsObj
34085 +{
34086 + t_Handle h_StatsAd;
34087 + t_Handle h_StatsCounters;
34088 + t_List node;
34089 +} t_FmPcdStatsObj;
34090 +
34091 +typedef struct
34092 +{
34093 + uint8_t key[FM_PCD_MAX_SIZE_OF_KEY];
34094 + uint8_t mask[FM_PCD_MAX_SIZE_OF_KEY];
34095 +
34096 + t_FmPcdCcNextEngineParams nextEngineParams;
34097 + uint32_t requiredAction;
34098 + uint32_t shadowAction;
34099 +
34100 + t_FmPcdStatsObj *p_StatsObj;
34101 +
34102 +} t_FmPcdCcKeyAndNextEngineParams;
34103 +
34104 +typedef struct
34105 +{
34106 + t_Handle p_Ad;
34107 + e_FmPcdEngine fmPcdEngine;
34108 + bool adAllocated;
34109 + bool isTree;
34110 +
34111 + uint32_t myInfo;
34112 + t_List *h_CcNextNodesLst;
34113 + t_Handle h_AdditionalInfo;
34114 + t_Handle h_Node;
34115 +} t_FmPcdModifyCcAdditionalParams;
34116 +
34117 +typedef struct
34118 +{
34119 + t_Handle p_AdTableNew;
34120 + t_Handle p_KeysMatchTableNew;
34121 + t_Handle p_AdTableOld;
34122 + t_Handle p_KeysMatchTableOld;
34123 + uint16_t numOfKeys;
34124 + t_Handle h_CurrentNode;
34125 + uint16_t savedKeyIndex;
34126 + t_Handle h_NodeForAdd;
34127 + t_Handle h_NodeForRmv;
34128 + t_Handle h_ManipForRmv;
34129 + t_Handle h_ManipForAdd;
34130 + t_FmPcdStatsObj *p_StatsObjForRmv;
34131 +#if (DPAA_VERSION >= 11)
34132 + t_Handle h_FrmReplicForAdd;
34133 + t_Handle h_FrmReplicForRmv;
34134 +#endif /* (DPAA_VERSION >= 11) */
34135 + bool tree;
34136 +
34137 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34138 +} t_FmPcdModifyCcKeyAdditionalParams;
34139 +
34140 +typedef struct
34141 +{
34142 + t_Handle h_Manip;
34143 + t_Handle h_CcNode;
34144 +} t_CcNextEngineInfo;
34145 +
34146 +typedef struct
34147 +{
34148 + uint16_t numOfKeys;
34149 + uint16_t maxNumOfKeys;
34150 +
34151 + bool maskSupport;
34152 + uint32_t keysMatchTableMaxSize;
34153 +
34154 + e_FmPcdCcStatsMode statisticsMode;
34155 + uint32_t numOfStatsFLRs;
34156 + uint32_t countersArraySize;
34157 +
34158 + bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */
34159 + t_Handle h_MissStatsCounters; /**< Valid for hash table node and match table that is a bucket;
34160 + Holds the statistics counters allocated by the hash table and
34161 + are shared by all hash table buckets; */
34162 + t_Handle h_PrivMissStatsCounters; /**< Valid for match table node that is a bucket of a hash table only;
34163 + Holds the statistics counters that were allocated for this node
34164 + and replaced by the shared counters (allocated by the hash table); */
34165 + bool statsEnForMiss; /**< Valid for hash table node only; TRUE is statistics are currently
34166 + enabled for hash 'miss', FALSE otherwise; This parameter effects the
34167 + returned statistics count to user, statistics AD always present for 'miss'
34168 + for all hash buckets; */
34169 + bool glblMaskUpdated;
34170 + t_Handle p_GlblMask;
34171 + bool lclMask;
34172 + uint8_t parseCode;
34173 + uint8_t offset;
34174 + uint8_t prsArrayOffset;
34175 + bool ctrlFlow;
34176 + uint16_t owners;
34177 +
34178 + uint8_t ccKeySizeAccExtraction;
34179 + uint8_t sizeOfExtraction;
34180 + uint8_t glblMaskSize;
34181 +
34182 + t_Handle h_KeysMatchTable;
34183 + t_Handle h_AdTable;
34184 + t_Handle h_StatsAds;
34185 + t_Handle h_TmpAd;
34186 + t_Handle h_Ad;
34187 + t_Handle h_StatsFLRs;
34188 +
34189 + t_List availableStatsLst;
34190 +
34191 + t_List ccPrevNodesLst;
34192 +
34193 + t_List ccTreeIdLst;
34194 + t_List ccTreesLst;
34195 +
34196 + t_Handle h_FmPcd;
34197 + uint32_t shadowAction;
34198 + uint8_t userSizeOfExtraction;
34199 + uint8_t userOffset;
34200 + uint8_t kgHashShift; /* used in hash-table */
34201 +
34202 + t_Handle h_Spinlock;
34203 +
34204 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34205 +} t_FmPcdCcNode;
34206 +
34207 +typedef struct
34208 +{
34209 + t_FmPcdCcNode *p_FmPcdCcNode;
34210 + bool occupied;
34211 + uint16_t owners;
34212 + volatile bool lock;
34213 +} t_FmPcdCcNodeArray;
34214 +
34215 +typedef struct
34216 +{
34217 + uint8_t numOfEntriesInGroup;
34218 + uint32_t totalBitsMask;
34219 + uint8_t baseGroupEntry;
34220 +} t_FmPcdCcGroupParam;
34221 +
34222 +typedef struct
34223 +{
34224 + t_Handle h_FmPcd;
34225 + uint8_t netEnvId;
34226 + uintptr_t ccTreeBaseAddr;
34227 + uint8_t numOfGrps;
34228 + t_FmPcdCcGroupParam fmPcdGroupParam[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34229 + t_List fmPortsLst;
34230 + t_FmPcdLock *p_Lock;
34231 + uint8_t numOfEntries;
34232 + uint16_t owners;
34233 + t_Handle h_FmPcdCcSavedManipParams;
34234 + bool modifiedState;
34235 + uint32_t requiredAction;
34236 + t_Handle h_IpReassemblyManip;
34237 + t_Handle h_CapwapReassemblyManip;
34238 +
34239 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34240 +} t_FmPcdCcTree;
34241 +
34242 +
34243 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List);
34244 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List);
34245 +t_Error FmPcdUpdateCcShadow (t_FmPcd *p_FmPcd, uint32_t size, uint32_t align);
34246 +
34247 +
34248 +#endif /* __FM_CC_H */
34249 --- /dev/null
34250 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
34251 @@ -0,0 +1,3242 @@
34252 +/*
34253 + * Copyright 2008-2012 Freescale Semiconductor Inc.
34254 + *
34255 + * Redistribution and use in source and binary forms, with or without
34256 + * modification, are permitted provided that the following conditions are met:
34257 + * * Redistributions of source code must retain the above copyright
34258 + * notice, this list of conditions and the following disclaimer.
34259 + * * Redistributions in binary form must reproduce the above copyright
34260 + * notice, this list of conditions and the following disclaimer in the
34261 + * documentation and/or other materials provided with the distribution.
34262 + * * Neither the name of Freescale Semiconductor nor the
34263 + * names of its contributors may be used to endorse or promote products
34264 + * derived from this software without specific prior written permission.
34265 + *
34266 + *
34267 + * ALTERNATIVELY, this software may be distributed under the terms of the
34268 + * GNU General Public License ("GPL") as published by the Free Software
34269 + * Foundation, either version 2 of that License or (at your option) any
34270 + * later version.
34271 + *
34272 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
34273 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34274 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34275 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
34276 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34277 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34278 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34279 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34280 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34281 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34282 + */
34283 +
34284 +
34285 +/******************************************************************************
34286 + @File fm_kg.c
34287 +
34288 + @Description FM PCD ...
34289 +*//***************************************************************************/
34290 +#include "std_ext.h"
34291 +#include "error_ext.h"
34292 +#include "string_ext.h"
34293 +#include "debug_ext.h"
34294 +#include "net_ext.h"
34295 +#include "fm_port_ext.h"
34296 +
34297 +#include "fm_common.h"
34298 +#include "fm_pcd.h"
34299 +#include "fm_hc.h"
34300 +#include "fm_pcd_ipc.h"
34301 +#include "fm_kg.h"
34302 +#include "fsl_fman_kg.h"
34303 +
34304 +
34305 +/****************************************/
34306 +/* static functions */
34307 +/****************************************/
34308 +
34309 +static uint32_t KgHwLock(t_Handle h_FmPcdKg)
34310 +{
34311 + ASSERT_COND(h_FmPcdKg);
34312 + return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock);
34313 +}
34314 +
34315 +static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags)
34316 +{
34317 + ASSERT_COND(h_FmPcdKg);
34318 + XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags);
34319 +}
34320 +
34321 +static uint32_t KgSchemeLock(t_Handle h_Scheme)
34322 +{
34323 + ASSERT_COND(h_Scheme);
34324 + return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34325 +}
34326 +
34327 +static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags)
34328 +{
34329 + ASSERT_COND(h_Scheme);
34330 + FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags);
34331 +}
34332 +
34333 +static bool KgSchemeFlagTryLock(t_Handle h_Scheme)
34334 +{
34335 + ASSERT_COND(h_Scheme);
34336 + return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34337 +}
34338 +
34339 +static void KgSchemeFlagUnlock(t_Handle h_Scheme)
34340 +{
34341 + ASSERT_COND(h_Scheme);
34342 + FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34343 +}
34344 +
34345 +static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar)
34346 +{
34347 +
34348 + struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
34349 +
34350 + if (fman_kg_write_ar_wait(regs, fmkg_ar))
34351 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation"));
34352 +
34353 + return E_OK;
34354 +}
34355 +
34356 +static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code)
34357 +{
34358 + int i;
34359 +
34360 + switch (code)
34361 + {
34362 + case (KG_SCH_GEN_PARSE_RESULT_N_FQID):
34363 + case (KG_SCH_GEN_DEFAULT):
34364 + case (KG_SCH_GEN_NEXTHDR):
34365 + for (i=0 ; i<numOfSwDefaults ; i++)
34366 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA)
34367 + return swDefaults[i].dfltSelect;
34368 + break;
34369 + case (KG_SCH_GEN_SHIM1):
34370 + case (KG_SCH_GEN_SHIM2):
34371 + case (KG_SCH_GEN_IP_PID_NO_V):
34372 + case (KG_SCH_GEN_ETH_NO_V):
34373 + case (KG_SCH_GEN_SNAP_NO_V):
34374 + case (KG_SCH_GEN_VLAN1_NO_V):
34375 + case (KG_SCH_GEN_VLAN2_NO_V):
34376 + case (KG_SCH_GEN_ETH_TYPE_NO_V):
34377 + case (KG_SCH_GEN_PPP_NO_V):
34378 + case (KG_SCH_GEN_MPLS1_NO_V):
34379 + case (KG_SCH_GEN_MPLS_LAST_NO_V):
34380 + case (KG_SCH_GEN_L3_NO_V):
34381 + case (KG_SCH_GEN_IP2_NO_V):
34382 + case (KG_SCH_GEN_GRE_NO_V):
34383 + case (KG_SCH_GEN_L4_NO_V):
34384 + for (i=0 ; i<numOfSwDefaults ; i++)
34385 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V)
34386 + return swDefaults[i].dfltSelect;
34387 + break;
34388 + case (KG_SCH_GEN_START_OF_FRM):
34389 + case (KG_SCH_GEN_ETH):
34390 + case (KG_SCH_GEN_SNAP):
34391 + case (KG_SCH_GEN_VLAN1):
34392 + case (KG_SCH_GEN_VLAN2):
34393 + case (KG_SCH_GEN_ETH_TYPE):
34394 + case (KG_SCH_GEN_PPP):
34395 + case (KG_SCH_GEN_MPLS1):
34396 + case (KG_SCH_GEN_MPLS2):
34397 + case (KG_SCH_GEN_MPLS3):
34398 + case (KG_SCH_GEN_MPLS_LAST):
34399 + case (KG_SCH_GEN_IPV4):
34400 + case (KG_SCH_GEN_IPV6):
34401 + case (KG_SCH_GEN_IPV4_TUNNELED):
34402 + case (KG_SCH_GEN_IPV6_TUNNELED):
34403 + case (KG_SCH_GEN_MIN_ENCAP):
34404 + case (KG_SCH_GEN_GRE):
34405 + case (KG_SCH_GEN_TCP):
34406 + case (KG_SCH_GEN_UDP):
34407 + case (KG_SCH_GEN_IPSEC_AH):
34408 + case (KG_SCH_GEN_SCTP):
34409 + case (KG_SCH_GEN_DCCP):
34410 + case (KG_SCH_GEN_IPSEC_ESP):
34411 + for (i=0 ; i<numOfSwDefaults ; i++)
34412 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA)
34413 + return swDefaults[i].dfltSelect;
34414 + break;
34415 + default:
34416 + break;
34417 + }
34418 +
34419 + return e_FM_PCD_KG_DFLT_ILLEGAL;
34420 +}
34421 +
34422 +static uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset)
34423 +{
34424 + *p_Offset = 0;
34425 +
34426 + switch (src)
34427 + {
34428 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
34429 + return KG_SCH_GEN_START_OF_FRM;
34430 + case (e_FM_PCD_EXTRACT_FROM_DFLT_VALUE):
34431 + return KG_SCH_GEN_DEFAULT;
34432 + case (e_FM_PCD_EXTRACT_FROM_PARSE_RESULT):
34433 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34434 + case (e_FM_PCD_EXTRACT_FROM_ENQ_FQID):
34435 + *p_Offset = 32;
34436 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34437 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
34438 + return KG_SCH_GEN_NEXTHDR;
34439 + default:
34440 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
34441 + return 0;
34442 + }
34443 +}
34444 +
34445 +static uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation)
34446 +{
34447 + if (!ignoreProtocolValidation)
34448 + switch (hdr)
34449 + {
34450 + case (HEADER_TYPE_NONE):
34451 + ASSERT_COND(FALSE);
34452 + case (HEADER_TYPE_ETH):
34453 + return KG_SCH_GEN_ETH;
34454 + case (HEADER_TYPE_LLC_SNAP):
34455 + return KG_SCH_GEN_SNAP;
34456 + case (HEADER_TYPE_PPPoE):
34457 + return KG_SCH_GEN_PPP;
34458 + case (HEADER_TYPE_MPLS):
34459 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34460 + return KG_SCH_GEN_MPLS1;
34461 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
34462 + return KG_SCH_GEN_MPLS2;
34463 + if (hdrIndex == e_FM_PCD_HDR_INDEX_3)
34464 + return KG_SCH_GEN_MPLS3;
34465 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34466 + return KG_SCH_GEN_MPLS_LAST;
34467 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34468 + return 0;
34469 + case (HEADER_TYPE_IPv4):
34470 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34471 + return KG_SCH_GEN_IPV4;
34472 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34473 + return KG_SCH_GEN_IPV4_TUNNELED;
34474 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index"));
34475 + return 0;
34476 + case (HEADER_TYPE_IPv6):
34477 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34478 + return KG_SCH_GEN_IPV6;
34479 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34480 + return KG_SCH_GEN_IPV6_TUNNELED;
34481 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index"));
34482 + return 0;
34483 + case (HEADER_TYPE_GRE):
34484 + return KG_SCH_GEN_GRE;
34485 + case (HEADER_TYPE_TCP):
34486 + return KG_SCH_GEN_TCP;
34487 + case (HEADER_TYPE_UDP):
34488 + return KG_SCH_GEN_UDP;
34489 + case (HEADER_TYPE_IPSEC_AH):
34490 + return KG_SCH_GEN_IPSEC_AH;
34491 + case (HEADER_TYPE_IPSEC_ESP):
34492 + return KG_SCH_GEN_IPSEC_ESP;
34493 + case (HEADER_TYPE_SCTP):
34494 + return KG_SCH_GEN_SCTP;
34495 + case (HEADER_TYPE_DCCP):
34496 + return KG_SCH_GEN_DCCP;
34497 + default:
34498 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34499 + return 0;
34500 + }
34501 + else
34502 + switch (hdr)
34503 + {
34504 + case (HEADER_TYPE_NONE):
34505 + ASSERT_COND(FALSE);
34506 + case (HEADER_TYPE_ETH):
34507 + return KG_SCH_GEN_ETH_NO_V;
34508 + case (HEADER_TYPE_LLC_SNAP):
34509 + return KG_SCH_GEN_SNAP_NO_V;
34510 + case (HEADER_TYPE_PPPoE):
34511 + return KG_SCH_GEN_PPP_NO_V;
34512 + case (HEADER_TYPE_MPLS):
34513 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34514 + return KG_SCH_GEN_MPLS1_NO_V;
34515 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34516 + return KG_SCH_GEN_MPLS_LAST_NO_V;
34517 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) )
34518 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported"));
34519 + else
34520 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34521 + return 0;
34522 + case (HEADER_TYPE_IPv4):
34523 + case (HEADER_TYPE_IPv6):
34524 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34525 + return KG_SCH_GEN_L3_NO_V;
34526 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34527 + return KG_SCH_GEN_IP2_NO_V;
34528 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
34529 + case (HEADER_TYPE_MINENCAP):
34530 + return KG_SCH_GEN_IP2_NO_V;
34531 + case (HEADER_TYPE_USER_DEFINED_L3):
34532 + return KG_SCH_GEN_L3_NO_V;
34533 + case (HEADER_TYPE_GRE):
34534 + return KG_SCH_GEN_GRE_NO_V;
34535 + case (HEADER_TYPE_TCP):
34536 + case (HEADER_TYPE_UDP):
34537 + case (HEADER_TYPE_IPSEC_AH):
34538 + case (HEADER_TYPE_IPSEC_ESP):
34539 + case (HEADER_TYPE_SCTP):
34540 + case (HEADER_TYPE_DCCP):
34541 + return KG_SCH_GEN_L4_NO_V;
34542 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
34543 + return KG_SCH_GEN_SHIM1;
34544 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
34545 + return KG_SCH_GEN_SHIM2;
34546 + default:
34547 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34548 + return 0;
34549 + }
34550 +}
34551 +static t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex)
34552 +{
34553 + if (!ignoreProtocolValidation)
34554 + switch (hdr)
34555 + {
34556 + case (HEADER_TYPE_NONE):
34557 + ASSERT_COND(FALSE);
34558 + break;
34559 + case (HEADER_TYPE_ETH):
34560 + switch (field.eth)
34561 + {
34562 + case (NET_HEADER_FIELD_ETH_TYPE):
34563 + return KG_SCH_GEN_ETH_TYPE;
34564 + default:
34565 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34566 + return 0;
34567 + }
34568 + break;
34569 + case (HEADER_TYPE_VLAN):
34570 + switch (field.vlan)
34571 + {
34572 + case (NET_HEADER_FIELD_VLAN_TCI):
34573 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34574 + return KG_SCH_GEN_VLAN1;
34575 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34576 + return KG_SCH_GEN_VLAN2;
34577 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34578 + return 0;
34579 + }
34580 + break;
34581 + case (HEADER_TYPE_MPLS):
34582 + case (HEADER_TYPE_IPSEC_AH):
34583 + case (HEADER_TYPE_IPSEC_ESP):
34584 + case (HEADER_TYPE_LLC_SNAP):
34585 + case (HEADER_TYPE_PPPoE):
34586 + case (HEADER_TYPE_IPv4):
34587 + case (HEADER_TYPE_IPv6):
34588 + case (HEADER_TYPE_GRE):
34589 + case (HEADER_TYPE_MINENCAP):
34590 + case (HEADER_TYPE_USER_DEFINED_L3):
34591 + case (HEADER_TYPE_TCP):
34592 + case (HEADER_TYPE_UDP):
34593 + case (HEADER_TYPE_SCTP):
34594 + case (HEADER_TYPE_DCCP):
34595 + case (HEADER_TYPE_USER_DEFINED_L4):
34596 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34597 + return 0;
34598 + default:
34599 + break;
34600 +
34601 + }
34602 + else
34603 + switch (hdr)
34604 + {
34605 + case (HEADER_TYPE_NONE):
34606 + ASSERT_COND(FALSE);
34607 + break;
34608 + case (HEADER_TYPE_ETH):
34609 + switch (field.eth)
34610 + {
34611 + case (NET_HEADER_FIELD_ETH_TYPE):
34612 + return KG_SCH_GEN_ETH_TYPE_NO_V;
34613 + default:
34614 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34615 + return 0;
34616 + }
34617 + break;
34618 + case (HEADER_TYPE_VLAN):
34619 + switch (field.vlan)
34620 + {
34621 + case (NET_HEADER_FIELD_VLAN_TCI) :
34622 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34623 + return KG_SCH_GEN_VLAN1_NO_V;
34624 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34625 + return KG_SCH_GEN_VLAN2_NO_V;
34626 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34627 + return 0;
34628 + }
34629 + break;
34630 + case (HEADER_TYPE_IPv4):
34631 + switch (field.ipv4)
34632 + {
34633 + case (NET_HEADER_FIELD_IPv4_PROTO):
34634 + return KG_SCH_GEN_IP_PID_NO_V;
34635 + default:
34636 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34637 + return 0;
34638 + }
34639 + break;
34640 + case (HEADER_TYPE_IPv6):
34641 + switch (field.ipv6)
34642 + {
34643 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
34644 + return KG_SCH_GEN_IP_PID_NO_V;
34645 + default:
34646 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34647 + return 0;
34648 + }
34649 + break;
34650 + case (HEADER_TYPE_MPLS):
34651 + case (HEADER_TYPE_LLC_SNAP):
34652 + case (HEADER_TYPE_PPPoE):
34653 + case (HEADER_TYPE_GRE):
34654 + case (HEADER_TYPE_MINENCAP):
34655 + case (HEADER_TYPE_USER_DEFINED_L3):
34656 + case (HEADER_TYPE_TCP):
34657 + case (HEADER_TYPE_UDP):
34658 + case (HEADER_TYPE_IPSEC_AH):
34659 + case (HEADER_TYPE_IPSEC_ESP):
34660 + case (HEADER_TYPE_SCTP):
34661 + case (HEADER_TYPE_DCCP):
34662 + case (HEADER_TYPE_USER_DEFINED_L4):
34663 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34664 + return 0;
34665 + default:
34666 + break;
34667 + }
34668 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported"));
34669 + return 0;
34670 +}
34671 +
34672 +static t_KnownFieldsMasks GetKnownProtMask(t_FmPcd *p_FmPcd, e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
34673 +{
34674 + UNUSED(p_FmPcd);
34675 +
34676 + switch (hdr)
34677 + {
34678 + case (HEADER_TYPE_NONE):
34679 + ASSERT_COND(FALSE);
34680 + break;
34681 + case (HEADER_TYPE_ETH):
34682 + switch (field.eth)
34683 + {
34684 + case (NET_HEADER_FIELD_ETH_DA):
34685 + return KG_SCH_KN_MACDST;
34686 + case (NET_HEADER_FIELD_ETH_SA):
34687 + return KG_SCH_KN_MACSRC;
34688 + case (NET_HEADER_FIELD_ETH_TYPE):
34689 + return KG_SCH_KN_ETYPE;
34690 + default:
34691 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34692 + return 0;
34693 + }
34694 + case (HEADER_TYPE_LLC_SNAP):
34695 + switch (field.llcSnap)
34696 + {
34697 + case (NET_HEADER_FIELD_LLC_SNAP_TYPE):
34698 + return KG_SCH_KN_ETYPE;
34699 + default:
34700 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34701 + return 0;
34702 + }
34703 + case (HEADER_TYPE_VLAN):
34704 + switch (field.vlan)
34705 + {
34706 + case (NET_HEADER_FIELD_VLAN_TCI):
34707 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34708 + return KG_SCH_KN_TCI1;
34709 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34710 + return KG_SCH_KN_TCI2;
34711 + else
34712 + {
34713 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34714 + return 0;
34715 + }
34716 + default:
34717 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34718 + return 0;
34719 + }
34720 + case (HEADER_TYPE_MPLS):
34721 + switch (field.mpls)
34722 + {
34723 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
34724 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34725 + return KG_SCH_KN_MPLS1;
34726 + if (index == e_FM_PCD_HDR_INDEX_2)
34727 + return KG_SCH_KN_MPLS2;
34728 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34729 + return KG_SCH_KN_MPLS_LAST;
34730 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
34731 + return 0;
34732 + default:
34733 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34734 + return 0;
34735 + }
34736 + case (HEADER_TYPE_IPv4):
34737 + switch (field.ipv4)
34738 + {
34739 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
34740 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34741 + return KG_SCH_KN_IPSRC1;
34742 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34743 + return KG_SCH_KN_IPSRC2;
34744 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34745 + return 0;
34746 + case (NET_HEADER_FIELD_IPv4_DST_IP):
34747 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34748 + return KG_SCH_KN_IPDST1;
34749 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34750 + return KG_SCH_KN_IPDST2;
34751 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34752 + return 0;
34753 + case (NET_HEADER_FIELD_IPv4_PROTO):
34754 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34755 + return KG_SCH_KN_PTYPE1;
34756 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34757 + return KG_SCH_KN_PTYPE2;
34758 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34759 + return 0;
34760 + case (NET_HEADER_FIELD_IPv4_TOS):
34761 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34762 + return KG_SCH_KN_IPTOS_TC1;
34763 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34764 + return KG_SCH_KN_IPTOS_TC2;
34765 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34766 + return 0;
34767 + default:
34768 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34769 + return 0;
34770 + }
34771 + case (HEADER_TYPE_IPv6):
34772 + switch (field.ipv6)
34773 + {
34774 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
34775 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34776 + return KG_SCH_KN_IPSRC1;
34777 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34778 + return KG_SCH_KN_IPSRC2;
34779 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34780 + return 0;
34781 + case (NET_HEADER_FIELD_IPv6_DST_IP):
34782 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34783 + return KG_SCH_KN_IPDST1;
34784 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34785 + return KG_SCH_KN_IPDST2;
34786 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34787 + return 0;
34788 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
34789 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34790 + return KG_SCH_KN_PTYPE1;
34791 + if (index == e_FM_PCD_HDR_INDEX_2)
34792 + return KG_SCH_KN_PTYPE2;
34793 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34794 +#ifdef FM_KG_NO_IPPID_SUPPORT
34795 + if (p_FmPcd->fmRevInfo.majorRev < 6)
34796 + return KG_SCH_KN_PTYPE2;
34797 +#endif /* FM_KG_NO_IPPID_SUPPORT */
34798 + return KG_SCH_KN_IPPID;
34799 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34800 + return 0;
34801 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
34802 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34803 + return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1);
34804 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34805 + return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2);
34806 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34807 + return 0;
34808 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC):
34809 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34810 + return KG_SCH_KN_IPTOS_TC1;
34811 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34812 + return KG_SCH_KN_IPTOS_TC2;
34813 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34814 + return 0;
34815 + case (NET_HEADER_FIELD_IPv6_FL):
34816 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34817 + return KG_SCH_KN_IPV6FL1;
34818 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34819 + return KG_SCH_KN_IPV6FL2;
34820 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34821 + return 0;
34822 + default:
34823 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34824 + return 0;
34825 + }
34826 + case (HEADER_TYPE_GRE):
34827 + switch (field.gre)
34828 + {
34829 + case (NET_HEADER_FIELD_GRE_TYPE):
34830 + return KG_SCH_KN_GREPTYPE;
34831 + default:
34832 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34833 + return 0;
34834 + }
34835 + case (HEADER_TYPE_MINENCAP):
34836 + switch (field.minencap)
34837 + {
34838 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
34839 + return KG_SCH_KN_IPSRC2;
34840 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
34841 + return KG_SCH_KN_IPDST2;
34842 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
34843 + return KG_SCH_KN_PTYPE2;
34844 + default:
34845 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34846 + return 0;
34847 + }
34848 + case (HEADER_TYPE_TCP):
34849 + switch (field.tcp)
34850 + {
34851 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
34852 + return KG_SCH_KN_L4PSRC;
34853 + case (NET_HEADER_FIELD_TCP_PORT_DST):
34854 + return KG_SCH_KN_L4PDST;
34855 + case (NET_HEADER_FIELD_TCP_FLAGS):
34856 + return KG_SCH_KN_TFLG;
34857 + default:
34858 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34859 + return 0;
34860 + }
34861 + case (HEADER_TYPE_UDP):
34862 + switch (field.udp)
34863 + {
34864 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
34865 + return KG_SCH_KN_L4PSRC;
34866 + case (NET_HEADER_FIELD_UDP_PORT_DST):
34867 + return KG_SCH_KN_L4PDST;
34868 + default:
34869 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34870 + return 0;
34871 + }
34872 + case (HEADER_TYPE_IPSEC_AH):
34873 + switch (field.ipsecAh)
34874 + {
34875 + case (NET_HEADER_FIELD_IPSEC_AH_SPI):
34876 + return KG_SCH_KN_IPSEC_SPI;
34877 + case (NET_HEADER_FIELD_IPSEC_AH_NH):
34878 + return KG_SCH_KN_IPSEC_NH;
34879 + default:
34880 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34881 + return 0;
34882 + }
34883 + case (HEADER_TYPE_IPSEC_ESP):
34884 + switch (field.ipsecEsp)
34885 + {
34886 + case (NET_HEADER_FIELD_IPSEC_ESP_SPI):
34887 + return KG_SCH_KN_IPSEC_SPI;
34888 + default:
34889 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34890 + return 0;
34891 + }
34892 + case (HEADER_TYPE_SCTP):
34893 + switch (field.sctp)
34894 + {
34895 + case (NET_HEADER_FIELD_SCTP_PORT_SRC):
34896 + return KG_SCH_KN_L4PSRC;
34897 + case (NET_HEADER_FIELD_SCTP_PORT_DST):
34898 + return KG_SCH_KN_L4PDST;
34899 + default:
34900 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34901 + return 0;
34902 + }
34903 + case (HEADER_TYPE_DCCP):
34904 + switch (field.dccp)
34905 + {
34906 + case (NET_HEADER_FIELD_DCCP_PORT_SRC):
34907 + return KG_SCH_KN_L4PSRC;
34908 + case (NET_HEADER_FIELD_DCCP_PORT_DST):
34909 + return KG_SCH_KN_L4PDST;
34910 + default:
34911 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34912 + return 0;
34913 + }
34914 + case (HEADER_TYPE_PPPoE):
34915 + switch (field.pppoe)
34916 + {
34917 + case (NET_HEADER_FIELD_PPPoE_PID):
34918 + return KG_SCH_KN_PPPID;
34919 + case (NET_HEADER_FIELD_PPPoE_SID):
34920 + return KG_SCH_KN_PPPSID;
34921 + default:
34922 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34923 + return 0;
34924 + }
34925 + default:
34926 + break;
34927 +
34928 + }
34929 +
34930 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34931 + return 0;
34932 +}
34933 +
34934 +
34935 +static uint8_t GetKnownFieldId(uint32_t bitMask)
34936 +{
34937 + uint8_t cnt = 0;
34938 +
34939 + while (bitMask)
34940 + if (bitMask & 0x80000000)
34941 + break;
34942 + else
34943 + {
34944 + cnt++;
34945 + bitMask <<= 1;
34946 + }
34947 + return cnt;
34948 +
34949 +}
34950 +
34951 +static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid)
34952 +{
34953 + uint8_t i, mask, numOfOnesToClear, walking1Mask = 1;
34954 +
34955 + /* bitOffset 1-7 --> mask 0x1-0x7F */
34956 + if (bitOffset<8)
34957 + {
34958 + mask = 0;
34959 + for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1)
34960 + mask |= walking1Mask;
34961 + }
34962 + else
34963 + {
34964 + mask = 0xFF;
34965 + numOfOnesToClear = 0;
34966 + if (fqid && bitOffset>24)
34967 + /* bitOffset 25-31 --> mask 0xFE-0x80 */
34968 + numOfOnesToClear = (uint8_t)(bitOffset-24);
34969 + else
34970 + /* bitOffset 9-15 --> mask 0xFE-0x80 */
34971 + if (!fqid && bitOffset>8)
34972 + numOfOnesToClear = (uint8_t)(bitOffset-8);
34973 + for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1)
34974 + mask &= ~walking1Mask;
34975 + /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/
34976 + }
34977 + return mask;
34978 +}
34979 +
34980 +static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
34981 +{
34982 + t_FmPcdKg *p_FmPcdKg;
34983 + t_FmPcdKgScheme *p_Scheme;
34984 + uint32_t intFlags;
34985 + uint8_t relativeSchemeId;
34986 + int i;
34987 +
34988 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
34989 +
34990 + /* for each scheme - update owners counters */
34991 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
34992 + {
34993 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
34994 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
34995 +
34996 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
34997 +
34998 + /* increment owners number */
34999 + intFlags = KgSchemeLock(p_Scheme);
35000 + p_Scheme->owners++;
35001 + KgSchemeUnlock(p_Scheme, intFlags);
35002 + }
35003 +}
35004 +
35005 +static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
35006 +{
35007 + t_FmPcdKg *p_FmPcdKg;
35008 + t_FmPcdKgScheme *p_Scheme;
35009 + uint32_t intFlags;
35010 + uint8_t relativeSchemeId;
35011 + int i;
35012 +
35013 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
35014 +
35015 + /* for each scheme - update owners counters */
35016 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
35017 + {
35018 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
35019 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
35020 +
35021 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
35022 +
35023 + /* increment owners number */
35024 + ASSERT_COND(p_Scheme->owners);
35025 + intFlags = KgSchemeLock(p_Scheme);
35026 + p_Scheme->owners--;
35027 + KgSchemeUnlock(p_Scheme, intFlags);
35028 + }
35029 +}
35030 +
35031 +static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set)
35032 +{
35033 + /* this routine is locked by the calling routine */
35034 + ASSERT_COND(p_Scheme);
35035 + ASSERT_COND(p_Scheme->valid);
35036 +
35037 + if (set)
35038 + p_Scheme->requiredActionFlag = TRUE;
35039 + else
35040 + {
35041 + p_Scheme->requiredAction = 0;
35042 + p_Scheme->requiredActionFlag = FALSE;
35043 + }
35044 +}
35045 +
35046 +static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add)
35047 +{
35048 + struct fman_kg_regs *p_KgRegs;
35049 +
35050 + uint32_t tmpKgarReg = 0, intFlags;
35051 + t_Error err = E_OK;
35052 +
35053 + /* The calling routine had locked the port, so for each port only one core can access
35054 + * (so we don't need a lock here) */
35055 +
35056 + if (p_FmPcd->h_Hc)
35057 + return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add);
35058 +
35059 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35060 +
35061 + tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
35062 + /* lock a common KG reg */
35063 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
35064 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35065 + if (err)
35066 + {
35067 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35068 + RETURN_ERROR(MINOR, err, NO_MSG);
35069 + }
35070 +
35071 + fman_kg_write_sp(p_KgRegs, spReg, add);
35072 +
35073 + tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
35074 +
35075 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35076 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35077 + return err;
35078 +}
35079 +
35080 +static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg)
35081 +{
35082 + struct fman_kg_regs *p_KgRegs;
35083 + uint32_t tmpKgarReg, intFlags;
35084 + t_Error err;
35085 +
35086 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35087 +
35088 + if (p_FmPcd->h_Hc)
35089 + {
35090 + err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg);
35091 + return err;
35092 + }
35093 +
35094 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
35095 + fman_kg_write_cpp(p_KgRegs, cppReg);
35096 + tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
35097 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35098 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35099 +
35100 + return err;
35101 +}
35102 +
35103 +static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId)
35104 +{
35105 + uint32_t tmpKgpeCpp;
35106 +
35107 + tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8);
35108 + tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT);
35109 +
35110 + return tmpKgpeCpp;
35111 +}
35112 +
35113 +static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
35114 +{
35115 + uint32_t tmpKgpeCpp = 0;
35116 +
35117 + tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId);
35118 + return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp);
35119 +}
35120 +
35121 +static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
35122 +{
35123 + KgWriteCpp(p_FmPcd, hardwarePortId, 0);
35124 +}
35125 +
35126 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
35127 +static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId)
35128 +{
35129 + return (uint32_t)(FM_KG_KGAR_GO |
35130 + FM_KG_KGAR_READ |
35131 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
35132 + DUMMY_PORT_ID |
35133 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
35134 + FM_PCD_KG_KGAR_WSEL_MASK);
35135 +
35136 + /* if we ever want to write 1 by 1, use:
35137 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
35138 + */
35139 +}
35140 +#endif /* (defined(DEBUG_ERRORS) && ... */
35141 +
35142 +static void PcdKgErrorException(t_Handle h_FmPcd)
35143 +{
35144 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
35145 + uint32_t event,schemeIndexes = 0, index = 0;
35146 + struct fman_kg_regs *p_KgRegs;
35147 +
35148 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
35149 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35150 + fman_kg_get_event(p_KgRegs, &event, &schemeIndexes);
35151 +
35152 + if (event & FM_EX_KG_DOUBLE_ECC)
35153 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC);
35154 + if (event & FM_EX_KG_KEYSIZE_OVERFLOW)
35155 + {
35156 + if (schemeIndexes)
35157 + {
35158 + while (schemeIndexes)
35159 + {
35160 + if (schemeIndexes & 0x1)
35161 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index));
35162 + schemeIndexes >>= 1;
35163 + index+=1;
35164 + }
35165 + }
35166 + else /* this should happen only when interrupt is forced. */
35167 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW);
35168 + }
35169 +}
35170 +
35171 +static t_Error KgInitGuest(t_FmPcd *p_FmPcd)
35172 +{
35173 + t_Error err = E_OK;
35174 + t_FmPcdIpcKgSchemesParams kgAlloc;
35175 + uint32_t replyLength;
35176 + t_FmPcdIpcReply reply;
35177 + t_FmPcdIpcMsg msg;
35178 +
35179 + ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID);
35180 +
35181 + /* in GUEST_PARTITION, we use the IPC */
35182 + memset(&reply, 0, sizeof(reply));
35183 + memset(&msg, 0, sizeof(msg));
35184 + memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams));
35185 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
35186 + kgAlloc.guestId = p_FmPcd->guestId;
35187 + msg.msgId = FM_PCD_ALLOC_KG_SCHEMES;
35188 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
35189 + replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t);
35190 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
35191 + (uint8_t*)&msg,
35192 + sizeof(msg.msgId) + sizeof(kgAlloc),
35193 + (uint8_t*)&reply,
35194 + &replyLength,
35195 + NULL,
35196 + NULL)) != E_OK)
35197 + RETURN_ERROR(MAJOR, err, NO_MSG);
35198 + if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)))
35199 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
35200 + memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t));
35201 +
35202 + return (t_Error)reply.error;
35203 +}
35204 +
35205 +static t_Error KgInitMaster(t_FmPcd *p_FmPcd)
35206 +{
35207 + t_Error err = E_OK;
35208 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35209 +
35210 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
35211 +
35212 + if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)
35213 + FmEnableRamsEcc(p_FmPcd->h_Fm);
35214 +
35215 + fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd));
35216 +
35217 + /* register even if no interrupts enabled, to allow future enablement */
35218 + FmRegisterIntr(p_FmPcd->h_Fm,
35219 + e_FM_MOD_KG,
35220 + 0,
35221 + e_FM_INTR_TYPE_ERR,
35222 + PcdKgErrorException,
35223 + p_FmPcd);
35224 +
35225 + fman_kg_enable_scheme_interrupts(p_Regs);
35226 +
35227 + if (p_FmPcd->p_FmPcdKg->numOfSchemes)
35228 + {
35229 + err = FmPcdKgAllocSchemes(p_FmPcd,
35230 + p_FmPcd->p_FmPcdKg->numOfSchemes,
35231 + p_FmPcd->guestId,
35232 + p_FmPcd->p_FmPcdKg->schemesIds);
35233 + if (err)
35234 + RETURN_ERROR(MINOR, err, NO_MSG);
35235 + }
35236 +
35237 + return E_OK;
35238 +}
35239 +
35240 +static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35241 +{
35242 + ASSERT_COND(!p_Scheme->valid);
35243 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35244 + FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35245 + p_Scheme->valid = TRUE;
35246 +}
35247 +
35248 +static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35249 +{
35250 + if (p_Scheme->owners)
35251 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to"));
35252 +
35253 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35254 + FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35255 + p_Scheme->valid = FALSE;
35256 +
35257 + return E_OK;
35258 +}
35259 +
35260 +static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme,
35261 + t_FmPcdKgSchemeParams *p_SchemeParams,
35262 + struct fman_kg_scheme_regs *p_SchemeRegs)
35263 +{
35264 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd);
35265 + uint32_t grpBits = 0;
35266 + uint8_t grpBase;
35267 + bool direct=TRUE, absolute=FALSE;
35268 + uint16_t profileId=0, numOfProfiles=0, relativeProfileId;
35269 + t_Error err = E_OK;
35270 + int i = 0;
35271 + t_NetEnvParams netEnvParams;
35272 + uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp;
35273 + t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL;
35274 + uint8_t j, curr, idx;
35275 + uint8_t id, shift=0, code=0, offset=0, size=0;
35276 + t_FmPcdExtractEntry *p_Extract = NULL;
35277 + t_FmPcdKgExtractedOrParams *p_ExtractOr;
35278 + bool generic = FALSE;
35279 + t_KnownFieldsMasks bitMask;
35280 + e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0;
35281 + t_FmPcdKgSchemesExtracts *p_LocalExtractsArray;
35282 + uint8_t numOfSwDefaults = 0;
35283 + t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS];
35284 + uint8_t currGenId = 0;
35285 +
35286 + memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt));
35287 + memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
35288 +
35289 + if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
35290 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
35291 + ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS));
35292 +
35293 + /* by netEnv parameters, get match vector */
35294 + if (!p_SchemeParams->alwaysDirect)
35295 + {
35296 + p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv);
35297 + netEnvParams.netEnvId = p_Scheme->netEnvId;
35298 + netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits;
35299 + memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits);
35300 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
35301 + if (err)
35302 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
35303 + p_Scheme->matchVector = netEnvParams.vector;
35304 + }
35305 + else
35306 + {
35307 + p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT;
35308 + p_Scheme->netEnvId = ILLEGAL_NETENV;
35309 + }
35310 +
35311 + if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID)
35312 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid"));
35313 +
35314 + if (p_SchemeParams->bypassFqidGeneration)
35315 + {
35316 +#ifdef FM_KG_NO_BYPASS_FQID_GEN
35317 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35318 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration."));
35319 +#endif /* FM_KG_NO_BYPASS_FQID_GEN */
35320 + if (p_SchemeParams->baseFqid)
35321 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID"));
35322 + }
35323 + else
35324 + if (!p_SchemeParams->baseFqid)
35325 + DBG(WARNING, ("baseFqid is 0."));
35326 +
35327 + if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR)
35328 + {
35329 + direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct;
35330 + p_Scheme->directPlcr = direct;
35331 + absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE);
35332 + if (!direct && absolute)
35333 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared."));
35334 +
35335 + if (direct)
35336 + {
35337 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId;
35338 + numOfProfiles = 1;
35339 + }
35340 + else
35341 + {
35342 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35343 + shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35344 + numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35345 + }
35346 + }
35347 +
35348 + if (p_SchemeParams->nextEngine == e_FM_PCD_CC)
35349 + {
35350 +#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
35351 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35352 + {
35353 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35354 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration."));
35355 + }
35356 +#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */
35357 +
35358 + err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree,
35359 + p_SchemeParams->kgNextEngineParams.cc.grpId,
35360 + &grpBits,
35361 + &grpBase);
35362 + if (err)
35363 + RETURN_ERROR(MAJOR, err, NO_MSG);
35364 + p_Scheme->ccUnits = grpBits;
35365 +
35366 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35367 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35368 + {
35369 + if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile)
35370 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification."));
35371 + absolute = FALSE;
35372 + direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct;
35373 + if (direct)
35374 + {
35375 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId;
35376 + numOfProfiles = 1;
35377 + }
35378 + else
35379 + {
35380 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35381 + shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35382 + numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35383 + }
35384 + }
35385 + }
35386 +
35387 + /* if policer is used directly after KG, or after CC */
35388 + if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) ||
35389 + ((p_SchemeParams->nextEngine == e_FM_PCD_CC) &&
35390 + (p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35391 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)))
35392 + {
35393 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
35394 + if (absolute)
35395 + {
35396 + /* for absolute direct policy only, */
35397 + relativeProfileId = profileId;
35398 + err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId);
35399 + if (err)
35400 + RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset"));
35401 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId))
35402 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid."));
35403 + p_Scheme->relativeProfileId = profileId;
35404 + }
35405 + else
35406 + {
35407 + /* save relative profile id's for later check */
35408 + p_Scheme->nextRelativePlcrProfile = TRUE;
35409 + p_Scheme->relativeProfileId = profileId;
35410 + p_Scheme->numOfProfiles = numOfProfiles;
35411 + }
35412 + }
35413 + else
35414 + {
35415 + /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration
35416 + is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */
35417 + if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs)
35418 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35419 + ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID"));
35420 + if (p_SchemeParams->bypassFqidGeneration &&
35421 + p_SchemeParams->useHash &&
35422 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids)
35423 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35424 + ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID"));
35425 + }
35426 +
35427 + /* configure all 21 scheme registers */
35428 + tmpReg = KG_SCH_MODE_EN;
35429 + switch (p_SchemeParams->nextEngine)
35430 + {
35431 + case (e_FM_PCD_PLCR):
35432 + /* add to mode register - NIA */
35433 + tmpReg |= KG_SCH_MODE_NIA_PLCR;
35434 + tmpReg |= NIA_ENG_PLCR;
35435 + tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0);
35436 + /* initialize policer profile command - */
35437 + /* configure kgse_ppc */
35438 + if (direct)
35439 + /* use profileId as base, other fields are 0 */
35440 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35441 + else
35442 + {
35443 + if (shift > MAX_PP_SHIFT)
35444 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35445 +
35446 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35447 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35448 +
35449 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35450 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35451 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35452 + ppcTmp |= (uint32_t)profileId;
35453 +
35454 + p_SchemeRegs->kgse_ppc = ppcTmp;
35455 + }
35456 + break;
35457 + case (e_FM_PCD_CC):
35458 + /* mode reg - define NIA */
35459 + tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
35460 +
35461 + p_SchemeRegs->kgse_ccbs = grpBits;
35462 + tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT);
35463 +
35464 + if (p_SchemeParams->kgNextEngineParams.cc.plcrNext)
35465 + {
35466 + if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)
35467 + {
35468 + /* find out if absolute or relative */
35469 + if (absolute)
35470 + 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"));
35471 + if (direct)
35472 + {
35473 + /* mask = 0, base = directProfileId */
35474 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35475 + }
35476 + else
35477 + {
35478 + if (shift > MAX_PP_SHIFT)
35479 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35480 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35481 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35482 +
35483 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35484 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35485 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35486 + ppcTmp |= (uint32_t)profileId;
35487 +
35488 + p_SchemeRegs->kgse_ppc = ppcTmp;
35489 + }
35490 + }
35491 + }
35492 + break;
35493 + case (e_FM_PCD_DONE):
35494 + if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME)
35495 + tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
35496 + else
35497 + tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
35498 + break;
35499 + default:
35500 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported"));
35501 + }
35502 + p_SchemeRegs->kgse_mode = tmpReg;
35503 +
35504 + p_SchemeRegs->kgse_mv = p_Scheme->matchVector;
35505 +
35506 +#if (DPAA_VERSION >= 11)
35507 + if (p_SchemeParams->overrideStorageProfile)
35508 + {
35509 + p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE;
35510 +
35511 + if (p_SchemeParams->storageProfile.direct)
35512 + {
35513 + profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId;
35514 + shift = 0;
35515 + numOfProfiles = 1;
35516 + }
35517 + else
35518 + {
35519 + profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35520 + shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift;
35521 + numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles;
35522 + }
35523 + if (shift > MAX_SP_SHIFT)
35524 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT));
35525 +
35526 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35527 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35528 +
35529 + tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT;
35530 + tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT);
35531 + tmpReg |= (uint32_t)profileId;
35532 +
35533 +
35534 + p_SchemeRegs->kgse_vsp = tmpReg;
35535 +
35536 + p_Scheme->vspe = TRUE;
35537 +
35538 + }
35539 + else
35540 + p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN;
35541 +#endif /* (DPAA_VERSION >= 11) */
35542 +
35543 + if (p_SchemeParams->useHash)
35544 + {
35545 + p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams;
35546 +
35547 + if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
35548 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range"));
35549 +
35550 + /* configure kgse_dv0 */
35551 + p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0;
35552 +
35553 + /* configure kgse_dv1 */
35554 + p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1;
35555 +
35556 + if (!p_SchemeParams->bypassFqidGeneration)
35557 + {
35558 + if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids))
35559 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2"));
35560 + if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid)
35561 + DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues."));
35562 + }
35563 +
35564 + /* configure kgse_ekdv */
35565 + tmpReg = 0;
35566 + for ( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++)
35567 + {
35568 + switch (p_KeyAndHash->dflts[i].type)
35569 + {
35570 + case (e_FM_PCD_KG_MAC_ADDR):
35571 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT);
35572 + break;
35573 + case (e_FM_PCD_KG_TCI):
35574 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT);
35575 + break;
35576 + case (e_FM_PCD_KG_ENET_TYPE):
35577 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT);
35578 + break;
35579 + case (e_FM_PCD_KG_PPP_SESSION_ID):
35580 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT);
35581 + break;
35582 + case (e_FM_PCD_KG_PPP_PROTOCOL_ID):
35583 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT);
35584 + break;
35585 + case (e_FM_PCD_KG_MPLS_LABEL):
35586 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT);
35587 + break;
35588 + case (e_FM_PCD_KG_IP_ADDR):
35589 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT);
35590 + break;
35591 + case (e_FM_PCD_KG_PROTOCOL_TYPE):
35592 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT);
35593 + break;
35594 + case (e_FM_PCD_KG_IP_TOS_TC):
35595 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT);
35596 + break;
35597 + case (e_FM_PCD_KG_IPV6_FLOW_LABEL):
35598 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35599 + break;
35600 + case (e_FM_PCD_KG_IPSEC_SPI):
35601 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT);
35602 + break;
35603 + case (e_FM_PCD_KG_L4_PORT):
35604 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35605 + break;
35606 + case (e_FM_PCD_KG_TCP_FLAG):
35607 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT);
35608 + break;
35609 + case (e_FM_PCD_KG_GENERIC_FROM_DATA):
35610 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA;
35611 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35612 + numOfSwDefaults ++;
35613 + break;
35614 + case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V):
35615 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V;
35616 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35617 + numOfSwDefaults ++;
35618 + break;
35619 + case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA):
35620 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
35621 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35622 + numOfSwDefaults ++;
35623 + break;
35624 + default:
35625 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35626 + }
35627 + }
35628 + p_SchemeRegs->kgse_ekdv = tmpReg;
35629 +
35630 + p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts));
35631 + if (!p_LocalExtractsArray)
35632 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
35633 +
35634 + /* configure kgse_ekfc and kgse_gec */
35635 + knownTmp = 0;
35636 + for ( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++)
35637 + {
35638 + p_Extract = &p_KeyAndHash->extractArray[i];
35639 + switch (p_Extract->type)
35640 + {
35641 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
35642 + knownTmp |= KG_SCH_KN_PORT_ID;
35643 + /* save in driver structure */
35644 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID);
35645 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35646 + break;
35647 + case (e_FM_PCD_EXTRACT_BY_HDR):
35648 + switch (p_Extract->extractByHdr.hdr)
35649 + {
35650 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
35651 + case (HEADER_TYPE_UDP_LITE):
35652 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35653 + break;
35654 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
35655 + case (HEADER_TYPE_UDP_ENCAP_ESP):
35656 + switch (p_Extract->extractByHdr.type)
35657 + {
35658 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35659 + /* case where extraction from ESP only */
35660 + if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE)
35661 + {
35662 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35663 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE;
35664 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35665 + }
35666 + else
35667 + {
35668 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35669 + p_Extract->extractByHdr.ignoreProtocolValidation = FALSE;
35670 + }
35671 + break;
35672 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35673 + switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp)
35674 + {
35675 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35676 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35677 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35678 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35679 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35680 + break;
35681 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35682 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35683 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35684 + /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/
35685 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35686 + break;
35687 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35688 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35689 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35690 + p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET;
35691 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35692 + break;
35693 + }
35694 + break;
35695 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35696 + switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp)
35697 + {
35698 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35699 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35700 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35701 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35702 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35703 + break;
35704 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35705 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35706 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35707 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE;
35708 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET;
35709 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35710 + break;
35711 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35712 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35713 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35714 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE;
35715 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET;
35716 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35717 + break;
35718 + }
35719 + break;
35720 + }
35721 + break;
35722 + default:
35723 + break;
35724 + }
35725 + switch (p_Extract->extractByHdr.type)
35726 + {
35727 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35728 + generic = TRUE;
35729 + /* get the header code for the generic extract */
35730 + code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation);
35731 + /* set generic register fields */
35732 + offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset;
35733 + size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size;
35734 + break;
35735 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35736 + generic = TRUE;
35737 + /* get the field code for the generic extract */
35738 + code = GetGenFieldCode(p_Extract->extractByHdr.hdr,
35739 + p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex);
35740 + offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset;
35741 + size = p_Extract->extractByHdr.extractByHdrType.fromField.size;
35742 + break;
35743 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35744 + if (!p_Extract->extractByHdr.ignoreProtocolValidation)
35745 + {
35746 + /* if we have a known field for it - use it, otherwise use generic */
35747 + bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex,
35748 + p_Extract->extractByHdr.extractByHdrType.fullField);
35749 + if (bitMask)
35750 + {
35751 + knownTmp |= bitMask;
35752 + /* save in driver structure */
35753 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask);
35754 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35755 + }
35756 + else
35757 + generic = TRUE;
35758 + }
35759 + else
35760 + generic = TRUE;
35761 + if (generic)
35762 + {
35763 + /* tmp - till we cover more headers under generic */
35764 + XX_Free(p_LocalExtractsArray);
35765 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported"));
35766 + }
35767 + break;
35768 + default:
35769 + XX_Free(p_LocalExtractsArray);
35770 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35771 + }
35772 + break;
35773 + case (e_FM_PCD_EXTRACT_NON_HDR):
35774 + /* use generic */
35775 + generic = TRUE;
35776 + offset = 0;
35777 + /* get the field code for the generic extract */
35778 + code = GetGenCode(p_Extract->extractNonHdr.src, &offset);
35779 + offset += p_Extract->extractNonHdr.offset;
35780 + size = p_Extract->extractNonHdr.size;
35781 + break;
35782 + default:
35783 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35784 + }
35785 +
35786 + if (generic)
35787 + {
35788 + /* set generic register fields */
35789 + if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS)
35790 + {
35791 + XX_Free(p_LocalExtractsArray);
35792 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
35793 + }
35794 + if (!code)
35795 + {
35796 + XX_Free(p_LocalExtractsArray);
35797 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
35798 + }
35799 +
35800 + genTmp = KG_SCH_GEN_VALID;
35801 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
35802 + genTmp |= offset;
35803 + if ((size > MAX_KG_SCH_SIZE) || (size < 1))
35804 + {
35805 + XX_Free(p_LocalExtractsArray);
35806 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)"));
35807 + }
35808 + genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT);
35809 + swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code);
35810 + if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL)
35811 + DBG(WARNING, ("No sw default configured"));
35812 + else
35813 + genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT;
35814 +
35815 + genTmp |= KG_SCH_GEN_MASK;
35816 + p_SchemeRegs->kgse_gec[currGenId] = genTmp;
35817 + /* save in driver structure */
35818 + p_LocalExtractsArray->extractsArray[i].id = currGenId++;
35819 + p_LocalExtractsArray->extractsArray[i].known = FALSE;
35820 + generic = FALSE;
35821 + }
35822 + }
35823 + p_SchemeRegs->kgse_ekfc = knownTmp;
35824 +
35825 + selectTmp = 0;
35826 + maskTmp = 0xFFFFFFFF;
35827 + /* configure kgse_bmch, kgse_bmcl and kgse_fqb */
35828 +
35829 + if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
35830 + {
35831 + XX_Free(p_LocalExtractsArray);
35832 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS));
35833 + }
35834 + for ( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++)
35835 + {
35836 + /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */
35837 + id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id;
35838 + /* Get the shift of the select field (depending on i) */
35839 + GET_MASK_SEL_SHIFT(shift,i);
35840 + if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known)
35841 + selectTmp |= id << shift;
35842 + else
35843 + selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift;
35844 +
35845 + /* Get the shift of the offset field (depending on i) - may
35846 + be in kgse_bmch or in kgse_fqb (depending on i) */
35847 + GET_MASK_OFFSET_SHIFT(shift,i);
35848 + if (i<=1)
35849 + selectTmp |= p_KeyAndHash->masks[i].offset << shift;
35850 + else
35851 + fqbTmp |= p_KeyAndHash->masks[i].offset << shift;
35852 +
35853 + /* Get the shift of the mask field (depending on i) */
35854 + GET_MASK_SHIFT(shift,i);
35855 + /* pass all bits */
35856 + maskTmp |= KG_SCH_BITMASK_MASK << shift;
35857 + /* clear bits that need masking */
35858 + maskTmp &= ~(0xFF << shift) ;
35859 + /* set mask bits */
35860 + maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ;
35861 + }
35862 + p_SchemeRegs->kgse_bmch = selectTmp;
35863 + p_SchemeRegs->kgse_bmcl = maskTmp;
35864 + /* kgse_fqb will be written t the end of the routine */
35865 +
35866 + /* configure kgse_hc */
35867 + if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT)
35868 + {
35869 + XX_Free(p_LocalExtractsArray);
35870 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT));
35871 + }
35872 + if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT)
35873 + {
35874 + XX_Free(p_LocalExtractsArray);
35875 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT));
35876 + }
35877 +
35878 + tmpReg = 0;
35879 +
35880 + tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift);
35881 + tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
35882 +
35883 + if (p_KeyAndHash->symmetricHash)
35884 + {
35885 + if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) ||
35886 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) ||
35887 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) ||
35888 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST)))
35889 + {
35890 + XX_Free(p_LocalExtractsArray);
35891 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing"));
35892 + }
35893 + tmpReg |= KG_SCH_HASH_CONFIG_SYM;
35894 + }
35895 + p_SchemeRegs->kgse_hc = tmpReg;
35896 +
35897 + /* build the return array describing the order of the extractions */
35898 +
35899 + /* the last currGenId places of the array
35900 + are for generic extracts that are always last.
35901 + We now sort for the calculation of the order of the known
35902 + extractions we sort the known extracts between orderedArray[0] and
35903 + orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1].
35904 + for the calculation of the order of the generic extractions we use:
35905 + num_of_generic - currGenId
35906 + num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId
35907 + first_generic_index = num_of_known */
35908 + curr = 0;
35909 + for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++)
35910 + {
35911 + if (p_LocalExtractsArray->extractsArray[i].known)
35912 + {
35913 + ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId));
35914 + j = curr;
35915 + /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original
35916 + index in the user's extractions array */
35917 + /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1]
35918 + location */
35919 + while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id <
35920 + p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id))
35921 + {
35922 + p_Scheme->orderedArray[j] =
35923 + p_Scheme->orderedArray[j-1];
35924 + j--;
35925 + }
35926 + p_Scheme->orderedArray[j] = (uint8_t)i;
35927 + curr++;
35928 + }
35929 + else
35930 + {
35931 + /* index is first_generic_index + generic index (id) */
35932 + idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id);
35933 + ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY);
35934 + p_Scheme->orderedArray[idx]= (uint8_t)i;
35935 + }
35936 + }
35937 + XX_Free(p_LocalExtractsArray);
35938 + }
35939 + else
35940 + {
35941 + /* clear all unused registers: */
35942 + p_SchemeRegs->kgse_ekfc = 0;
35943 + p_SchemeRegs->kgse_ekdv = 0;
35944 + p_SchemeRegs->kgse_bmch = 0;
35945 + p_SchemeRegs->kgse_bmcl = 0;
35946 + p_SchemeRegs->kgse_hc = 0;
35947 + p_SchemeRegs->kgse_dv0 = 0;
35948 + p_SchemeRegs->kgse_dv1 = 0;
35949 + }
35950 +
35951 + if (p_SchemeParams->bypassFqidGeneration)
35952 + p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID;
35953 +
35954 + /* configure kgse_spc */
35955 + if ( p_SchemeParams->schemeCounter.update)
35956 + p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value;
35957 +
35958 +
35959 + /* check that are enough generic registers */
35960 + if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS)
35961 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
35962 +
35963 + /* extracted OR mask on Qid */
35964 + for ( i=0 ;i<p_SchemeParams->numOfUsedExtractedOrs ; i++)
35965 + {
35966 +
35967 + p_Scheme->extractedOrs = TRUE;
35968 + /* configure kgse_gec[i] */
35969 + p_ExtractOr = &p_SchemeParams->extractedOrs[i];
35970 + switch (p_ExtractOr->type)
35971 + {
35972 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
35973 + code = KG_SCH_GEN_PARSE_RESULT_N_FQID;
35974 + offset = 0;
35975 + break;
35976 + case (e_FM_PCD_EXTRACT_BY_HDR):
35977 + /* get the header code for the generic extract */
35978 + code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation);
35979 + /* set generic register fields */
35980 + offset = p_ExtractOr->extractionOffset;
35981 + break;
35982 + case (e_FM_PCD_EXTRACT_NON_HDR):
35983 + /* get the field code for the generic extract */
35984 + offset = 0;
35985 + code = GetGenCode(p_ExtractOr->src, &offset);
35986 + offset += p_ExtractOr->extractionOffset;
35987 + break;
35988 + default:
35989 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35990 + }
35991 +
35992 + /* set generic register fields */
35993 + if (!code)
35994 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
35995 + genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID;
35996 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
35997 + genTmp |= offset;
35998 + if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile)
35999 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile"));
36000 +
36001 + /************************************************************************************
36002 + bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter
36003 + in the following way:
36004 +
36005 + Driver API and implementation:
36006 + ==============================
36007 + FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID.
36008 + if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that
36009 + are not overlapping FQID.
36010 + ------------------------
36011 + | FQID (24) |
36012 + ------------------------
36013 + --------
36014 + | | extracted OR byte
36015 + --------
36016 +
36017 + Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the
36018 + PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that
36019 + are not overlapping PP id.
36020 +
36021 + --------
36022 + | PP (8) |
36023 + --------
36024 + --------
36025 + | | extracted OR byte
36026 + --------
36027 +
36028 + HW implementation
36029 + =================
36030 + FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located
36031 + as the highest byte of that word and may be rotated to effect any part os the FQID or
36032 + the PP.
36033 + ------------------------ --------
36034 + | FQID (24) || PP (8) |
36035 + ------------------------ --------
36036 + --------
36037 + | | extracted OR byte
36038 + --------
36039 +
36040 + ************************************************************************************/
36041 +
36042 + if (p_ExtractOr->bitOffsetInFqid)
36043 + {
36044 + if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET )
36045 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)"));
36046 + if (p_ExtractOr->bitOffsetInFqid<8)
36047 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT);
36048 + else
36049 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT);
36050 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE);
36051 + }
36052 + else /* effect policer profile */
36053 + {
36054 + if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET )
36055 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)"));
36056 + p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile;
36057 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT);
36058 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE);
36059 + }
36060 +
36061 + genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT);
36062 + /* clear bits that need masking */
36063 + genTmp &= ~KG_SCH_GEN_MASK ;
36064 + /* set mask bits */
36065 + genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT);
36066 + p_SchemeRegs->kgse_gec[currGenId++] = genTmp;
36067 +
36068 + }
36069 + /* clear all unused GEC registers */
36070 + for ( i=currGenId ;i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
36071 + p_SchemeRegs->kgse_gec[i] = 0;
36072 +
36073 + /* add base Qid for this scheme */
36074 + /* add configuration for kgse_fqb */
36075 + if (p_SchemeParams->baseFqid & ~0x00FFFFFF)
36076 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1"));
36077 +
36078 + fqbTmp |= p_SchemeParams->baseFqid;
36079 + p_SchemeRegs->kgse_fqb = fqbTmp;
36080 +
36081 + p_Scheme->nextEngine = p_SchemeParams->nextEngine;
36082 + p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction;
36083 +
36084 + return E_OK;
36085 +}
36086 +
36087 +
36088 +/*****************************************************************************/
36089 +/* Inter-module API routines */
36090 +/*****************************************************************************/
36091 +
36092 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet)
36093 +{
36094 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36095 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
36096 + t_FmPcdIpcKgClsPlanParams kgAlloc;
36097 + t_Error err = E_OK;
36098 + uint32_t oredVectors = 0;
36099 + int i, j;
36100 +
36101 + /* this routine is protected by the calling routine ! */
36102 + if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS))
36103 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected."));
36104 +
36105 + /* find a new clsPlan group */
36106 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
36107 + if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used)
36108 + break;
36109 + if (i == FM_MAX_NUM_OF_PORTS)
36110 + RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available."));
36111 +
36112 + p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE;
36113 +
36114 + p_Grp->clsPlanGrpId = (uint8_t)i;
36115 +
36116 + if (p_Grp->numOfOptions == 0)
36117 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i;
36118 +
36119 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i];
36120 + p_ClsPlanGrp->netEnvId = p_Grp->netEnvId;
36121 + p_ClsPlanGrp->owners = 0;
36122 + FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId);
36123 + if (p_Grp->numOfOptions != 0)
36124 + FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId);
36125 +
36126 + p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions);
36127 + /* a minimal group of 8 is required */
36128 + if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP)
36129 + p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP;
36130 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36131 + {
36132 + err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry);
36133 +
36134 + if (err)
36135 + RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
36136 + }
36137 + else
36138 + {
36139 + t_FmPcdIpcMsg msg;
36140 + uint32_t replyLength;
36141 + t_FmPcdIpcReply reply;
36142 +
36143 + /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36144 + memset(&reply, 0, sizeof(reply));
36145 + memset(&msg, 0, sizeof(msg));
36146 + memset(&kgAlloc, 0, sizeof(kgAlloc));
36147 + kgAlloc.guestId = p_FmPcd->guestId;
36148 + kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36149 + msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN;
36150 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36151 + replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry));
36152 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36153 + (uint8_t*)&msg,
36154 + sizeof(msg.msgId) + sizeof(kgAlloc),
36155 + (uint8_t*)&reply,
36156 + &replyLength,
36157 + NULL,
36158 + NULL)) != E_OK)
36159 + RETURN_ERROR(MAJOR, err, NO_MSG);
36160 +
36161 + if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)))
36162 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36163 + if ((t_Error)reply.error != E_OK)
36164 + RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG);
36165 +
36166 + p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody);
36167 + }
36168 +
36169 + /* build classification plan entries parameters */
36170 + p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry;
36171 + p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36172 +
36173 + oredVectors = 0;
36174 + for (i = 0; i<p_Grp->numOfOptions; i++)
36175 + {
36176 + oredVectors |= p_Grp->optVectors[i];
36177 + /* save an array of used options - the indexes represent the power of 2 index */
36178 + p_ClsPlanGrp->optArray[i] = p_Grp->options[i];
36179 + }
36180 + /* set the classification plan relevant entries so that all bits
36181 + * relevant to the list of options is cleared
36182 + */
36183 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36184 + p_ClsPlanSet->vectors[j] = ~oredVectors;
36185 +
36186 + for (i = 0; i<p_Grp->numOfOptions; i++)
36187 + {
36188 + /* option i got the place 2^i in the clsPlan array. all entries that
36189 + * have bit i set, should have the vector bit cleared. So each option
36190 + * has one location that it is exclusive (1,2,4,8...) and represent the
36191 + * presence of that option only, and other locations that represent a
36192 + * combination of options.
36193 + * e.g:
36194 + * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2
36195 + * now represents a frame with ethernet-BC header - so the bit
36196 + * representing ethernet-BC should be set and all other option bits
36197 + * should be cleared.
36198 + * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit
36199 + * vector[1] set, but they also have other bits set:
36200 + * 3=1+2, options 0 and 1
36201 + * 6=2+4, options 1 and 2
36202 + * 7=1+2+4, options 0,1,and 2
36203 + * 10=2+8, options 1 and 3
36204 + * etc.
36205 + * */
36206 +
36207 + /* now for each option (i), we set their bits in all entries (j)
36208 + * that contain bit 2^i.
36209 + */
36210 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36211 + {
36212 + if (j & (1<<i))
36213 + p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i];
36214 + }
36215 + }
36216 +
36217 + return E_OK;
36218 +}
36219 +
36220 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId)
36221 +{
36222 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36223 + t_FmPcdIpcKgClsPlanParams kgAlloc;
36224 + t_Error err;
36225 + t_FmPcdIpcMsg msg;
36226 + uint32_t replyLength;
36227 + t_FmPcdIpcReply reply;
36228 +
36229 + /* check that no port is bound to this clsPlan */
36230 + if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners)
36231 + {
36232 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to"));
36233 + return;
36234 + }
36235 +
36236 + FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN);
36237 +
36238 + if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
36239 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36240 + else
36241 + FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId);
36242 +
36243 + /* free blocks */
36244 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36245 + KgFreeClsPlanEntries(h_FmPcd,
36246 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp,
36247 + p_FmPcd->guestId,
36248 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry);
36249 + else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36250 + {
36251 + memset(&reply, 0, sizeof(reply));
36252 + memset(&msg, 0, sizeof(msg));
36253 + kgAlloc.guestId = p_FmPcd->guestId;
36254 + kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp;
36255 + kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry;
36256 + msg.msgId = FM_PCD_FREE_KG_CLSPLAN;
36257 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36258 + replyLength = sizeof(uint32_t);
36259 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36260 + (uint8_t*)&msg,
36261 + sizeof(msg.msgId) + sizeof(kgAlloc),
36262 + (uint8_t*)&reply,
36263 + &replyLength,
36264 + NULL,
36265 + NULL);
36266 + if (err != E_OK)
36267 + {
36268 + REPORT_ERROR(MINOR, err, NO_MSG);
36269 + return;
36270 + }
36271 + if (replyLength != sizeof(uint32_t))
36272 + {
36273 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36274 + return;
36275 + }
36276 + if ((t_Error)reply.error != E_OK)
36277 + {
36278 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed"));
36279 + return;
36280 + }
36281 + }
36282 +
36283 + /* clear clsPlan driver structure */
36284 + memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp));
36285 +}
36286 +
36287 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add)
36288 +{
36289 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36290 + uint32_t j, schemesPerPortVector = 0;
36291 + t_FmPcdKgScheme *p_Scheme;
36292 + uint8_t i, relativeSchemeId;
36293 + uint32_t tmp, walking1Mask;
36294 + uint8_t swPortIndex = 0;
36295 +
36296 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36297 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36298 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
36299 +
36300 + /* for each scheme */
36301 + for (i = 0; i<p_BindPort->numOfSchemes; i++)
36302 + {
36303 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
36304 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
36305 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
36306 +
36307 + if (add)
36308 + {
36309 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
36310 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
36311 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
36312 + /* check netEnvId of the port against the scheme netEnvId */
36313 + if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV))
36314 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId"));
36315 +
36316 + /* if next engine is private port policer profile, we need to check that it is valid */
36317 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId);
36318 + if (p_Scheme->nextRelativePlcrProfile)
36319 + {
36320 + for (j = 0;j<p_Scheme->numOfProfiles;j++)
36321 + {
36322 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort);
36323 + if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles)
36324 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range"));
36325 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j)))
36326 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid."));
36327 + }
36328 + }
36329 + if (!p_BindPort->useClsPlan)
36330 + {
36331 + /* This check may be redundant as port is a assigned to the whole NetEnv */
36332 +
36333 + /* if this port does not use clsPlan, it may not be bound to schemes with units that contain
36334 + cls plan options. Schemes that are used only directly, should not be checked.
36335 + it also may not be bound to schemes that go to CC with units that are options - so we OR
36336 + the match vector and the grpBits (= ccUnits) */
36337 + if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits)
36338 + {
36339 + uint8_t netEnvId;
36340 + walking1Mask = 0x80000000;
36341 + netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId;
36342 + tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector;
36343 + tmp |= p_Scheme->ccUnits;
36344 + while (tmp)
36345 + {
36346 + if (tmp & walking1Mask)
36347 + {
36348 + tmp &= ~walking1Mask;
36349 + if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask))
36350 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options"));
36351 + }
36352 + walking1Mask >>= 1;
36353 + }
36354 + }
36355 + }
36356 + }
36357 + /* build vector */
36358 + schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]);
36359 + }
36360 +
36361 + *p_SpReg = schemesPerPortVector;
36362 +
36363 + return E_OK;
36364 +}
36365 +
36366 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36367 +{
36368 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36369 + uint32_t spReg;
36370 + t_Error err = E_OK;
36371 +
36372 + err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE);
36373 + if (err)
36374 + RETURN_ERROR(MAJOR, err, NO_MSG);
36375 +
36376 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE);
36377 + if (err)
36378 + RETURN_ERROR(MAJOR, err, NO_MSG);
36379 +
36380 + IncSchemeOwners(p_FmPcd, p_SchemeBind);
36381 +
36382 + return E_OK;
36383 +}
36384 +
36385 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36386 +{
36387 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36388 + uint32_t spReg;
36389 + t_Error err = E_OK;
36390 +
36391 + err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE);
36392 + if (err)
36393 + RETURN_ERROR(MAJOR, err, NO_MSG);
36394 +
36395 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE);
36396 + if (err)
36397 + RETURN_ERROR(MAJOR, err, NO_MSG);
36398 +
36399 + DecSchemeOwners(p_FmPcd, p_SchemeBind);
36400 +
36401 + return E_OK;
36402 +}
36403 +
36404 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme)
36405 +{
36406 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
36407 +
36408 + return p_Scheme->valid;
36409 +}
36410 +
36411 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId)
36412 +{
36413 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36414 +
36415 + if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT)
36416 + return TRUE;
36417 + else
36418 + return FALSE;
36419 +}
36420 +
36421 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36422 +{
36423 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36424 + uint8_t i, j;
36425 +
36426 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36427 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36428 +
36429 + /* This routine is issued only on master core of master partition -
36430 + either directly or through IPC, so no need for lock */
36431 +
36432 + for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++)
36433 + {
36434 + if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated)
36435 + {
36436 + p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE;
36437 + p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId;
36438 + p_SchemesIds[j] = i;
36439 + j++;
36440 + }
36441 + }
36442 +
36443 + if (j != numOfSchemes)
36444 + {
36445 + /* roll back */
36446 + for (j--; j; j--)
36447 + {
36448 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE;
36449 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0;
36450 + p_SchemesIds[j] = 0;
36451 + }
36452 +
36453 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found"));
36454 + }
36455 +
36456 + return E_OK;
36457 +}
36458 +
36459 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36460 +{
36461 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36462 + uint8_t i;
36463 +
36464 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36465 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36466 +
36467 + /* This routine is issued only on master core of master partition -
36468 + either directly or through IPC */
36469 +
36470 + for (i = 0; i < numOfSchemes; i++)
36471 + {
36472 + if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated)
36473 + {
36474 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated"));
36475 + }
36476 + if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId)
36477 + {
36478 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. "));
36479 + }
36480 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE;
36481 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0;
36482 + }
36483 +
36484 + return E_OK;
36485 +}
36486 +
36487 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First)
36488 +{
36489 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36490 + uint8_t numOfBlocks, blocksFound=0, first=0;
36491 + uint8_t i, j;
36492 +
36493 + /* This routine is issued only on master core of master partition -
36494 + either directly or through IPC, so no need for lock */
36495 +
36496 + if (!numOfClsPlanEntries)
36497 + return E_OK;
36498 +
36499 + if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries)))
36500 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8"));
36501 +
36502 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36503 +
36504 + /* try to find consequent blocks */
36505 + first = 0;
36506 + for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;)
36507 + {
36508 + if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated)
36509 + {
36510 + blocksFound++;
36511 + i++;
36512 + if (blocksFound == numOfBlocks)
36513 + break;
36514 + }
36515 + else
36516 + {
36517 + blocksFound = 0;
36518 + /* advance i to the next aligned address */
36519 + first = i = (uint8_t)(first + numOfBlocks);
36520 + }
36521 + }
36522 +
36523 + if (blocksFound == numOfBlocks)
36524 + {
36525 + *p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP);
36526 + for (j = first; j < (first + numOfBlocks); j++)
36527 + {
36528 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE;
36529 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId;
36530 + }
36531 + return E_OK;
36532 + }
36533 + else
36534 + RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan"));
36535 +}
36536 +
36537 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base)
36538 +{
36539 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36540 + uint8_t numOfBlocks;
36541 + uint8_t i, baseBlock;
36542 +
36543 +#ifdef DISABLE_ASSERTIONS
36544 +UNUSED(guestId);
36545 +#endif /* DISABLE_ASSERTIONS */
36546 +
36547 + /* This routine is issued only on master core of master partition -
36548 + either directly or through IPC, so no need for lock */
36549 +
36550 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36551 + ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP));
36552 +
36553 + baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP);
36554 + for (i=baseBlock;i<baseBlock+numOfBlocks;i++)
36555 + {
36556 + ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated);
36557 + ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId);
36558 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE;
36559 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0;
36560 + }
36561 +}
36562 +
36563 +void KgEnable(t_FmPcd *p_FmPcd)
36564 +{
36565 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36566 +
36567 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36568 + fman_kg_enable(p_Regs);
36569 +}
36570 +
36571 +void KgDisable(t_FmPcd *p_FmPcd)
36572 +{
36573 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36574 +
36575 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36576 + fman_kg_disable(p_Regs);
36577 +}
36578 +
36579 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set)
36580 +{
36581 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36582 + struct fman_kg_cp_regs *p_FmPcdKgPortRegs;
36583 + uint32_t tmpKgarReg = 0, intFlags;
36584 + uint16_t i, j;
36585 +
36586 + /* This routine is protected by the calling routine ! */
36587 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36588 + p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs;
36589 +
36590 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
36591 + for (i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8)
36592 + {
36593 + tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
36594 +
36595 + for (j = i; j < i+8; j++)
36596 + {
36597 + ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1));
36598 + WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]);
36599 + }
36600 +
36601 + if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK)
36602 + {
36603 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED"));
36604 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36605 + return;
36606 + }
36607 + }
36608 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36609 +}
36610 +
36611 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
36612 +{
36613 + t_FmPcdKg *p_FmPcdKg;
36614 +
36615 + UNUSED(p_FmPcd);
36616 +
36617 + if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES)
36618 + {
36619 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
36620 + ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES));
36621 + return NULL;
36622 + }
36623 +
36624 + p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg));
36625 + if (!p_FmPcdKg)
36626 + {
36627 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED"));
36628 + return NULL;
36629 + }
36630 + memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg));
36631 +
36632 +
36633 + if (FmIsMaster(p_FmPcd->h_Fm))
36634 + {
36635 + p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm));
36636 + p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions;
36637 + p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0];
36638 + }
36639 +
36640 + p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes;
36641 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes)
36642 + {
36643 + p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
36644 + DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES"));
36645 + }
36646 +
36647 + p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36648 +
36649 + return p_FmPcdKg;
36650 +}
36651 +
36652 +t_Error KgInit(t_FmPcd *p_FmPcd)
36653 +{
36654 + t_Error err = E_OK;
36655 +
36656 + p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock();
36657 + if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36658 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock"));
36659 +
36660 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36661 + err = KgInitMaster(p_FmPcd);
36662 + else
36663 + err = KgInitGuest(p_FmPcd);
36664 +
36665 + if (err != E_OK)
36666 + {
36667 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36668 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36669 + }
36670 +
36671 + return err;
36672 +}
36673 +
36674 +t_Error KgFree(t_FmPcd *p_FmPcd)
36675 +{
36676 + t_FmPcdIpcKgSchemesParams kgAlloc;
36677 + t_Error err = E_OK;
36678 + t_FmPcdIpcMsg msg;
36679 + uint32_t replyLength;
36680 + t_FmPcdIpcReply reply;
36681 +
36682 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR);
36683 +
36684 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36685 + {
36686 + err = FmPcdKgFreeSchemes(p_FmPcd,
36687 + p_FmPcd->p_FmPcdKg->numOfSchemes,
36688 + p_FmPcd->guestId,
36689 + p_FmPcd->p_FmPcdKg->schemesIds);
36690 + if (err)
36691 + RETURN_ERROR(MAJOR, err, NO_MSG);
36692 +
36693 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36694 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36695 +
36696 + return E_OK;
36697 + }
36698 +
36699 + /* guest */
36700 + memset(&reply, 0, sizeof(reply));
36701 + memset(&msg, 0, sizeof(msg));
36702 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
36703 + kgAlloc.guestId = p_FmPcd->guestId;
36704 + ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES);
36705 + memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes);
36706 + msg.msgId = FM_PCD_FREE_KG_SCHEMES;
36707 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36708 + replyLength = sizeof(uint32_t);
36709 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36710 + (uint8_t*)&msg,
36711 + sizeof(msg.msgId) + sizeof(kgAlloc),
36712 + (uint8_t*)&reply,
36713 + &replyLength,
36714 + NULL,
36715 + NULL)) != E_OK)
36716 + RETURN_ERROR(MAJOR, err, NO_MSG);
36717 + if (replyLength != sizeof(uint32_t))
36718 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36719 +
36720 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36721 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36722 +
36723 + return (t_Error)reply.error;
36724 +}
36725 +
36726 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp)
36727 +{
36728 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36729 + t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams;
36730 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
36731 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
36732 + t_Error err;
36733 +
36734 + /* This function is issued only from FM_PORT_SetPcd which locked all PCD modules,
36735 + so no need for lock here */
36736 +
36737 + memset(&grpParams, 0, sizeof(grpParams));
36738 + grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN;
36739 + p_GrpParams = &grpParams;
36740 +
36741 + p_GrpParams->netEnvId = netEnvId;
36742 +
36743 + /* Get from the NetEnv the information of the clsPlan (can be already created,
36744 + * or needs to build) */
36745 + err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams);
36746 + if (err)
36747 + RETURN_ERROR(MINOR,err,NO_MSG);
36748 +
36749 + if (p_GrpParams->grpExists)
36750 + {
36751 + /* this group was already updated (at least) in SW */
36752 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36753 + }
36754 + else
36755 + {
36756 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
36757 + if (!p_ClsPlanSet)
36758 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
36759 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
36760 + /* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */
36761 + err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet);
36762 + if (err)
36763 + {
36764 + XX_Free(p_ClsPlanSet);
36765 + RETURN_ERROR(MINOR, err, NO_MSG);
36766 + }
36767 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36768 +
36769 + if (p_FmPcd->h_Hc)
36770 + {
36771 + /* write clsPlan entries to memory */
36772 + err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet);
36773 + if (err)
36774 + {
36775 + XX_Free(p_ClsPlanSet);
36776 + RETURN_ERROR(MAJOR, err, NO_MSG);
36777 + }
36778 + }
36779 + else
36780 + /* write clsPlan entries to memory */
36781 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
36782 +
36783 + XX_Free(p_ClsPlanSet);
36784 + }
36785 +
36786 + /* Set caller parameters */
36787 +
36788 + /* mark if this is an empty classification group */
36789 + if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
36790 + *p_IsEmptyClsPlanGrp = TRUE;
36791 + else
36792 + *p_IsEmptyClsPlanGrp = FALSE;
36793 +
36794 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId];
36795 +
36796 + /* increment owners number */
36797 + p_ClsPlanGrp->owners++;
36798 +
36799 + /* copy options array for port */
36800 + 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));
36801 +
36802 + /* bind port to the new or existing group */
36803 + err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId);
36804 + if (err)
36805 + RETURN_ERROR(MINOR, err, NO_MSG);
36806 +
36807 + return E_OK;
36808 +}
36809 +
36810 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
36811 +{
36812 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36813 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId];
36814 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
36815 + t_Error err;
36816 +
36817 + /* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules,
36818 + so no need for lock here */
36819 +
36820 + UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId);
36821 +
36822 + /* decrement owners number */
36823 + ASSERT_COND(p_ClsPlanGrp->owners);
36824 + p_ClsPlanGrp->owners--;
36825 +
36826 + if (!p_ClsPlanGrp->owners)
36827 + {
36828 + if (p_FmPcd->h_Hc)
36829 + {
36830 + err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId);
36831 + return err;
36832 + }
36833 + else
36834 + {
36835 + /* clear clsPlan entries in memory */
36836 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
36837 + if (!p_ClsPlanSet)
36838 + {
36839 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
36840 + }
36841 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
36842 +
36843 + p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry;
36844 + p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp;
36845 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
36846 + XX_Free(p_ClsPlanSet);
36847 +
36848 + FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId);
36849 + }
36850 + }
36851 + return E_OK;
36852 +}
36853 +
36854 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId)
36855 +{
36856 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36857 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36858 +
36859 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction;
36860 +}
36861 +
36862 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId)
36863 +{
36864 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36865 +
36866 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36867 +
36868 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag;
36869 +}
36870 +
36871 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId)
36872 +{
36873 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36874 +
36875 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36876 +
36877 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr;
36878 +}
36879 +
36880 +
36881 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId)
36882 +{
36883 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36884 +
36885 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36886 +
36887 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId;
36888 +}
36889 +
36890 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId)
36891 +{
36892 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36893 +
36894 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36895 +
36896 + if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs &&
36897 + p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) ||
36898 + p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile)
36899 + return TRUE;
36900 + else
36901 + return FALSE;
36902 +
36903 +}
36904 +
36905 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId)
36906 +{
36907 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36908 +
36909 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid);
36910 +
36911 + return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine;
36912 +}
36913 +
36914 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId)
36915 +{
36916 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36917 +
36918 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36919 +
36920 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction;
36921 +}
36922 +
36923 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction)
36924 +{
36925 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
36926 +
36927 + /* this routine is protected by calling routine */
36928 +
36929 + ASSERT_COND(p_Scheme->valid);
36930 +
36931 + p_Scheme->requiredAction |= requiredAction;
36932 +}
36933 +
36934 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg)
36935 +{
36936 + return (bool)!!(schemeModeReg & KG_SCH_MODE_EN);
36937 +}
36938 +
36939 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter)
36940 +{
36941 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
36942 + FM_KG_KGAR_GO |
36943 + FM_KG_KGAR_WRITE |
36944 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
36945 + DUMMY_PORT_ID |
36946 + (updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0));
36947 +}
36948 +
36949 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId)
36950 +{
36951 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
36952 + FM_KG_KGAR_GO |
36953 + FM_KG_KGAR_READ |
36954 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
36955 + DUMMY_PORT_ID |
36956 + FM_KG_KGAR_SCM_WSEL_UPDATE_CNT);
36957 +
36958 +}
36959 +
36960 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId)
36961 +{
36962 + return (uint32_t)(FM_KG_KGAR_GO |
36963 + FM_KG_KGAR_WRITE |
36964 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
36965 + DUMMY_PORT_ID |
36966 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
36967 + FM_PCD_KG_KGAR_WSEL_MASK);
36968 +
36969 + /* if we ever want to write 1 by 1, use:
36970 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
36971 + */
36972 +}
36973 +
36974 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId)
36975 +{
36976 +
36977 + return (uint32_t)(FM_KG_KGAR_GO |
36978 + FM_KG_KGAR_WRITE |
36979 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
36980 + hardwarePortId |
36981 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
36982 +}
36983 +
36984 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId)
36985 +{
36986 +
36987 + return (uint32_t)(FM_KG_KGAR_GO |
36988 + FM_KG_KGAR_READ |
36989 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
36990 + hardwarePortId |
36991 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
36992 +}
36993 +
36994 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId)
36995 +{
36996 +
36997 + return (uint32_t)(FM_KG_KGAR_GO |
36998 + FM_KG_KGAR_WRITE |
36999 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37000 + hardwarePortId |
37001 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
37002 +}
37003 +
37004 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp)
37005 +{
37006 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37007 +
37008 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry;
37009 +}
37010 +
37011 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp)
37012 +{
37013 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37014 +
37015 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp;
37016 +}
37017 +
37018 +
37019 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme)
37020 +{
37021 + return ((t_FmPcdKgScheme*)h_Scheme)->schemeId;
37022 +
37023 +}
37024 +
37025 +#if (DPAA_VERSION >= 11)
37026 +bool FmPcdKgGetVspe(t_Handle h_Scheme)
37027 +{
37028 + return ((t_FmPcdKgScheme*)h_Scheme)->vspe;
37029 +
37030 +}
37031 +#endif /* (DPAA_VERSION >= 11) */
37032 +
37033 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId)
37034 +{
37035 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37036 + uint8_t i;
37037 +
37038 + for (i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++)
37039 + if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId)
37040 + return i;
37041 +
37042 + if (i == p_FmPcd->p_FmPcdKg->numOfSchemes)
37043 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range"));
37044 +
37045 + return FM_PCD_KG_NUM_OF_SCHEMES;
37046 +}
37047 +
37048 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId)
37049 +{
37050 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37051 +
37052 + ASSERT_COND(p_FmPcd);
37053 +
37054 + /* check that schemeId is in range */
37055 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
37056 + {
37057 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
37058 + return NULL;
37059 + }
37060 +
37061 + if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]))
37062 + return NULL;
37063 +
37064 + return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37065 +}
37066 +
37067 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme)
37068 +{
37069 + return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE;
37070 +}
37071 +
37072 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
37073 +{
37074 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37075 + uint8_t relativeSchemeId, physicalSchemeId;
37076 + uint32_t tmpKgarReg, tmpReg32 = 0, intFlags;
37077 + t_Error err;
37078 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
37079 +
37080 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
37081 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);
37082 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
37083 +
37084 + /* Calling function locked all PCD modules, so no need to lock here */
37085 +
37086 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
37087 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37088 +
37089 + if (p_FmPcd->h_Hc)
37090 + {
37091 + err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value);
37092 +
37093 + UpdateRequiredActionFlag(h_Scheme,TRUE);
37094 + FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction);
37095 + return err;
37096 + }
37097 +
37098 + physicalSchemeId = p_Scheme->schemeId;
37099 +
37100 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
37101 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
37102 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37103 +
37104 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag ||
37105 + !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction))
37106 + {
37107 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
37108 + {
37109 + switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine)
37110 + {
37111 + case (e_FM_PCD_DONE):
37112 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME)
37113 + {
37114 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37115 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37116 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37117 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37118 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
37119 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA);
37120 + /* call indirect command for scheme write */
37121 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37122 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37123 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37124 + }
37125 + break;
37126 + case (e_FM_PCD_PLCR):
37127 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr ||
37128 + (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs &&
37129 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) ||
37130 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile)
37131 + {
37132 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
37133 + }
37134 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction);
37135 + if (err)
37136 + {
37137 + RETURN_ERROR(MAJOR, err, NO_MSG);
37138 + }
37139 + break;
37140 + default:
37141 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME"));
37142 + }
37143 + }
37144 + if (requiredAction & UPDATE_KG_NIA_CC_WA)
37145 + {
37146 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC)
37147 + {
37148 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37149 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37150 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37151 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37152 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
37153 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
37154 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC);
37155 + /* call indirect command for scheme write */
37156 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37157 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37158 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37159 + }
37160 + }
37161 + if (requiredAction & UPDATE_KG_OPT_MODE)
37162 + {
37163 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37164 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37165 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37166 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value);
37167 + /* call indirect command for scheme write */
37168 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37169 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37170 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37171 + }
37172 + if (requiredAction & UPDATE_KG_NIA)
37173 + {
37174 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37175 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37176 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37177 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37178 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
37179 + tmpReg32 |= value;
37180 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32);
37181 + /* call indirect command for scheme write */
37182 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37183 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37184 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37185 + }
37186 + }
37187 +
37188 + UpdateRequiredActionFlag(h_Scheme, TRUE);
37189 + FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction);
37190 +
37191 + return E_OK;
37192 +}
37193 +/*********************** End of inter-module routines ************************/
37194 +
37195 +
37196 +/****************************************/
37197 +/* API routines */
37198 +/****************************************/
37199 +
37200 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams)
37201 +{
37202 + t_FmPcd *p_FmPcd;
37203 + struct fman_kg_scheme_regs schemeRegs;
37204 + struct fman_kg_scheme_regs *p_MemRegs;
37205 + uint8_t i;
37206 + t_Error err = E_OK;
37207 + uint32_t tmpKgarReg;
37208 + uint32_t intFlags;
37209 + uint8_t physicalSchemeId, relativeSchemeId = 0;
37210 + t_FmPcdKgScheme *p_Scheme;
37211 +
37212 + if (p_SchemeParams->modify)
37213 + {
37214 + p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme;
37215 + p_FmPcd = p_Scheme->h_FmPcd;
37216 +
37217 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37218 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37219 +
37220 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
37221 + {
37222 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37223 + ("Scheme is invalid"));
37224 + return NULL;
37225 + }
37226 +
37227 + if (!KgSchemeFlagTryLock(p_Scheme))
37228 + {
37229 + DBG(TRACE, ("Scheme Try Lock - BUSY"));
37230 + /* Signal to caller BUSY condition */
37231 + p_SchemeParams->id.h_Scheme = NULL;
37232 + return NULL;
37233 + }
37234 + }
37235 + else
37236 + {
37237 + p_FmPcd = (t_FmPcd*)h_FmPcd;
37238 +
37239 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37240 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37241 +
37242 + relativeSchemeId = p_SchemeParams->id.relativeSchemeId;
37243 + /* check that schemeId is in range */
37244 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
37245 + {
37246 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
37247 + return NULL;
37248 + }
37249 +
37250 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37251 + if (FmPcdKgIsSchemeValidSw(p_Scheme))
37252 + {
37253 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37254 + ("Scheme id (%d)!", relativeSchemeId));
37255 + return NULL;
37256 + }
37257 + /* Clear all fields, scheme may have beed previously used */
37258 + memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme));
37259 +
37260 + p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId];
37261 + p_Scheme->h_FmPcd = p_FmPcd;
37262 +
37263 + p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd);
37264 + if (!p_Scheme->p_Lock)
37265 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!"));
37266 + }
37267 +
37268 + err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs);
37269 + if (err)
37270 + {
37271 + REPORT_ERROR(MAJOR, err, NO_MSG);
37272 + if (p_SchemeParams->modify)
37273 + KgSchemeFlagUnlock(p_Scheme);
37274 + if (!p_SchemeParams->modify &&
37275 + p_Scheme->p_Lock)
37276 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37277 + return NULL;
37278 + }
37279 +
37280 + if (p_FmPcd->h_Hc)
37281 + {
37282 + err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc,
37283 + (t_Handle)p_Scheme,
37284 + &schemeRegs,
37285 + p_SchemeParams->schemeCounter.update);
37286 + if (p_SchemeParams->modify)
37287 + KgSchemeFlagUnlock(p_Scheme);
37288 + if (err)
37289 + {
37290 + if (!p_SchemeParams->modify &&
37291 + p_Scheme->p_Lock)
37292 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37293 + return NULL;
37294 + }
37295 + if (!p_SchemeParams->modify)
37296 + ValidateSchemeSw(p_Scheme);
37297 + return (t_Handle)p_Scheme;
37298 + }
37299 +
37300 + physicalSchemeId = p_Scheme->schemeId;
37301 +
37302 + /* configure all 21 scheme registers */
37303 + p_MemRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs;
37304 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37305 + WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc);
37306 + WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs);
37307 + WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode);
37308 + WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv);
37309 + WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0);
37310 + WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1);
37311 + WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv);
37312 + WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc);
37313 + WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch);
37314 + WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl);
37315 + WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc);
37316 + WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc);
37317 + WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb);
37318 + WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om);
37319 + WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp);
37320 + for (i=0 ; i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
37321 + WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]);
37322 +
37323 + /* call indirect command for scheme write */
37324 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update);
37325 +
37326 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37327 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37328 +
37329 + if (!p_SchemeParams->modify)
37330 + ValidateSchemeSw(p_Scheme);
37331 + else
37332 + KgSchemeFlagUnlock(p_Scheme);
37333 +
37334 + return (t_Handle)p_Scheme;
37335 +}
37336 +
37337 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme)
37338 +{
37339 + t_FmPcd *p_FmPcd;
37340 + uint8_t physicalSchemeId;
37341 + uint32_t tmpKgarReg, intFlags;
37342 + t_Error err = E_OK;
37343 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
37344 +
37345 + SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE);
37346 +
37347 + p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd);
37348 +
37349 + UpdateRequiredActionFlag(h_Scheme, FALSE);
37350 +
37351 + /* check that no port is bound to this scheme */
37352 + err = InvalidateSchemeSw(h_Scheme);
37353 + if (err)
37354 + RETURN_ERROR(MINOR, err, NO_MSG);
37355 +
37356 + if (p_FmPcd->h_Hc)
37357 + {
37358 + err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme);
37359 + if (p_Scheme->p_Lock)
37360 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37361 + return err;
37362 + }
37363 +
37364 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37365 +
37366 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37367 + /* clear mode register, including enable bit */
37368 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0);
37369 +
37370 + /* call indirect command for scheme write */
37371 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37372 +
37373 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37374 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37375 +
37376 + if (p_Scheme->p_Lock)
37377 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37378 +
37379 + return E_OK;
37380 +}
37381 +
37382 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme)
37383 +{
37384 + t_FmPcd *p_FmPcd;
37385 + uint32_t tmpKgarReg, spc, intFlags;
37386 + uint8_t physicalSchemeId;
37387 +
37388 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37389 +
37390 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37391 + if (p_FmPcd->h_Hc)
37392 + return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme);
37393 +
37394 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37395 +
37396 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37397 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37398 +
37399 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37400 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37401 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37402 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37403 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37404 + spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc);
37405 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37406 +
37407 + return spc;
37408 +}
37409 +
37410 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value)
37411 +{
37412 + t_FmPcd *p_FmPcd;
37413 + uint32_t tmpKgarReg, intFlags;
37414 + uint8_t physicalSchemeId;
37415 +
37416 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37417 +
37418 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37419 +
37420 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
37421 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
37422 +
37423 + if (p_FmPcd->h_Hc)
37424 + return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value);
37425 +
37426 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37427 + /* check that schemeId is in range */
37428 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37429 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37430 +
37431 + /* read specified scheme into scheme registers */
37432 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37433 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37434 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37435 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37436 + {
37437 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37438 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37439 + }
37440 +
37441 + /* change counter value */
37442 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value);
37443 +
37444 + /* call indirect command for scheme write */
37445 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
37446 +
37447 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37448 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37449 +
37450 + return E_OK;
37451 +}
37452 +
37453 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset)
37454 +{
37455 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37456 + struct fman_kg_regs *p_Regs;
37457 +
37458 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37459 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37460 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37461 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37462 +
37463 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37464 + if (!FmIsMaster(p_FmPcd->h_Fm))
37465 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!"));
37466 +
37467 + WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset);
37468 +
37469 + return E_OK;
37470 +}
37471 +
37472 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value)
37473 +{
37474 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37475 + struct fman_kg_regs *p_Regs;
37476 +
37477 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37478 + SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE);
37479 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37480 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37481 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37482 +
37483 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37484 +
37485 + if (!FmIsMaster(p_FmPcd->h_Fm))
37486 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!"));
37487 +
37488 + if (valueId == 0)
37489 + WRITE_UINT32(p_Regs->fmkg_gdv0r,value);
37490 + else
37491 + WRITE_UINT32(p_Regs->fmkg_gdv1r,value);
37492 + return E_OK;
37493 +}
37494 --- /dev/null
37495 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
37496 @@ -0,0 +1,206 @@
37497 +/*
37498 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37499 + *
37500 + * Redistribution and use in source and binary forms, with or without
37501 + * modification, are permitted provided that the following conditions are met:
37502 + * * Redistributions of source code must retain the above copyright
37503 + * notice, this list of conditions and the following disclaimer.
37504 + * * Redistributions in binary form must reproduce the above copyright
37505 + * notice, this list of conditions and the following disclaimer in the
37506 + * documentation and/or other materials provided with the distribution.
37507 + * * Neither the name of Freescale Semiconductor nor the
37508 + * names of its contributors may be used to endorse or promote products
37509 + * derived from this software without specific prior written permission.
37510 + *
37511 + *
37512 + * ALTERNATIVELY, this software may be distributed under the terms of the
37513 + * GNU General Public License ("GPL") as published by the Free Software
37514 + * Foundation, either version 2 of that License or (at your option) any
37515 + * later version.
37516 + *
37517 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37518 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37519 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37520 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37521 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37522 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37523 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37524 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37525 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37526 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37527 + */
37528 +
37529 +
37530 +/******************************************************************************
37531 + @File fm_kg.h
37532 +
37533 + @Description FM KG private header
37534 +*//***************************************************************************/
37535 +#ifndef __FM_KG_H
37536 +#define __FM_KG_H
37537 +
37538 +#include "std_ext.h"
37539 +
37540 +/***********************************************************************/
37541 +/* Keygen defines */
37542 +/***********************************************************************/
37543 +/* maskes */
37544 +#if (DPAA_VERSION >= 11)
37545 +#define KG_SCH_VSP_SHIFT_MASK 0x0003f000
37546 +#define KG_SCH_OM_VSPE 0x00000001
37547 +#define KG_SCH_VSP_NO_KSP_EN 0x80000000
37548 +
37549 +#define MAX_SP_SHIFT 23
37550 +#define KG_SCH_VSP_MASK_SHIFT 12
37551 +#define KG_SCH_VSP_SHIFT 24
37552 +#endif /* (DPAA_VERSION >= 11) */
37553 +
37554 +typedef uint32_t t_KnownFieldsMasks;
37555 +#define KG_SCH_KN_PORT_ID 0x80000000
37556 +#define KG_SCH_KN_MACDST 0x40000000
37557 +#define KG_SCH_KN_MACSRC 0x20000000
37558 +#define KG_SCH_KN_TCI1 0x10000000
37559 +#define KG_SCH_KN_TCI2 0x08000000
37560 +#define KG_SCH_KN_ETYPE 0x04000000
37561 +#define KG_SCH_KN_PPPSID 0x02000000
37562 +#define KG_SCH_KN_PPPID 0x01000000
37563 +#define KG_SCH_KN_MPLS1 0x00800000
37564 +#define KG_SCH_KN_MPLS2 0x00400000
37565 +#define KG_SCH_KN_MPLS_LAST 0x00200000
37566 +#define KG_SCH_KN_IPSRC1 0x00100000
37567 +#define KG_SCH_KN_IPDST1 0x00080000
37568 +#define KG_SCH_KN_PTYPE1 0x00040000
37569 +#define KG_SCH_KN_IPTOS_TC1 0x00020000
37570 +#define KG_SCH_KN_IPV6FL1 0x00010000
37571 +#define KG_SCH_KN_IPSRC2 0x00008000
37572 +#define KG_SCH_KN_IPDST2 0x00004000
37573 +#define KG_SCH_KN_PTYPE2 0x00002000
37574 +#define KG_SCH_KN_IPTOS_TC2 0x00001000
37575 +#define KG_SCH_KN_IPV6FL2 0x00000800
37576 +#define KG_SCH_KN_GREPTYPE 0x00000400
37577 +#define KG_SCH_KN_IPSEC_SPI 0x00000200
37578 +#define KG_SCH_KN_IPSEC_NH 0x00000100
37579 +#define KG_SCH_KN_IPPID 0x00000080
37580 +#define KG_SCH_KN_L4PSRC 0x00000004
37581 +#define KG_SCH_KN_L4PDST 0x00000002
37582 +#define KG_SCH_KN_TFLG 0x00000001
37583 +
37584 +typedef uint8_t t_GenericCodes;
37585 +#define KG_SCH_GEN_SHIM1 0x70
37586 +#define KG_SCH_GEN_DEFAULT 0x10
37587 +#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20
37588 +#define KG_SCH_GEN_START_OF_FRM 0x40
37589 +#define KG_SCH_GEN_SHIM2 0x71
37590 +#define KG_SCH_GEN_IP_PID_NO_V 0x72
37591 +#define KG_SCH_GEN_ETH 0x03
37592 +#define KG_SCH_GEN_ETH_NO_V 0x73
37593 +#define KG_SCH_GEN_SNAP 0x04
37594 +#define KG_SCH_GEN_SNAP_NO_V 0x74
37595 +#define KG_SCH_GEN_VLAN1 0x05
37596 +#define KG_SCH_GEN_VLAN1_NO_V 0x75
37597 +#define KG_SCH_GEN_VLAN2 0x06
37598 +#define KG_SCH_GEN_VLAN2_NO_V 0x76
37599 +#define KG_SCH_GEN_ETH_TYPE 0x07
37600 +#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77
37601 +#define KG_SCH_GEN_PPP 0x08
37602 +#define KG_SCH_GEN_PPP_NO_V 0x78
37603 +#define KG_SCH_GEN_MPLS1 0x09
37604 +#define KG_SCH_GEN_MPLS2 0x19
37605 +#define KG_SCH_GEN_MPLS3 0x29
37606 +#define KG_SCH_GEN_MPLS1_NO_V 0x79
37607 +#define KG_SCH_GEN_MPLS_LAST 0x0a
37608 +#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a
37609 +#define KG_SCH_GEN_IPV4 0x0b
37610 +#define KG_SCH_GEN_IPV6 0x1b
37611 +#define KG_SCH_GEN_L3_NO_V 0x7b
37612 +#define KG_SCH_GEN_IPV4_TUNNELED 0x0c
37613 +#define KG_SCH_GEN_IPV6_TUNNELED 0x1c
37614 +#define KG_SCH_GEN_MIN_ENCAP 0x2c
37615 +#define KG_SCH_GEN_IP2_NO_V 0x7c
37616 +#define KG_SCH_GEN_GRE 0x0d
37617 +#define KG_SCH_GEN_GRE_NO_V 0x7d
37618 +#define KG_SCH_GEN_TCP 0x0e
37619 +#define KG_SCH_GEN_UDP 0x1e
37620 +#define KG_SCH_GEN_IPSEC_AH 0x2e
37621 +#define KG_SCH_GEN_SCTP 0x3e
37622 +#define KG_SCH_GEN_DCCP 0x4e
37623 +#define KG_SCH_GEN_IPSEC_ESP 0x6e
37624 +#define KG_SCH_GEN_L4_NO_V 0x7e
37625 +#define KG_SCH_GEN_NEXTHDR 0x7f
37626 +/* shifts */
37627 +#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27
37628 +#define KG_SCH_PP_SHIFT_LOW_SHIFT 12
37629 +#define KG_SCH_PP_MASK_SHIFT 16
37630 +#define KG_SCH_MODE_CCOBASE_SHIFT 24
37631 +#define KG_SCH_DEF_MAC_ADDR_SHIFT 30
37632 +#define KG_SCH_DEF_TCI_SHIFT 28
37633 +#define KG_SCH_DEF_ENET_TYPE_SHIFT 26
37634 +#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24
37635 +#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22
37636 +#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20
37637 +#define KG_SCH_DEF_IP_ADDR_SHIFT 18
37638 +#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16
37639 +#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14
37640 +#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12
37641 +#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10
37642 +#define KG_SCH_DEF_L4_PORT_SHIFT 8
37643 +#define KG_SCH_DEF_TCP_FLAG_SHIFT 6
37644 +#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24
37645 +#define KG_SCH_GEN_MASK_SHIFT 16
37646 +#define KG_SCH_GEN_HT_SHIFT 8
37647 +#define KG_SCH_GEN_SIZE_SHIFT 24
37648 +#define KG_SCH_GEN_DEF_SHIFT 29
37649 +#define FM_PCD_KG_KGAR_NUM_SHIFT 16
37650 +
37651 +/* others */
37652 +#define NUM_OF_SW_DEFAULTS 3
37653 +#define MAX_PP_SHIFT 23
37654 +#define MAX_KG_SCH_SIZE 16
37655 +#define MASK_FOR_GENERIC_BASE_ID 0x20
37656 +#define MAX_HASH_SHIFT 40
37657 +#define MAX_KG_SCH_FQID_BIT_OFFSET 31
37658 +#define MAX_KG_SCH_PP_BIT_OFFSET 15
37659 +#define MAX_DIST_FQID_SHIFT 23
37660 +
37661 +#define GET_MASK_SEL_SHIFT(shift,i) \
37662 +switch (i) { \
37663 + case (0):shift = 26;break; \
37664 + case (1):shift = 20;break; \
37665 + case (2):shift = 10;break; \
37666 + case (3):shift = 4;break; \
37667 + default: \
37668 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37669 +}
37670 +
37671 +#define GET_MASK_OFFSET_SHIFT(shift,i) \
37672 +switch (i) { \
37673 + case (0):shift = 16;break; \
37674 + case (1):shift = 0;break; \
37675 + case (2):shift = 28;break; \
37676 + case (3):shift = 24;break; \
37677 + default: \
37678 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37679 +}
37680 +
37681 +#define GET_MASK_SHIFT(shift,i) \
37682 +switch (i) { \
37683 + case (0):shift = 24;break; \
37684 + case (1):shift = 16;break; \
37685 + case (2):shift = 8;break; \
37686 + case (3):shift = 0;break; \
37687 + default: \
37688 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37689 +}
37690 +
37691 +/***********************************************************************/
37692 +/* Keygen defines */
37693 +/***********************************************************************/
37694 +
37695 +#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100
37696 +#define NO_VALIDATION 0x70
37697 +#define KG_ACTION_REG_TO 1024
37698 +#define KG_MAX_PROFILE 255
37699 +#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF
37700 +
37701 +
37702 +#endif /* __FM_KG_H */
37703 --- /dev/null
37704 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
37705 @@ -0,0 +1,5571 @@
37706 +/*
37707 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37708 + *
37709 + * Redistribution and use in source and binary forms, with or without
37710 + * modification, are permitted provided that the following conditions are met:
37711 + * * Redistributions of source code must retain the above copyright
37712 + * notice, this list of conditions and the following disclaimer.
37713 + * * Redistributions in binary form must reproduce the above copyright
37714 + * notice, this list of conditions and the following disclaimer in the
37715 + * documentation and/or other materials provided with the distribution.
37716 + * * Neither the name of Freescale Semiconductor nor the
37717 + * names of its contributors may be used to endorse or promote products
37718 + * derived from this software without specific prior written permission.
37719 + *
37720 + *
37721 + * ALTERNATIVELY, this software may be distributed under the terms of the
37722 + * GNU General Public License ("GPL") as published by the Free Software
37723 + * Foundation, either version 2 of that License or (at your option) any
37724 + * later version.
37725 + *
37726 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37727 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37728 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37729 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37730 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37731 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37732 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37733 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37734 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37735 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37736 + */
37737 +
37738 +
37739 +/******************************************************************************
37740 + @File fm_manip.c
37741 +
37742 + @Description FM PCD manip ...
37743 + *//***************************************************************************/
37744 +#include "std_ext.h"
37745 +#include "error_ext.h"
37746 +#include "string_ext.h"
37747 +#include "debug_ext.h"
37748 +#include "fm_pcd_ext.h"
37749 +#include "fm_port_ext.h"
37750 +#include "fm_muram_ext.h"
37751 +#include "memcpy_ext.h"
37752 +
37753 +#include "fm_common.h"
37754 +#include "fm_hc.h"
37755 +#include "fm_manip.h"
37756 +
37757 +/****************************************/
37758 +/* static functions */
37759 +/****************************************/
37760 +static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo)
37761 +{
37762 + t_FmPcdManip *p_CurManip = p_Manip;
37763 +
37764 + if (!MANIP_IS_UNIFIED(p_Manip))
37765 + p_CurManip = p_Manip;
37766 + else
37767 + {
37768 + /* go to first unified */
37769 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37770 + p_CurManip = p_CurManip->h_PrevManip;
37771 + }
37772 +
37773 + switch (manipInfo)
37774 + {
37775 + case (e_MANIP_HMCT):
37776 + return p_CurManip->p_Hmct;
37777 + case (e_MANIP_HMTD):
37778 + return p_CurManip->h_Ad;
37779 + case (e_MANIP_HANDLER_TABLE_OWNER):
37780 + return (t_Handle)p_CurManip;
37781 + default:
37782 + return NULL;
37783 + }
37784 +}
37785 +
37786 +static uint16_t GetHmctSize(t_FmPcdManip *p_Manip)
37787 +{
37788 + uint16_t size = 0;
37789 + t_FmPcdManip *p_CurManip = p_Manip;
37790 +
37791 + if (!MANIP_IS_UNIFIED(p_Manip))
37792 + return p_Manip->tableSize;
37793 +
37794 + /* accumulate sizes, starting with the first node */
37795 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37796 + p_CurManip = p_CurManip->h_PrevManip;
37797 +
37798 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
37799 + {
37800 + size += p_CurManip->tableSize;
37801 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
37802 + }
37803 + size += p_CurManip->tableSize; /* add last size */
37804 +
37805 + return (size);
37806 +}
37807 +
37808 +static uint16_t GetDataSize(t_FmPcdManip *p_Manip)
37809 +{
37810 + uint16_t size = 0;
37811 + t_FmPcdManip *p_CurManip = p_Manip;
37812 +
37813 + if (!MANIP_IS_UNIFIED(p_Manip))
37814 + return p_Manip->dataSize;
37815 +
37816 + /* accumulate sizes, starting with the first node */
37817 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37818 + p_CurManip = p_CurManip->h_PrevManip;
37819 +
37820 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
37821 + {
37822 + size += p_CurManip->dataSize;
37823 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
37824 + }
37825 + size += p_CurManip->dataSize; /* add last size */
37826 +
37827 + return (size);
37828 +}
37829 +
37830 +static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams,
37831 + uint16_t *p_TableSize, uint8_t *p_DataSize)
37832 +{
37833 + uint8_t localDataSize, remain, tableSize = 0, dataSize = 0;
37834 +
37835 + if (p_FmPcdManipParams->u.hdr.rmv)
37836 + {
37837 + switch (p_FmPcdManipParams->u.hdr.rmvParams.type)
37838 + {
37839 + case (e_FM_PCD_MANIP_RMV_GENERIC):
37840 + tableSize += HMCD_BASIC_SIZE;
37841 + break;
37842 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
37843 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
37844 + {
37845 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
37846 +#if (DPAA_VERSION >= 11)
37847 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
37848 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
37849 +#endif /* (DPAA_VERSION >= 11) */
37850 + tableSize += HMCD_BASIC_SIZE;
37851 + break;
37852 + default:
37853 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37854 + ("Unknown byHdr.type"));
37855 + }
37856 + break;
37857 + default:
37858 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37859 + ("Unknown rmvParams.type"));
37860 + }
37861 + }
37862 +
37863 + if (p_FmPcdManipParams->u.hdr.insrt)
37864 + {
37865 + switch (p_FmPcdManipParams->u.hdr.insrtParams.type)
37866 + {
37867 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
37868 + remain =
37869 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
37870 + % 4);
37871 + if (remain)
37872 + localDataSize =
37873 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
37874 + + 4 - remain);
37875 + else
37876 + localDataSize =
37877 + p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
37878 + tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize);
37879 + break;
37880 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
37881 + {
37882 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
37883 + {
37884 +
37885 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
37886 + tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE;
37887 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
37888 + {
37889 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
37890 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
37891 + dataSize +=
37892 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
37893 + break;
37894 + default:
37895 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
37896 + }
37897 + break;
37898 +#if (DPAA_VERSION >= 11)
37899 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
37900 + tableSize +=
37901 + (HMCD_BASIC_SIZE + HMCD_PTR_SIZE
37902 + + HMCD_PARAM_SIZE
37903 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
37904 + dataSize += 2;
37905 + break;
37906 +
37907 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
37908 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
37909 + tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE);
37910 +
37911 + break;
37912 +
37913 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
37914 + tableSize +=
37915 + (HMCD_BASIC_SIZE
37916 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
37917 + break;
37918 +#endif /* (DPAA_VERSION >= 11) */
37919 + default:
37920 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37921 + ("Unknown byHdr.type"));
37922 + }
37923 + }
37924 + break;
37925 + default:
37926 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37927 + ("Unknown insrtParams.type"));
37928 + }
37929 + }
37930 +
37931 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
37932 + {
37933 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
37934 + {
37935 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
37936 + tableSize += HMCD_BASIC_SIZE;
37937 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
37938 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
37939 + {
37940 + tableSize += HMCD_PTR_SIZE;
37941 + dataSize += DSCP_TO_VLAN_TABLE_SIZE;
37942 + }
37943 + break;
37944 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
37945 + tableSize += HMCD_BASIC_SIZE;
37946 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37947 + & HDR_MANIP_IPV4_ID)
37948 + {
37949 + tableSize += HMCD_PARAM_SIZE;
37950 + dataSize += 2;
37951 + }
37952 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37953 + & HDR_MANIP_IPV4_SRC)
37954 + tableSize += HMCD_IPV4_ADDR_SIZE;
37955 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37956 + & HDR_MANIP_IPV4_DST)
37957 + tableSize += HMCD_IPV4_ADDR_SIZE;
37958 + break;
37959 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
37960 + tableSize += HMCD_BASIC_SIZE;
37961 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37962 + & HDR_MANIP_IPV6_SRC)
37963 + tableSize += HMCD_IPV6_ADDR_SIZE;
37964 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37965 + & HDR_MANIP_IPV6_DST)
37966 + tableSize += HMCD_IPV6_ADDR_SIZE;
37967 + break;
37968 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
37969 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
37970 + == HDR_MANIP_TCP_UDP_CHECKSUM)
37971 + /* we implement this case with the update-checksum descriptor */
37972 + tableSize += HMCD_BASIC_SIZE;
37973 + else
37974 + /* we implement this case with the TCP/UDP-update descriptor */
37975 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
37976 + break;
37977 + default:
37978 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37979 + ("Unknown fieldUpdateParams.type"));
37980 + }
37981 + }
37982 +
37983 + if (p_FmPcdManipParams->u.hdr.custom)
37984 + {
37985 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
37986 + {
37987 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
37988 + {
37989 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE;
37990 + dataSize +=
37991 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
37992 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
37993 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
37994 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
37995 + dataSize += 2;
37996 + }
37997 + break;
37998 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
37999 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
38000 + break;
38001 + default:
38002 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38003 + ("Unknown customParams.type"));
38004 + }
38005 + }
38006 +
38007 + *p_TableSize = tableSize;
38008 + *p_DataSize = dataSize;
38009 +
38010 + return E_OK;
38011 +}
38012 +
38013 +static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo,
38014 + uint8_t *parseArrayOffset)
38015 +{
38016 + e_NetHeaderType hdr = p_HdrInfo->hdr;
38017 + e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex;
38018 + bool byField = p_HdrInfo->byField;
38019 + t_FmPcdFields field;
38020 +
38021 + if (byField)
38022 + field = p_HdrInfo->fullField;
38023 +
38024 + if (byField)
38025 + {
38026 + switch (hdr)
38027 + {
38028 + case (HEADER_TYPE_ETH):
38029 + switch (field.eth)
38030 + {
38031 + case (NET_HEADER_FIELD_ETH_TYPE):
38032 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
38033 + break;
38034 + default:
38035 + RETURN_ERROR(
38036 + MAJOR,
38037 + E_NOT_SUPPORTED,
38038 + ("Header manipulation of the type Ethernet with this field not supported"));
38039 + }
38040 + break;
38041 + case (HEADER_TYPE_VLAN):
38042 + switch (field.vlan)
38043 + {
38044 + case (NET_HEADER_FIELD_VLAN_TCI):
38045 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38046 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38047 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
38048 + else
38049 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
38050 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
38051 + break;
38052 + default:
38053 + RETURN_ERROR(
38054 + MAJOR,
38055 + E_NOT_SUPPORTED,
38056 + ("Header manipulation of the type VLAN with this field not supported"));
38057 + }
38058 + break;
38059 + default:
38060 + RETURN_ERROR(
38061 + MAJOR,
38062 + E_NOT_SUPPORTED,
38063 + ("Header manipulation of this header by field not supported"));
38064 + }
38065 + }
38066 + else
38067 + {
38068 + switch (hdr)
38069 + {
38070 + case (HEADER_TYPE_ETH):
38071 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
38072 + break;
38073 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
38074 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
38075 + break;
38076 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
38077 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
38078 + break;
38079 + case (HEADER_TYPE_LLC_SNAP):
38080 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
38081 + break;
38082 + case (HEADER_TYPE_PPPoE):
38083 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
38084 + break;
38085 + case (HEADER_TYPE_MPLS):
38086 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38087 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38088 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
38089 + else
38090 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
38091 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
38092 + break;
38093 + case (HEADER_TYPE_IPv4):
38094 + case (HEADER_TYPE_IPv6):
38095 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38096 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38097 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
38098 + else
38099 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
38100 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
38101 + break;
38102 + case (HEADER_TYPE_MINENCAP):
38103 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
38104 + break;
38105 + case (HEADER_TYPE_GRE):
38106 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
38107 + break;
38108 + case (HEADER_TYPE_TCP):
38109 + case (HEADER_TYPE_UDP):
38110 + case (HEADER_TYPE_IPSEC_AH):
38111 + case (HEADER_TYPE_IPSEC_ESP):
38112 + case (HEADER_TYPE_DCCP):
38113 + case (HEADER_TYPE_SCTP):
38114 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
38115 + break;
38116 + case (HEADER_TYPE_CAPWAP):
38117 + case (HEADER_TYPE_CAPWAP_DTLS):
38118 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
38119 + break;
38120 + default:
38121 + RETURN_ERROR(
38122 + MAJOR,
38123 + E_NOT_SUPPORTED,
38124 + ("Header manipulation of this header is not supported"));
38125 + }
38126 + }
38127 + return E_OK;
38128 +}
38129 +
38130 +static t_Error BuildHmct(t_FmPcdManip *p_Manip,
38131 + t_FmPcdManipParams *p_FmPcdManipParams,
38132 + uint8_t *p_DestHmct, uint8_t *p_DestData, bool new)
38133 +{
38134 + uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData;
38135 + uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr;
38136 + uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData =
38137 + p_DestData;
38138 + t_Handle h_FmPcd = p_Manip->h_FmPcd;
38139 + uint8_t j = 0;
38140 +
38141 + if (p_FmPcdManipParams->u.hdr.rmv)
38142 + {
38143 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38144 + == e_FM_PCD_MANIP_RMV_GENERIC)
38145 + {
38146 + /* initialize HMCD */
38147 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT;
38148 + /* tmp, should be conditional */
38149 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset
38150 + << HMCD_RMV_OFFSET_SHIFT;
38151 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size
38152 + << HMCD_RMV_SIZE_SHIFT;
38153 + }
38154 + else
38155 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38156 + == e_FM_PCD_MANIP_RMV_BY_HDR)
38157 + {
38158 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
38159 + {
38160 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
38161 + {
38162 + uint8_t hmcdOpt;
38163 +
38164 + /* initialize HMCD */
38165 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT;
38166 +
38167 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2)
38168 + {
38169 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET):
38170 + hmcdOpt = HMCD_RMV_L2_ETHERNET;
38171 + break;
38172 + case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS):
38173 + hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS;
38174 + break;
38175 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS):
38176 + hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS;
38177 + break;
38178 + case (e_FM_PCD_MANIP_HDR_RMV_MPLS):
38179 + hmcdOpt = HMCD_RMV_L2_MPLS;
38180 + break;
38181 + case (e_FM_PCD_MANIP_HDR_RMV_PPPOE):
38182 + hmcdOpt = HMCD_RMV_L2_PPPOE;
38183 + break;
38184 + default:
38185 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38186 + }
38187 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38188 + break;
38189 + }
38190 +#if (DPAA_VERSION >= 11)
38191 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
38192 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV)
38193 + << HMCD_OC_SHIFT;
38194 + break;
38195 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
38196 + {
38197 + uint8_t prsArrayOffset;
38198 + t_Error err = E_OK;
38199 +
38200 + tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL)
38201 + << HMCD_OC_SHIFT;
38202 +
38203 + err =
38204 + GetPrOffsetByHeaderOrField(
38205 + &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
38206 + &prsArrayOffset);
38207 + ASSERT_COND(!err);
38208 + /* was previously checked */
38209 +
38210 + tmpReg |= ((uint32_t)prsArrayOffset << 16);
38211 + }
38212 + break;
38213 +#endif /* (DPAA_VERSION >= 11) */
38214 + default:
38215 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38216 + ("manip header remove by hdr type!"));
38217 + }
38218 + }
38219 +
38220 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38221 + /* save a pointer to the "last" indication word */
38222 + p_Last = p_TmpHmct;
38223 + /* advance to next command */
38224 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38225 + }
38226 +
38227 + if (p_FmPcdManipParams->u.hdr.insrt)
38228 + {
38229 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38230 + == e_FM_PCD_MANIP_INSRT_GENERIC)
38231 + {
38232 + /* initialize HMCD */
38233 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace)
38234 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE)
38235 + << HMCD_OC_SHIFT;
38236 + else
38237 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT;
38238 +
38239 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset
38240 + << HMCD_INSRT_OFFSET_SHIFT;
38241 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
38242 + << HMCD_INSRT_SIZE_SHIFT;
38243 +
38244 + size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
38245 + p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data;
38246 +
38247 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38248 + /* save a pointer to the "last" indication word */
38249 + p_Last = p_TmpHmct;
38250 +
38251 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38252 +
38253 + /* initialize data to be inserted */
38254 + /* if size is not a multiple of 4, padd with 0's */
38255 + origSize = size;
38256 + remain = (uint8_t)(size % 4);
38257 + if (remain)
38258 + {
38259 + size += (uint8_t)(4 - remain);
38260 + p_LocalData = (uint32_t *)XX_Malloc(size);
38261 + memset((uint8_t *)p_LocalData, 0, size);
38262 + memcpy((uint8_t *)p_LocalData, p_UsrData, origSize);
38263 + }
38264 + else
38265 + p_LocalData = (uint32_t*)p_UsrData;
38266 +
38267 + /* initialize data and advance pointer to next command */
38268 + MemCpy8(p_TmpHmct, p_LocalData, size);
38269 + p_TmpHmct += size / sizeof(uint32_t);
38270 +
38271 + if (remain)
38272 + XX_Free(p_LocalData);
38273 + }
38274 +
38275 + else
38276 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38277 + == e_FM_PCD_MANIP_INSRT_BY_HDR)
38278 + {
38279 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
38280 + {
38281 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
38282 + {
38283 + uint8_t hmcdOpt;
38284 +
38285 + /* initialize HMCD */
38286 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT)
38287 + << HMCD_OC_SHIFT;
38288 +
38289 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
38290 + {
38291 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
38292 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update)
38293 + hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS;
38294 + else
38295 + hmcdOpt = HMCD_INSRT_L2_MPLS;
38296 + break;
38297 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
38298 + hmcdOpt = HMCD_INSRT_L2_PPPOE;
38299 + break;
38300 + default:
38301 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38302 + }
38303 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38304 +
38305 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38306 + /* save a pointer to the "last" indication word */
38307 + p_Last = p_TmpHmct;
38308 +
38309 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38310 +
38311 + /* set size and pointer of user's data */
38312 + size =
38313 + (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
38314 +
38315 + ASSERT_COND(p_TmpData);
38316 + MemCpy8(
38317 + p_TmpData,
38318 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data,
38319 + size);
38320 + tmpReg =
38321 + (size << HMCD_INSRT_L2_SIZE_SHIFT)
38322 + | (uint32_t)(XX_VirtToPhys(p_TmpData)
38323 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38324 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38325 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38326 + p_TmpData += size;
38327 + }
38328 + break;
38329 +#if (DPAA_VERSION >= 11)
38330 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
38331 + tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT)
38332 + << HMCD_OC_SHIFT;
38333 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum)
38334 + tmpReg |= HMCD_IP_L4_CS_CALC;
38335 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode
38336 + == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS)
38337 + tmpReg |= HMCD_IP_OR_QOS;
38338 + tmpReg |=
38339 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset
38340 + & HMCD_IP_LAST_PID_MASK;
38341 + tmpReg |=
38342 + ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38343 + << HMCD_IP_SIZE_SHIFT)
38344 + & HMCD_IP_SIZE_MASK);
38345 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite)
38346 + tmpReg |= HMCD_IP_DF_MODE;
38347 +
38348 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38349 +
38350 + /* save a pointer to the "last" indication word */
38351 + p_Last = p_TmpHmct;
38352 +
38353 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38354 +
38355 + /* set IP id */
38356 + ASSERT_COND(p_TmpData);
38357 + WRITE_UINT16(
38358 + *(uint16_t*)p_TmpData,
38359 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id);
38360 + WRITE_UINT32(
38361 + *p_TmpHmct,
38362 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38363 + p_TmpData += 2;
38364 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38365 +
38366 + WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset);
38367 + p_TmpHmct += HMCD_PARAM_SIZE / 4;
38368 +
38369 + MemCpy8(
38370 + p_TmpHmct,
38371 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data,
38372 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
38373 + p_TmpHmct +=
38374 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38375 + / 4;
38376 + break;
38377 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
38378 + tmpReg = HMCD_INSRT_UDP_LITE;
38379 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
38380 + tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT)
38381 + << HMCD_OC_SHIFT;
38382 +
38383 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38384 +
38385 + /* save a pointer to the "last" indication word */
38386 + p_Last = p_TmpHmct;
38387 +
38388 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38389 +
38390 + MemCpy8(
38391 + p_TmpHmct,
38392 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38393 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38394 + p_TmpHmct +=
38395 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38396 + / 4;
38397 + break;
38398 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
38399 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT)
38400 + << HMCD_OC_SHIFT;
38401 + tmpReg |= HMCD_CAPWAP_INSRT;
38402 +
38403 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38404 +
38405 + /* save a pointer to the "last" indication word */
38406 + p_Last = p_TmpHmct;
38407 +
38408 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38409 +
38410 + MemCpy8(
38411 + p_TmpHmct,
38412 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38413 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38414 + p_TmpHmct +=
38415 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38416 + / 4;
38417 + break;
38418 +#endif /* (DPAA_VERSION >= 11) */
38419 + default:
38420 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38421 + ("manip header insert by header type!"));
38422 +
38423 + }
38424 + }
38425 + }
38426 +
38427 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
38428 + {
38429 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
38430 + {
38431 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
38432 + /* set opcode */
38433 + tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE)
38434 + << HMCD_OC_SHIFT;
38435 +
38436 + /* set mode & table pointer */
38437 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38438 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
38439 + {
38440 + /* set Mode */
38441 + tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI)
38442 + << HMCD_VLAN_PRI_REP_MODE_SHIFT;
38443 + /* set VPRI default */
38444 + tmpReg |=
38445 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal;
38446 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38447 + /* save a pointer to the "last" indication word */
38448 + p_Last = p_TmpHmct;
38449 + /* write the table pointer into the Manip descriptor */
38450 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38451 +
38452 + tmpReg = 0;
38453 + ASSERT_COND(p_TmpData);
38454 + for (i = 0; i < HMCD_DSCP_VALUES; i++)
38455 + {
38456 + /* first we build from each 8 values a 32bit register */
38457 + tmpReg |=
38458 + (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i])
38459 + << (32 - 4 * (j + 1));
38460 + j++;
38461 + /* Than we write this register to the next table word
38462 + * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */
38463 + if ((i % 8) == 7)
38464 + {
38465 + WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1),
38466 + tmpReg);
38467 + tmpReg = 0;
38468 + j = 0;
38469 + }
38470 + }
38471 +
38472 + WRITE_UINT32(
38473 + *p_TmpHmct,
38474 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38475 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38476 +
38477 + p_TmpData += DSCP_TO_VLAN_TABLE_SIZE;
38478 + }
38479 + else
38480 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38481 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
38482 + {
38483 + /* set Mode */
38484 + /* line commented out as it has no-side-effect ('0' value). */
38485 + /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/;
38486 + /* set VPRI parameter */
38487 + tmpReg |=
38488 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri;
38489 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38490 + /* save a pointer to the "last" indication word */
38491 + p_Last = p_TmpHmct;
38492 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38493 + }
38494 + break;
38495 +
38496 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
38497 + /* set opcode */
38498 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT;
38499 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38500 + & HDR_MANIP_IPV4_TTL)
38501 + tmpReg |= HMCD_IPV4_UPDATE_TTL;
38502 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38503 + & HDR_MANIP_IPV4_TOS)
38504 + {
38505 + tmpReg |= HMCD_IPV4_UPDATE_TOS;
38506 + tmpReg |=
38507 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos
38508 + << HMCD_IPV4_UPDATE_TOS_SHIFT;
38509 + }
38510 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38511 + & HDR_MANIP_IPV4_ID)
38512 + tmpReg |= HMCD_IPV4_UPDATE_ID;
38513 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38514 + & HDR_MANIP_IPV4_SRC)
38515 + tmpReg |= HMCD_IPV4_UPDATE_SRC;
38516 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38517 + & HDR_MANIP_IPV4_DST)
38518 + tmpReg |= HMCD_IPV4_UPDATE_DST;
38519 + /* write the first 4 bytes of the descriptor */
38520 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38521 + /* save a pointer to the "last" indication word */
38522 + p_Last = p_TmpHmct;
38523 +
38524 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38525 +
38526 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38527 + & HDR_MANIP_IPV4_ID)
38528 + {
38529 + ASSERT_COND(p_TmpData);
38530 + WRITE_UINT16(
38531 + *(uint16_t*)p_TmpData,
38532 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id);
38533 + WRITE_UINT32(
38534 + *p_TmpHmct,
38535 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38536 + p_TmpData += 2;
38537 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38538 + }
38539 +
38540 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38541 + & HDR_MANIP_IPV4_SRC)
38542 + {
38543 + WRITE_UINT32(
38544 + *p_TmpHmct,
38545 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src);
38546 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38547 + }
38548 +
38549 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38550 + & HDR_MANIP_IPV4_DST)
38551 + {
38552 + WRITE_UINT32(
38553 + *p_TmpHmct,
38554 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst);
38555 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38556 + }
38557 + break;
38558 +
38559 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
38560 + /* set opcode */
38561 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT;
38562 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38563 + & HDR_MANIP_IPV6_HL)
38564 + tmpReg |= HMCD_IPV6_UPDATE_HL;
38565 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38566 + & HDR_MANIP_IPV6_TC)
38567 + {
38568 + tmpReg |= HMCD_IPV6_UPDATE_TC;
38569 + tmpReg |=
38570 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass
38571 + << HMCD_IPV6_UPDATE_TC_SHIFT;
38572 + }
38573 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38574 + & HDR_MANIP_IPV6_SRC)
38575 + tmpReg |= HMCD_IPV6_UPDATE_SRC;
38576 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38577 + & HDR_MANIP_IPV6_DST)
38578 + tmpReg |= HMCD_IPV6_UPDATE_DST;
38579 + /* write the first 4 bytes of the descriptor */
38580 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38581 + /* save a pointer to the "last" indication word */
38582 + p_Last = p_TmpHmct;
38583 +
38584 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38585 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38586 + & HDR_MANIP_IPV6_SRC)
38587 + {
38588 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38589 + {
38590 + memcpy(&tmp_ipv6_addr,
38591 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i],
38592 + sizeof(uint32_t));
38593 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38594 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38595 + }
38596 + }
38597 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38598 + & HDR_MANIP_IPV6_DST)
38599 + {
38600 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38601 + {
38602 + memcpy(&tmp_ipv6_addr,
38603 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i],
38604 + sizeof(uint32_t));
38605 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38606 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38607 + }
38608 + }
38609 + break;
38610 +
38611 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
38612 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38613 + == HDR_MANIP_TCP_UDP_CHECKSUM)
38614 + {
38615 + /* we implement this case with the update-checksum descriptor */
38616 + /* set opcode */
38617 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM)
38618 + << HMCD_OC_SHIFT;
38619 + /* write the first 4 bytes of the descriptor */
38620 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38621 + /* save a pointer to the "last" indication word */
38622 + p_Last = p_TmpHmct;
38623 +
38624 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38625 + }
38626 + else
38627 + {
38628 + /* we implement this case with the TCP/UDP update descriptor */
38629 + /* set opcode */
38630 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE)
38631 + << HMCD_OC_SHIFT;
38632 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38633 + & HDR_MANIP_TCP_UDP_DST)
38634 + tmpReg |= HMCD_TCP_UDP_UPDATE_DST;
38635 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38636 + & HDR_MANIP_TCP_UDP_SRC)
38637 + tmpReg |= HMCD_TCP_UDP_UPDATE_SRC;
38638 + /* write the first 4 bytes of the descriptor */
38639 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38640 + /* save a pointer to the "last" indication word */
38641 + p_Last = p_TmpHmct;
38642 +
38643 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38644 +
38645 + tmpReg = 0;
38646 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38647 + & HDR_MANIP_TCP_UDP_SRC)
38648 + tmpReg |=
38649 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src)
38650 + << HMCD_TCP_UDP_UPDATE_SRC_SHIFT;
38651 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38652 + & HDR_MANIP_TCP_UDP_DST)
38653 + tmpReg |=
38654 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst);
38655 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38656 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38657 + }
38658 + break;
38659 +
38660 + default:
38661 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38662 + ("Unknown fieldUpdateParams.type"));
38663 + }
38664 + }
38665 +
38666 + if (p_FmPcdManipParams->u.hdr.custom)
38667 + {
38668 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
38669 + {
38670 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
38671 + /* set opcode */
38672 + tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT;
38673 +
38674 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl)
38675 + tmpReg |= HMCD_IP_REPLACE_TTL_HL;
38676 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38677 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6)
38678 + /* line commented out as it has no-side-effect ('0' value). */
38679 + /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/;
38680 + else
38681 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38682 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38683 + {
38684 + tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6;
38685 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)
38686 + tmpReg |= HMCD_IP_REPLACE_ID;
38687 + }
38688 + else
38689 + RETURN_ERROR(
38690 + MINOR,
38691 + E_NOT_SUPPORTED,
38692 + ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set."));
38693 +
38694 + /* write the first 4 bytes of the descriptor */
38695 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38696 + /* save a pointer to the "last" indication word */
38697 + p_Last = p_TmpHmct;
38698 +
38699 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38700 +
38701 + size =
38702 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
38703 + ASSERT_COND(p_TmpData);
38704 + MemCpy8(
38705 + p_TmpData,
38706 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr,
38707 + size);
38708 + tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT);
38709 + tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData)
38710 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38711 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38712 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38713 + p_TmpData += size;
38714 +
38715 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38716 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38717 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
38718 + {
38719 + WRITE_UINT16(
38720 + *(uint16_t*)p_TmpData,
38721 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id);
38722 + WRITE_UINT32(
38723 + *p_TmpHmct,
38724 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38725 + p_TmpData += 2;
38726 + }
38727 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38728 + break;
38729 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
38730 + /* set opcode */
38731 + tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT;
38732 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT;
38733 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT;
38734 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT;
38735 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38736 + tmpReg |= HMCD_GEN_FIELD_MASK_EN;
38737 +
38738 + /* write the first 4 bytes of the descriptor */
38739 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38740 + /* save a pointer to the "last" indication word */
38741 + p_Last = p_TmpHmct;
38742 +
38743 + p_TmpHmct += HMCD_BASIC_SIZE/4;
38744 +
38745 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38746 + {
38747 + tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT;
38748 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT;
38749 + /* write the next 4 bytes of the descriptor */
38750 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38751 + }
38752 + p_TmpHmct += HMCD_PARAM_SIZE/4;
38753 + break;
38754 + default:
38755 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38756 + ("Unknown customParams.type"));
38757 + }
38758 + }
38759 +
38760 + /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table
38761 + the old table and should be freed */
38762 + if (p_FmPcdManipParams->h_NextManip
38763 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
38764 + && (MANIP_DONT_REPARSE(p_Manip)))
38765 + {
38766 + if (new)
38767 + {
38768 + /* If this is the first time this manip is created we need to free unused memory. If it
38769 + * is a dynamic changes case, the memory used is either the CC shadow or the existing
38770 + * table - no allocation, no free */
38771 + MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip);
38772 +
38773 + p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST;
38774 + }
38775 + }
38776 + else
38777 + {
38778 + ASSERT_COND(p_Last);
38779 + /* set the "last" indication on the last command of the current table */
38780 + WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST);
38781 + }
38782 +
38783 + return E_OK;
38784 +}
38785 +
38786 +static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip,
38787 + t_FmPcdManipParams *p_FmPcdManipParams)
38788 +{
38789 + t_FmPcdManip *p_CurManip;
38790 + t_Error err;
38791 + uint32_t nextSize = 0, totalSize;
38792 + uint16_t tmpReg;
38793 + uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr;
38794 +
38795 + /* set Manip structure */
38796 +
38797 + p_Manip->dontParseAfterManip =
38798 + p_FmPcdManipParams->u.hdr.dontParseAfterManip;
38799 +
38800 + if (p_FmPcdManipParams->h_NextManip)
38801 + { /* Next Header manipulation exists */
38802 + p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip);
38803 +
38804 + if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip)
38805 + nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip)
38806 + + GetDataSize(p_FmPcdManipParams->h_NextManip));
38807 + else /* either parsing is required or next manip is Frag; no table merging. */
38808 + p_Manip->cascaded = TRUE;
38809 + /* pass up the "cascaded" attribute. The whole chain is cascaded
38810 + * if something is cascaded along the way. */
38811 + if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip))
38812 + p_Manip->cascaded = TRUE;
38813 + }
38814 +
38815 + /* Allocate new table */
38816 + /* calculate table size according to manip parameters */
38817 + err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize,
38818 + &p_Manip->dataSize);
38819 + if (err)
38820 + RETURN_ERROR(MINOR, err, NO_MSG);
38821 +
38822 + totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize);
38823 +
38824 + p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem(
38825 + ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4);
38826 + if (!p_Manip->p_Hmct)
38827 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed"));
38828 +
38829 + if (p_Manip->dataSize)
38830 + p_Manip->p_Data =
38831 + (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize));
38832 +
38833 + /* update shadow size to allow runtime replacement of Header manipulation */
38834 + /* The allocated shadow is divided as follows:
38835 + 0 . . . 16 . . .
38836 + --------------------------------
38837 + | Shadow | Shadow HMTD |
38838 + | HMTD | Match Table |
38839 + | (16 bytes) | (maximal size) |
38840 + --------------------------------
38841 + */
38842 +
38843 + err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16),
38844 + (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN);
38845 + if (err != E_OK)
38846 + {
38847 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
38848 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
38849 + ("MURAM allocation for HdrManip node shadow"));
38850 + }
38851 +
38852 + if (p_FmPcdManipParams->h_NextManip
38853 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
38854 + && (MANIP_DONT_REPARSE(p_Manip)))
38855 + {
38856 + p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip,
38857 + e_MANIP_HMCT);
38858 + p_CurManip = p_FmPcdManipParams->h_NextManip;
38859 + /* Run till the last Manip (which is the first to configure) */
38860 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
38861 + p_CurManip = p_CurManip->h_NextManip;
38862 +
38863 + while (p_CurManip)
38864 + {
38865 + /* If this is a unified table, point to the part of the table
38866 + * which is the relative offset in HMCT.
38867 + */
38868 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
38869 + (p_Manip->tableSize +
38870 + (PTR_TO_UINT(p_CurManip->p_Hmct) -
38871 + PTR_TO_UINT(p_OldHmct))));
38872 + if (p_CurManip->p_Data)
38873 + p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
38874 + (p_Manip->tableSize +
38875 + (PTR_TO_UINT(p_CurManip->p_Data) -
38876 + PTR_TO_UINT(p_OldHmct))));
38877 + else
38878 + p_TmpDataPtr = NULL;
38879 +
38880 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
38881 + p_TmpDataPtr, FALSE);
38882 + /* update old manip table pointer */
38883 + MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr);
38884 + MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr);
38885 +
38886 + p_CurManip = p_CurManip->h_PrevManip;
38887 + }
38888 + /* We copied the HMCT to create a new large HMCT so we can free the old one */
38889 + FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip),
38890 + p_OldHmct);
38891 + }
38892 +
38893 + /* Fill table */
38894 + err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct,
38895 + p_Manip->p_Data, TRUE);
38896 + if (err)
38897 + {
38898 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
38899 + RETURN_ERROR(MINOR, err, NO_MSG);
38900 + }
38901 +
38902 + /* Build HMTD (table descriptor) */
38903 + tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */
38904 +
38905 + /* add parseAfterManip */
38906 + if (!p_Manip->dontParseAfterManip)
38907 + tmpReg |= HMTD_CFG_PRS_AFTER_HM;
38908 +
38909 + /* create cascade */
38910 + /*if (p_FmPcdManipParams->h_NextManip
38911 + && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/
38912 + if (p_Manip->cascaded)
38913 + {
38914 + uint16_t nextAd;
38915 + /* indicate that there's another HM table descriptor */
38916 + tmpReg |= HMTD_CFG_NEXT_AD_EN;
38917 + /* get address of next HMTD (table descriptor; h_Ad).
38918 + * If the next HMTD was removed due to table unifing, get the address
38919 + * of the "next next" as written in the h_Ad of the next h_Manip node.
38920 + */
38921 + if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST)
38922 + nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
38923 + else
38924 + nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx;
38925 +
38926 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd);
38927 + }
38928 +
38929 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg);
38930 + WRITE_UINT32(
38931 + ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr,
38932 + (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38933 +
38934 + WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC);
38935 +
38936 + if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST)
38937 + {
38938 + /* The HMTD of the next Manip is never going to be used */
38939 + if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate)
38940 + FM_MURAM_FreeMem(
38941 + ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram,
38942 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
38943 + else
38944 + XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
38945 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL;
38946 + }
38947 +
38948 + return E_OK;
38949 +}
38950 +
38951 +static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip,
38952 + t_FmPcdManipParams *p_FmPcdManipParams)
38953 +{
38954 + uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL;
38955 + uint16_t newSize;
38956 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
38957 + t_Error err;
38958 + t_FmPcdManip *p_CurManip = p_Manip;
38959 +
38960 + err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize);
38961 + if (err)
38962 + RETURN_ERROR(MINOR, err, NO_MSG);
38963 +
38964 + /* check coherency of new table parameters */
38965 + if (newSize > p_Manip->tableSize)
38966 + RETURN_ERROR(
38967 + MINOR,
38968 + E_INVALID_VALUE,
38969 + ("New Hdr Manip configuration requires larger size than current one (command table)."));
38970 + if (newDataSize > p_Manip->dataSize)
38971 + RETURN_ERROR(
38972 + MINOR,
38973 + E_INVALID_VALUE,
38974 + ("New Hdr Manip configuration requires larger size than current one (data)."));
38975 + if (p_FmPcdManipParams->h_NextManip)
38976 + RETURN_ERROR(
38977 + MINOR, E_INVALID_VALUE,
38978 + ("New Hdr Manip configuration can not contain h_NextManip."));
38979 + if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize))
38980 + RETURN_ERROR(
38981 + MINOR,
38982 + E_INVALID_VALUE,
38983 + ("New Hdr Manip configuration in a chained manipulation requires different size than current one."));
38984 + if (p_Manip->dontParseAfterManip
38985 + != p_FmPcdManipParams->u.hdr.dontParseAfterManip)
38986 + RETURN_ERROR(
38987 + MINOR,
38988 + E_INVALID_VALUE,
38989 + ("New Hdr Manip configuration differs in dontParseAfterManip value."));
38990 +
38991 + p_Manip->tableSize = newSize;
38992 + p_Manip->dataSize = newDataSize;
38993 +
38994 + /* Build the new table in the shadow */
38995 + if (!MANIP_IS_UNIFIED(p_Manip))
38996 + {
38997 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
38998 + if (p_Manip->p_Data)
38999 + p_TmpDataPtr =
39000 + (uint8_t*)PTR_MOVE(p_TmpHmctPtr,
39001 + (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct)));
39002 +
39003 + BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data,
39004 + FALSE);
39005 + }
39006 + else
39007 + {
39008 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
39009 + ASSERT_COND(p_WholeHmct);
39010 +
39011 + /* Run till the last Manip (which is the first to configure) */
39012 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39013 + p_CurManip = p_CurManip->h_NextManip;
39014 +
39015 + while (p_CurManip)
39016 + {
39017 + /* If this is a non-head node in a unified table, point to the part of the shadow
39018 + * which is the relative offset in HMCT.
39019 + * else, point to the beginning of the
39020 + * shadow table (we save 16 for the HMTD.
39021 + */
39022 + p_TmpHmctPtr =
39023 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
39024 + (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct)));
39025 + if (p_CurManip->p_Data)
39026 + p_TmpDataPtr =
39027 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
39028 + (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct)));
39029 +
39030 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39031 + p_TmpDataPtr, FALSE);
39032 + p_CurManip = p_CurManip->h_PrevManip;
39033 + }
39034 + }
39035 +
39036 + return E_OK;
39037 +}
39038 +
39039 +static t_Error CreateManipActionBackToOrig(
39040 + t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams)
39041 +{
39042 + uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr;
39043 + t_FmPcdManip *p_CurManip = p_Manip;
39044 +
39045 + /* Build the new table in the shadow */
39046 + if (!MANIP_IS_UNIFIED(p_Manip))
39047 + BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data,
39048 + FALSE);
39049 + else
39050 + {
39051 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
39052 + ASSERT_COND(p_WholeHmct);
39053 +
39054 + /* Run till the last Manip (which is the first to configure) */
39055 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39056 + p_CurManip = p_CurManip->h_NextManip;
39057 +
39058 + while (p_CurManip)
39059 + {
39060 + /* If this is a unified table, point to the part of the table
39061 + * which is the relative offset in HMCT.
39062 + */
39063 + p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/
39064 + p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/
39065 +
39066 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39067 + p_TmpDataPtr, FALSE);
39068 +
39069 + p_CurManip = p_CurManip->h_PrevManip;
39070 + }
39071 + }
39072 +
39073 + return E_OK;
39074 +}
39075 +
39076 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
39077 +static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
39078 +{
39079 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
39080 + t_Handle p_Ad;
39081 + uint32_t tmpReg32 = 0;
39082 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
39083 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
39084 +
39085 + switch (p_Manip->opcode)
39086 + {
39087 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
39088 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
39089 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
39090 + {
39091 + tmpReg32 =
39092 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
39093 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
39094 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets =
39095 + tmpReg32;
39096 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
39097 + p_Manip->icOffset = icOffset;
39098 + }
39099 + else
39100 + {
39101 + if (p_Manip->icOffset != icOffset)
39102 + RETURN_ERROR(
39103 + MAJOR,
39104 + E_INVALID_VALUE,
39105 + ("this manipulation was updated previously by different value"););
39106 + }
39107 + break;
39108 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
39109 + if (p_Manip->h_Frag)
39110 + {
39111 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
39112 + {
39113 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
39114 + tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
39115 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
39116 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
39117 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
39118 + p_Manip->icOffset = icOffset;
39119 + }
39120 + else
39121 + {
39122 + if (p_Manip->icOffset != icOffset)
39123 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
39124 + }
39125 + }
39126 + break;
39127 + }
39128 +
39129 + return E_OK;
39130 +}
39131 +
39132 +static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(
39133 + t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
39134 +{
39135 +
39136 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39137 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39138 + t_Error err;
39139 + uint32_t tmpReg32;
39140 +
39141 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39142 +
39143 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
39144 + SANITY_CHECK_RETURN_ERROR(
39145 + (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX),
39146 + E_INVALID_STATE);
39147 + SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
39148 +
39149 + if (p_Manip->updateParams)
39150 + {
39151 + if ((!(p_Manip->updateParams & OFFSET_OF_PR))
39152 + || (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39153 + RETURN_ERROR(
39154 + MAJOR, E_INVALID_STATE,
39155 + ("in this stage parameters from Port has not be updated"));
39156 +
39157 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39158 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39159 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39160 +
39161 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39162 + if (err)
39163 + RETURN_ERROR(MAJOR, err, NO_MSG);
39164 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39165 + RETURN_ERROR(
39166 + MAJOR, E_INVALID_STATE,
39167 + ("Parser result offset wasn't configured previousely"));
39168 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39169 + ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
39170 +#endif
39171 + }
39172 + else
39173 + if (validate)
39174 + {
39175 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39176 + || (p_Manip->updateParams & OFFSET_OF_PR))
39177 + RETURN_ERROR(
39178 + MAJOR, E_INVALID_STATE,
39179 + ("in this stage parameters from Port has be updated"));
39180 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39181 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39182 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39183 +
39184 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39185 + if (err)
39186 + RETURN_ERROR(MAJOR, err, NO_MSG);
39187 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39188 + RETURN_ERROR(
39189 + MAJOR, E_INVALID_STATE,
39190 + ("Parser result offset wasn't configured previousely"));
39191 +
39192 + }
39193 +
39194 + ASSERT_COND(p_Ad);
39195 +
39196 + if (p_Manip->updateParams & OFFSET_OF_PR)
39197 + {
39198 + tmpReg32 = 0;
39199 + tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
39200 + WRITE_UINT32(p_Ad->matchTblPtr,
39201 + (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
39202 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39203 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39204 + }
39205 + else
39206 + if (validate)
39207 + {
39208 + tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
39209 + if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
39210 + RETURN_ERROR(
39211 + MAJOR,
39212 + E_INVALID_STATE,
39213 + ("this manipulation was updated previousely by different value"););
39214 + }
39215 +
39216 + return E_OK;
39217 +}
39218 +
39219 +static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
39220 +{
39221 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39222 + t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL;
39223 + uint32_t tmpReg32 = 0;
39224 +
39225 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39226 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39227 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39228 + 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);
39229 +
39230 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39231 +
39232 + if (p_Manip->updateParams)
39233 + {
39234 +
39235 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39236 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39237 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39238 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39239 + if (!p_SavedManipParams)
39240 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39241 + p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
39242 +
39243 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39244 + tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16);
39245 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39246 +
39247 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39248 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39249 + }
39250 + else if (validate)
39251 + {
39252 +
39253 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39254 + if (!p_SavedManipParams)
39255 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39256 + if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset)
39257 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39258 + }
39259 +
39260 + return E_OK;
39261 +}
39262 +
39263 +static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort,
39264 + t_FmPcdManip *p_Manip,
39265 + t_Handle h_Ad,
39266 + bool validate,
39267 + t_Handle h_FmTree)
39268 +{
39269 + t_AdOfTypeContLookup *p_Ad;
39270 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39271 + t_Error err;
39272 + uint32_t tmpReg32 = 0;
39273 + t_FmPcdCcSavedManipParams *p_SavedManipParams;
39274 +
39275 + UNUSED(h_Ad);
39276 +
39277 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39278 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39279 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39280 + SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) ||
39281 + (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
39282 +
39283 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39284 +
39285 + if (p_Manip->updateParams)
39286 + {
39287 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39288 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39289 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39290 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39291 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39292 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39293 + /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */
39294 + fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1;
39295 +
39296 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39297 + if (err)
39298 + RETURN_ERROR(MAJOR, err, NO_MSG);
39299 +
39300 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39301 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39302 +
39303 + p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
39304 + p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39305 +
39306 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39307 + ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
39308 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39309 +
39310 + FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams);
39311 + }
39312 + else if (validate)
39313 + {
39314 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) ||
39315 + ((p_Manip->updateParams & OFFSET_OF_DATA)))
39316 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39317 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39318 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39319 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39320 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39321 + if (err)
39322 + RETURN_ERROR(MAJOR, err, NO_MSG);
39323 +
39324 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39325 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39326 + }
39327 +
39328 + if (p_Manip->updateParams)
39329 + {
39330 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39331 + tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
39332 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39333 +
39334 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39335 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39336 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39337 + }
39338 + else if (validate)
39339 + {
39340 + if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset)
39341 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39342 + }
39343 +
39344 + return E_OK;
39345 +}
39346 +
39347 +static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd,
39348 + t_Handle h_FmPort,
39349 + t_FmPcdManip *p_Manip,
39350 + t_Handle h_Ad,
39351 + bool validate)
39352 +{
39353 + t_CapwapReasmPram *p_ReassmTbl;
39354 + t_Error err;
39355 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39356 + uint8_t i = 0;
39357 + uint16_t size;
39358 + uint32_t tmpReg32;
39359 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
39360 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
39361 +
39362 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39363 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39364 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
39365 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
39366 + SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
39367 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
39368 +
39369 + if (p_Manip->h_FmPcd != h_FmPcd)
39370 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
39371 + ("handler of PCD previously was initiated by different value"));
39372 +
39373 + UNUSED(h_Ad);
39374 +
39375 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39376 + p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag;
39377 +
39378 + if (p_Manip->updateParams)
39379 + {
39380 + if ((!(p_Manip->updateParams & NUM_OF_TASKS) &&
39381 + !(p_Manip->updateParams & OFFSET_OF_DATA) &&
39382 + !(p_Manip->updateParams & OFFSET_OF_PR) &&
39383 + !(p_Manip->updateParams & HW_PORT_ID)) ||
39384 + ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) ||
39385 + (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) ||
39386 + (p_Manip->shadowUpdateParams & HW_PORT_ID)))
39387 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39388 +
39389 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39390 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39391 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39392 +
39393 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39394 + if (err)
39395 + RETURN_ERROR(MAJOR, err, NO_MSG);
39396 +
39397 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39398 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
39399 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39400 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
39401 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39402 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39403 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39404 + ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
39405 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39406 + }
39407 + else if (validate)
39408 + {
39409 + if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) &&
39410 + !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
39411 + !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) &&
39412 + !(p_Manip->shadowUpdateParams & HW_PORT_ID)) &&
39413 + ((p_Manip->updateParams & NUM_OF_TASKS) ||
39414 + (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) ||
39415 + (p_Manip->updateParams & HW_PORT_ID)))
39416 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39417 +
39418 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39419 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39420 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39421 +
39422 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39423 + if (err)
39424 + RETURN_ERROR(MAJOR, err, NO_MSG);
39425 +
39426 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39427 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously"));
39428 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39429 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously"));
39430 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39431 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39432 + }
39433 +
39434 + if (p_Manip->updateParams)
39435 + {
39436 + if (p_Manip->updateParams & NUM_OF_TASKS)
39437 + {
39438 + /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */
39439 + size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks);
39440 + if (size > 255)
39441 + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
39442 +
39443 + p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
39444 +
39445 + /*p_ReassmFrmDescrIndxPoolTbl*/
39446 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl =
39447 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39448 + (uint32_t)(size + 1),
39449 + 4);
39450 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
39451 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table"));
39452 +
39453 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1));
39454 +
39455 + for ( i = 0; i < size; i++)
39456 + WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
39457 +
39458 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
39459 +
39460 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
39461 +
39462 + /*p_ReassmFrmDescrPoolTbl*/
39463 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl =
39464 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39465 + (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
39466 + 4);
39467 +
39468 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
39469 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table"));
39470 +
39471 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
39472 +
39473 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
39474 +
39475 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
39476 +
39477 + /*p_TimeOutTbl*/
39478 +
39479 + p_Manip->capwapFragParams.p_TimeOutTbl =
39480 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39481 + (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
39482 + 4);
39483 +
39484 + if (!p_Manip->capwapFragParams.p_TimeOutTbl)
39485 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table"));
39486 +
39487 + MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
39488 +
39489 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
39490 + WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
39491 +
39492 + p_Manip->updateParams &= ~NUM_OF_TASKS;
39493 + p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
39494 + }
39495 +
39496 + if (p_Manip->updateParams & OFFSET_OF_DATA)
39497 + {
39498 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39499 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39500 + tmpReg32|= p_Manip->capwapFragParams.dataOffset;
39501 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39502 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39503 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39504 + }
39505 +
39506 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39507 + {
39508 + p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
39509 +
39510 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39511 + tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
39512 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39513 +
39514 + tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
39515 + tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24;
39516 + WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
39517 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39518 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39519 + }
39520 + else
39521 + {
39522 + p_Manip->capwapFragParams.prOffset = 0xff;
39523 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39524 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39525 + }
39526 +
39527 + p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
39528 + p_Manip->updateParams &= ~HW_PORT_ID;
39529 + p_Manip->shadowUpdateParams |= HW_PORT_ID;
39530 +
39531 + /*timeout hc */
39532 + ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames;
39533 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24;
39534 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
39535 + ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2;
39536 + return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
39537 + }
39538 +
39539 + else if (validate)
39540 + {
39541 + if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId)
39542 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
39543 + if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks)
39544 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
39545 +
39546 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39547 + {
39548 + if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
39549 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39550 + }
39551 + else
39552 + {
39553 + if (p_Manip->capwapFragParams.prOffset != 0xff)
39554 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39555 + }
39556 + if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset)
39557 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
39558 + }
39559 +
39560 + return E_OK;
39561 +}
39562 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
39563 +
39564 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
39565 +{
39566 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
39567 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 };
39568 + t_Error err = E_OK;
39569 + uint8_t result;
39570 + uint32_t bitFor1Micro, tsbs, log2num;
39571 +
39572 + ASSERT_COND(p_FmPcd);
39573 + ASSERT_COND(h_ReasmCommonPramTbl);
39574 +
39575 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39576 + if (bitFor1Micro == 0)
39577 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39578 +
39579 + bitFor1Micro = 32 - bitFor1Micro;
39580 + LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num);
39581 + tsbs = bitFor1Micro - log2num;
39582 +
39583 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(
39584 + h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
39585 + ccReassmTimeoutParams.tsbs = (uint8_t)tsbs;
39586 + ccReassmTimeoutParams.activate = TRUE;
39587 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams,
39588 + &result)) != E_OK)
39589 + RETURN_ERROR(MAJOR, err, NO_MSG);
39590 +
39591 + switch (result)
39592 + {
39593 + case (0):
39594 + return E_OK;
39595 + case (1):
39596 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM"));
39597 + case (2):
39598 + RETURN_ERROR(
39599 + MAJOR, E_NO_MEMORY,
39600 + ("failed to allocate internal buffer from the HC-Port"));
39601 + case (3):
39602 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
39603 + ("'Disable Timeout Task' with invalid IPRCPT"));
39604 + case (4):
39605 + RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks"));
39606 + case (5):
39607 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command"));
39608 + default:
39609 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
39610 + }
39611 + return E_OK;
39612 +}
39613 +
39614 +static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip)
39615 +{
39616 + uint32_t tmpReg32 = 0, i, bitFor1Micro;
39617 + uint64_t tmpReg64, size;
39618 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
39619 + t_Error err = E_OK;
39620 +
39621 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39622 + if (bitFor1Micro == 0)
39623 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39624 +
39625 + /* Allocation of the Reassembly Common Parameters table. This table is located in the
39626 + MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */
39627 + p_Manip->reassmParams.p_ReassCommonTbl =
39628 + (t_ReassCommonTbl *)FM_MURAM_AllocMem(
39629 + p_FmPcd->h_FmMuram,
39630 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE,
39631 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN);
39632 +
39633 + if (!p_Manip->reassmParams.p_ReassCommonTbl)
39634 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39635 + ("MURAM alloc for Reassembly common parameters table"));
39636 +
39637 + MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0,
39638 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE);
39639 +
39640 + /* Setting the TimeOut Mode.*/
39641 + tmpReg32 = 0;
39642 + if (p_Manip->reassmParams.timeOutMode
39643 + == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
39644 + tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES;
39645 +
39646 + /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID.
39647 + In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/
39648 + tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames;
39649 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid,
39650 + tmpReg32);
39651 +
39652 + /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/
39653 + size = p_Manip->reassmParams.maxNumFramesInProcess + 129;
39654 +
39655 + /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */
39656 + p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr =
39657 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39658 + (uint32_t)(size * 2),
39659 + 256));
39660 + if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
39661 + RETURN_ERROR(
39662 + MAJOR, E_NO_MEMORY,
39663 + ("MURAM alloc for Reassembly frame descriptor indexes pool"));
39664 +
39665 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr),
39666 + 0, (uint32_t)(size * 2));
39667 +
39668 + /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to
39669 + the maximum number of frames that are allowed to be reassembled simultaneously + 128.
39670 + The last entry in this pool must contain the index zero*/
39671 + for (i = 0; i < (size - 1); i++)
39672 + WRITE_UINT16(
39673 + *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)),
39674 + (uint16_t)(i+1));
39675 +
39676 + /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */
39677 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39678 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr))
39679 + - p_FmPcd->physicalMuramBase);
39680 + WRITE_UINT32(
39681 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr,
39682 + tmpReg32);
39683 +
39684 + /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory.
39685 + The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/
39686 + p_Manip->reassmParams.reassFrmDescrPoolTblAddr =
39687 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64));
39688 +
39689 + if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
39690 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39691 +
39692 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0,
39693 + (uint32_t)(size * 64));
39694 +
39695 + /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/
39696 + tmpReg64 = (uint64_t)(XX_VirtToPhys(
39697 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)));
39698 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39699 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39700 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39701 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39702 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39703 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39704 + WRITE_UINT32(
39705 + p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi,
39706 + (uint32_t)(tmpReg64 >> 32));
39707 + WRITE_UINT32(
39708 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow,
39709 + (uint32_t)tmpReg64);
39710 +
39711 + /*Allocation of the TimeOut table - This table resides in the MURAM.
39712 + The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/
39713 + p_Manip->reassmParams.timeOutTblAddr =
39714 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8));
39715 +
39716 + if (!p_Manip->reassmParams.timeOutTblAddr)
39717 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39718 + ("MURAM alloc for Reassembly timeout table"));
39719 +
39720 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0,
39721 + (uint16_t)(size * 8));
39722 +
39723 + /* Sets the TimeOut table offset from MURAM */
39724 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39725 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr))
39726 + - p_FmPcd->physicalMuramBase);
39727 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr,
39728 + tmpReg32);
39729 +
39730 + /* Sets the Expiration Delay */
39731 + tmpReg32 = 0;
39732 + tmpReg32 |= (((uint32_t)(1 << bitFor1Micro))
39733 + * p_Manip->reassmParams.timeoutThresholdForReassmProcess);
39734 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay,
39735 + tmpReg32);
39736 +
39737 + err = FmPcdRegisterReassmPort(p_FmPcd,
39738 + p_Manip->reassmParams.p_ReassCommonTbl);
39739 + if (err != E_OK)
39740 + {
39741 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
39742 + p_Manip->reassmParams.p_ReassCommonTbl);
39743 + RETURN_ERROR(MAJOR, err, ("port registration"));
39744 + }
39745 +
39746 + return err;
39747 +}
39748 +
39749 +static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
39750 +{
39751 + t_FmPcd *p_FmPcd = p_Manip->h_FmPcd;
39752 + uint32_t tmpReg32, autoLearnHashTblSize;
39753 + uint32_t numOfWays, setSize, setSizeCode, keySize;
39754 + uint32_t waySize, numOfSets, numOfEntries;
39755 + uint64_t tmpReg64;
39756 + uint16_t minFragSize;
39757 + uint16_t maxReassemSize;
39758 + uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr;
39759 + t_ReassTbl **p_ReassTbl;
39760 +
39761 + switch (hdr)
39762 + {
39763 + case HEADER_TYPE_IPv4:
39764 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl;
39765 + p_AutoLearnHashTblAddr =
39766 + &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr;
39767 + p_AutoLearnSetLockTblAddr =
39768 + &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr;
39769 + minFragSize = p_Manip->reassmParams.ip.minFragSize[0];
39770 + maxReassemSize = 0;
39771 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0];
39772 + keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */
39773 + break;
39774 + case HEADER_TYPE_IPv6:
39775 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl;
39776 + p_AutoLearnHashTblAddr =
39777 + &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr;
39778 + p_AutoLearnSetLockTblAddr =
39779 + &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr;
39780 + minFragSize = p_Manip->reassmParams.ip.minFragSize[1];
39781 + maxReassemSize = 0;
39782 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1];
39783 + keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */
39784 + if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH)
39785 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways"));
39786 + break;
39787 + case HEADER_TYPE_CAPWAP:
39788 + p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl;
39789 + p_AutoLearnHashTblAddr =
39790 + &p_Manip->reassmParams.capwap.autoLearnHashTblAddr;
39791 + p_AutoLearnSetLockTblAddr =
39792 + &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr;
39793 + minFragSize = 0;
39794 + maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize;
39795 + numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry;
39796 + keySize = 4;
39797 + break;
39798 + default:
39799 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
39800 + }
39801 + keySize += 2; /* 2 bytes reserved for RFDIndex */
39802 +#if (DPAA_VERSION >= 11)
39803 + keySize += 2; /* 2 bytes reserved */
39804 +#endif /* (DPAA_VERSION >= 11) */
39805 + waySize = ROUND_UP(keySize, 8);
39806 +
39807 + /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/
39808 + *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem(
39809 + p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE,
39810 + FM_PCD_MANIP_REASM_TABLE_ALIGN);
39811 + if (!*p_ReassTbl)
39812 + RETURN_ERROR( MAJOR, E_NO_MEMORY,
39813 + ("MURAM alloc for Reassembly specific parameters table"));
39814 + memset(*p_ReassTbl, 0, sizeof(t_ReassTbl));
39815 +
39816 + /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/
39817 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl)
39818 + - p_FmPcd->physicalMuramBase);
39819 + WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32);
39820 +
39821 + /* Calculate set size (set size is rounded-up to next power of 2) */
39822 + NEXT_POWER_OF_2(numOfWays * waySize, setSize);
39823 +
39824 + /* Get set size code */
39825 + LOG2(setSize, setSizeCode);
39826 +
39827 + /* Sets ways number and set size code */
39828 + WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize,
39829 + (uint16_t)((numOfWays << 8) | setSizeCode));
39830 +
39831 + /* It is recommended that the total number of entries in this table
39832 + (number of sets * number of ways) will be twice the number of frames that
39833 + are expected to be reassembled simultaneously.*/
39834 + numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2);
39835 +
39836 + /* sets number calculation - number of entries = number of sets * number of ways */
39837 + numOfSets = numOfEntries / numOfWays;
39838 +
39839 + /* Sets AutoLearnHashKeyMask*/
39840 + NEXT_POWER_OF_2(numOfSets, numOfSets);
39841 +
39842 + WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask,
39843 + (uint16_t)(numOfSets - 1));
39844 +
39845 + /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory.
39846 + The size of this table is determined by the number of sets and the set size.
39847 + Table size = set size * number of sets
39848 + This table base address should be aligned to SetSize.*/
39849 + autoLearnHashTblSize = numOfSets * setSize;
39850 +
39851 + *p_AutoLearnHashTblAddr =
39852 + PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize));
39853 + if (!*p_AutoLearnHashTblAddr)
39854 + {
39855 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
39856 + *p_ReassTbl = NULL;
39857 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39858 + }
39859 + MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize);
39860 +
39861 + /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */
39862 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39863 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39864 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39865 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39866 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39867 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39868 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
39869 + WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi,
39870 + (uint32_t)(tmpReg64 >> 32));
39871 + WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
39872 +
39873 + /* Allocation of the Set Lock table - This table resides in external memory
39874 + The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes.
39875 + This table resides in external memory and its base address should be 4-byte aligned */
39876 + *p_AutoLearnSetLockTblAddr =
39877 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4));
39878 + if (!*p_AutoLearnSetLockTblAddr)
39879 + {
39880 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
39881 + *p_ReassTbl = NULL;
39882 + XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
39883 + *p_AutoLearnHashTblAddr = 0;
39884 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39885 + }
39886 + MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4));
39887 +
39888 + /* sets Set Lock table pointer and liodn offset*/
39889 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39890 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39891 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39892 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39893 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39894 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39895 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr));
39896 + WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi,
39897 + (uint32_t)(tmpReg64 >> 32));
39898 + WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
39899 +
39900 + /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */
39901 + WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize);
39902 +
39903 + WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize);
39904 +
39905 + return E_OK;
39906 +}
39907 +
39908 +static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams,
39909 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
39910 + t_Handle h_Ad, bool validate)
39911 +{
39912 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39913 + uint32_t tmpReg32;
39914 + t_Error err;
39915 + t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams;
39916 +#if (DPAA_VERSION >= 11)
39917 + t_FmPcdCtrlParamsPage *p_ParamsPage;
39918 +#endif /* (DPAA_VERSION >= 11) */
39919 +
39920 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
39921 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE);
39922 + SANITY_CHECK_RETURN_ERROR(
39923 + (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY),
39924 + E_INVALID_STATE);
39925 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
39926 + SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams,
39927 + E_INVALID_HANDLE);
39928 +
39929 + UNUSED(h_Ad);
39930 +
39931 + if (!p_Manip->updateParams)
39932 + return E_OK;
39933 +
39934 + if (p_Manip->h_FmPcd != h_FmPcd)
39935 + RETURN_ERROR(
39936 + MAJOR, E_INVALID_STATE,
39937 + ("handler of PCD previously was initiated by different value"));
39938 +
39939 + if (p_Manip->updateParams)
39940 + {
39941 + if ((!(p_Manip->updateParams
39942 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))
39943 + || ((p_Manip->shadowUpdateParams
39944 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))))
39945 + RETURN_ERROR(
39946 + MAJOR, E_INVALID_STATE,
39947 + ("in this stage parameters from Port has not be updated"));
39948 +
39949 + fmPortGetSetCcParams.setCcParams.type = 0;
39950 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
39951 + {
39952 + fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE;
39953 + fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF;
39954 + }
39955 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV;
39956 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
39957 + != E_OK)
39958 + RETURN_ERROR(MAJOR, err, NO_MSG);
39959 + if (fmPortGetSetCcParams.getCcParams.type
39960 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV))
39961 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
39962 + ("offset of the data wasn't configured previously"));
39963 + if (p_Manip->updateParams
39964 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))
39965 + {
39966 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
39967 + uint8_t *p_Ptr, i, totalNumOfTnums;
39968 +
39969 + totalNumOfTnums =
39970 + (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks
39971 + + fmPortGetSetCcParams.getCcParams.numOfExtraTasks);
39972 +
39973 + p_Manip->reassmParams.internalBufferPoolAddr =
39974 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39975 + (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS),
39976 + BMI_FIFO_UNITS));
39977 + if (!p_Manip->reassmParams.internalBufferPoolAddr)
39978 + RETURN_ERROR(
39979 + MAJOR, E_NO_MEMORY,
39980 + ("MURAM alloc for Reassembly internal buffers pool"));
39981 + MemSet8(
39982 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr),
39983 + 0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS));
39984 +
39985 + p_Manip->reassmParams.internalBufferPoolManagementIndexAddr =
39986 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39987 + (uint32_t)(5 + totalNumOfTnums),
39988 + 4));
39989 + if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
39990 + RETURN_ERROR(
39991 + MAJOR,
39992 + E_NO_MEMORY,
39993 + ("MURAM alloc for Reassembly internal buffers management"));
39994 +
39995 + p_Ptr =
39996 + (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr);
39997 + WRITE_UINT32(
39998 + *(uint32_t*)p_Ptr,
39999 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase));
40000 + for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++)
40001 + WRITE_UINT8(*p_Ptr, i);
40002 + WRITE_UINT8(*p_Ptr, 0xFF);
40003 +
40004 + tmpReg32 =
40005 + (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT)
40006 + | ((uint32_t)(XX_VirtToPhys(
40007 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr))
40008 + - p_FmPcd->physicalMuramBase));
40009 + WRITE_UINT32(
40010 + p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement,
40011 + tmpReg32);
40012 +
40013 + p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
40014 + | DISCARD_MASK);
40015 + p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
40016 + | DISCARD_MASK);
40017 + }
40018 + }
40019 +
40020 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
40021 + {
40022 + if (p_Manip->reassmParams.capwap.h_Scheme)
40023 + {
40024 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40025 + p_Manip->reassmParams.capwap.h_Scheme;
40026 + p_PcdParams->p_KgParams->numOfSchemes++;
40027 + }
40028 +
40029 + }
40030 + else
40031 + {
40032 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
40033 + {
40034 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40035 + p_Manip->reassmParams.ip.h_Ipv4Scheme;
40036 + p_PcdParams->p_KgParams->numOfSchemes++;
40037 + }
40038 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
40039 + {
40040 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40041 + p_Manip->reassmParams.ip.h_Ipv6Scheme;
40042 + p_PcdParams->p_KgParams->numOfSchemes++;
40043 + }
40044 +#if (DPAA_VERSION >= 11)
40045 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6)
40046 + {
40047 + if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
40048 + (void**)&p_ParamsPage)) != E_OK)
40049 + RETURN_ERROR(MAJOR, err, NO_MSG);
40050 +
40051 + tmpReg32 = NIA_ENG_KG;
40052 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
40053 + {
40054 + tmpReg32 |= NIA_KG_DIRECT;
40055 + tmpReg32 |= NIA_KG_CC_EN;
40056 + tmpReg32 |= FmPcdKgGetSchemeId(
40057 + p_Manip->reassmParams.ip.h_Ipv4Scheme);
40058 + WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32);
40059 + }
40060 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
40061 + {
40062 + tmpReg32 &= ~NIA_AC_MASK;
40063 + tmpReg32 |= NIA_KG_DIRECT;
40064 + tmpReg32 |= NIA_KG_CC_EN;
40065 + tmpReg32 |= FmPcdKgGetSchemeId(
40066 + p_Manip->reassmParams.ip.h_Ipv6Scheme);
40067 + WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32);
40068 + }
40069 + }
40070 +#else
40071 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6)
40072 + {
40073 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask,
40074 + fmPortGetSetCcParams.getCcParams.discardMask);
40075 + }
40076 +#endif /* (DPAA_VERSION >= 11) */
40077 + }
40078 + return E_OK;
40079 +}
40080 +
40081 +#if (DPAA_VERSION == 10)
40082 +static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid)
40083 +{
40084 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
40085 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
40086 + t_Error err;
40087 +
40088 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
40089 +
40090 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
40091 +
40092 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS;
40093 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
40094 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
40095 + RETURN_ERROR(MAJOR, err, NO_MSG);
40096 +
40097 + if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0)
40098 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed,"
40099 + "Failed to release %d buffers to the BM (missing FBPRs)",
40100 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers));
40101 +
40102 + return E_OK;
40103 +}
40104 +
40105 +static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid)
40106 +{
40107 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
40108 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
40109 + t_Error err;
40110 +
40111 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
40112 +
40113 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
40114 +
40115 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
40116 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
40117 + RETURN_ERROR(MAJOR, err, NO_MSG);
40118 +
40119 + return E_OK;
40120 +}
40121 +#endif /* (DPAA_VERSION == 10) */
40122 +
40123 +static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
40124 +{
40125 + if (p_Manip->h_Ad)
40126 + {
40127 + if (p_Manip->muramAllocate)
40128 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
40129 + else
40130 + XX_Free(p_Manip->h_Ad);
40131 + p_Manip->h_Ad = NULL;
40132 + }
40133 + if (p_Manip->p_Template)
40134 + {
40135 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
40136 + p_Manip->p_Template = NULL;
40137 + }
40138 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40139 + if (p_Manip->h_Frag)
40140 + {
40141 + if (p_Manip->capwapFragParams.p_AutoLearnHashTbl)
40142 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40143 + p_Manip->capwapFragParams.p_AutoLearnHashTbl);
40144 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
40145 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40146 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl);
40147 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
40148 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40149 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl);
40150 + if (p_Manip->capwapFragParams.p_TimeOutTbl)
40151 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40152 + p_Manip->capwapFragParams.p_TimeOutTbl);
40153 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
40154 +
40155 + }
40156 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40157 + if (p_Manip->frag)
40158 + {
40159 + if (p_Manip->fragParams.p_Frag)
40160 + {
40161 +#if (DPAA_VERSION == 10)
40162 + FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid);
40163 +#endif /* (DPAA_VERSION == 10) */
40164 +
40165 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
40166 + }
40167 + }
40168 + else
40169 + if (p_Manip->reassm)
40170 + {
40171 + FmPcdUnregisterReassmPort(p_FmPcd,
40172 + p_Manip->reassmParams.p_ReassCommonTbl);
40173 +
40174 + if (p_Manip->reassmParams.timeOutTblAddr)
40175 + FM_MURAM_FreeMem(
40176 + p_FmPcd->h_FmMuram,
40177 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr));
40178 + if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
40179 + XX_FreeSmart(
40180 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr));
40181 + if (p_Manip->reassmParams.p_ReassCommonTbl)
40182 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40183 + p_Manip->reassmParams.p_ReassCommonTbl);
40184 + if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
40185 + FM_MURAM_FreeMem(
40186 + p_FmPcd->h_FmMuram,
40187 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr));
40188 + if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
40189 + FM_MURAM_FreeMem(
40190 + p_FmPcd->h_FmMuram,
40191 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr));
40192 + if (p_Manip->reassmParams.internalBufferPoolAddr)
40193 + FM_MURAM_FreeMem(
40194 + p_FmPcd->h_FmMuram,
40195 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr));
40196 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP)
40197 + {
40198 +
40199 + }
40200 + else
40201 + {
40202 + if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)
40203 + XX_FreeSmart(
40204 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr));
40205 + if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)
40206 + XX_FreeSmart(
40207 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr));
40208 + if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)
40209 + XX_FreeSmart(
40210 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr));
40211 + if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)
40212 + XX_FreeSmart(
40213 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr));
40214 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
40215 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40216 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl);
40217 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
40218 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40219 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl);
40220 + if (p_Manip->reassmParams.ip.h_Ipv6Ad)
40221 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad);
40222 + if (p_Manip->reassmParams.ip.h_Ipv4Ad)
40223 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad);
40224 + }
40225 + }
40226 +
40227 + if (p_Manip->p_StatsTbl)
40228 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
40229 +}
40230 +
40231 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40232 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams)
40233 +{
40234 + if (p_ManipParams->u.hdr.rmv)
40235 + {
40236 + switch (p_ManipParams->u.hdr.rmvParams.type)
40237 + {
40238 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40239 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40240 + {
40241 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) :
40242 + if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include)
40243 + {
40244 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40245 + {
40246 + case (HEADER_TYPE_CAPWAP_DTLS) :
40247 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
40248 + p_Manip->muramAllocate = TRUE;
40249 + if (p_ManipParams->u.hdr.insrt)
40250 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
40251 + if (p_ManipParams->fragOrReasm)
40252 + {
40253 + if (!p_ManipParams->fragOrReasmParams.frag)
40254 + {
40255 + switch (p_ManipParams->fragOrReasmParams.hdr)
40256 + {
40257 + case (HEADER_TYPE_CAPWAP):
40258 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40259 + break;
40260 + default:
40261 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
40262 + }
40263 + }
40264 + else
40265 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
40266 + }
40267 + break;
40268 + default:
40269 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
40270 + }
40271 + }
40272 + else
40273 + {
40274 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40275 + {
40276 + case (HEADER_TYPE_CAPWAP_DTLS) :
40277 + case (HEADER_TYPE_CAPWAP) :
40278 + if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt)
40279 + 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"));
40280 + p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40281 + p_Manip->muramAllocate = TRUE;
40282 + p_ManipParams->u.hdr.insrt = TRUE; //internal frame header
40283 + break;
40284 + default :
40285 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40286 + }
40287 + }
40288 + break;
40289 + default :
40290 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40291 + }
40292 + break;
40293 + default:
40294 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40295 + }
40296 + }
40297 + else if (p_ManipParams->u.hdr.insrt)
40298 + {
40299 + switch (p_ManipParams->u.hdr.insrtParams.type)
40300 + {
40301 + case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) :
40302 +
40303 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
40304 + p_Manip->muramAllocate = FALSE;
40305 + if (p_ManipParams->fragOrReasm)
40306 + {
40307 + if (p_ManipParams->fragOrReasmParams.frag)
40308 + {
40309 + switch (p_ManipParams->fragOrReasmParams.hdr)
40310 + {
40311 + case (HEADER_TYPE_CAPWAP):
40312 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40313 + break;
40314 + default:
40315 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
40316 + }
40317 + }
40318 + else
40319 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
40320 + }
40321 + break;
40322 +
40323 + default:
40324 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
40325 + }
40326 + }
40327 + else if (p_ManipParams->fragOrReasm)
40328 + {
40329 + if (p_ManipParams->fragOrReasmParams.frag)
40330 + {
40331 + switch (p_ManipParams->fragOrReasmParams.hdr)
40332 + {
40333 + case (HEADER_TYPE_CAPWAP):
40334 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40335 + p_Manip->muramAllocate = FALSE;
40336 + break;
40337 + default:
40338 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
40339 + }
40340 + }
40341 + else
40342 + {
40343 + switch (p_ManipParams->fragOrReasmParams.hdr)
40344 + {
40345 + case (HEADER_TYPE_CAPWAP):
40346 + 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"));
40347 + default:
40348 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
40349 + }
40350 + }
40351 +
40352 + }
40353 + else
40354 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
40355 +
40356 + p_Manip->insrt = p_ManipParams->u.hdr.insrt;
40357 + p_Manip->rmv = p_ManipParams->u.hdr.rmv;
40358 +
40359 + return E_OK;
40360 +}
40361 +
40362 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40363 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip,
40364 + t_FmPcdManipParams *p_ManipParams)
40365 +{
40366 + switch (p_ManipParams->type)
40367 + {
40368 + case e_FM_PCD_MANIP_HDR:
40369 + /* Check that next-manip is not already used */
40370 + if (p_ManipParams->h_NextManip)
40371 + {
40372 + if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip))
40373 + RETURN_ERROR(
40374 + MAJOR, E_INVALID_STATE,
40375 + ("h_NextManip is already a part of another chain"));
40376 + if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40377 + != e_FM_PCD_MANIP_HDR) &&
40378 + (MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40379 + != e_FM_PCD_MANIP_FRAG))
40380 + RETURN_ERROR(
40381 + MAJOR,
40382 + E_NOT_SUPPORTED,
40383 + ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation."));
40384 + }
40385 +
40386 + if (p_ManipParams->u.hdr.rmv)
40387 + {
40388 + switch (p_ManipParams->u.hdr.rmvParams.type)
40389 + {
40390 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40391 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40392 + {
40393 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
40394 + break;
40395 +#if (DPAA_VERSION >= 11)
40396 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
40397 + break;
40398 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
40399 + {
40400 + t_Error err;
40401 + uint8_t prsArrayOffset;
40402 +
40403 + err =
40404 + GetPrOffsetByHeaderOrField(
40405 + &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
40406 + &prsArrayOffset);
40407 + if (err)
40408 + RETURN_ERROR(MAJOR, err, NO_MSG);
40409 + break;
40410 + }
40411 +#endif /* (DPAA_VERSION >= 11) */
40412 + default:
40413 + RETURN_ERROR(
40414 + MAJOR,
40415 + E_INVALID_STATE,
40416 + ("invalid type of remove manipulation"));
40417 + }
40418 + break;
40419 + case (e_FM_PCD_MANIP_RMV_GENERIC):
40420 + break;
40421 + default:
40422 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40423 + ("invalid type of remove manipulation"));
40424 + }
40425 + p_Manip->opcode = HMAN_OC;
40426 + p_Manip->muramAllocate = TRUE;
40427 + p_Manip->rmv = TRUE;
40428 + }
40429 + else
40430 + if (p_ManipParams->u.hdr.insrt)
40431 + {
40432 + switch (p_ManipParams->u.hdr.insrtParams.type)
40433 + {
40434 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
40435 + {
40436 + switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type)
40437 + {
40438 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
40439 + /* nothing to check */
40440 + break;
40441 +#if (DPAA_VERSION >= 11)
40442 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
40443 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
40444 + % 4)
40445 + RETURN_ERROR(
40446 + MAJOR,
40447 + E_INVALID_VALUE,
40448 + ("IP inserted header must be of size which is a multiple of four bytes"));
40449 + break;
40450 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
40451 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40452 + % 4)
40453 + RETURN_ERROR(
40454 + MAJOR,
40455 + E_INVALID_VALUE,
40456 + ("CAPWAP inserted header must be of size which is a multiple of four bytes"));
40457 + break;
40458 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
40459 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
40460 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40461 + != 8)
40462 + RETURN_ERROR(
40463 + MAJOR,
40464 + E_INVALID_VALUE,
40465 + ("Inserted header must be of size 8"));
40466 + break;
40467 +#endif /* (DPAA_VERSION >= 11) */
40468 + default:
40469 + RETURN_ERROR(
40470 + MAJOR,
40471 + E_INVALID_STATE,
40472 + ("unsupported insert by header type"));
40473 + }
40474 + }
40475 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
40476 + break;
40477 + default:
40478 + RETURN_ERROR(
40479 + MAJOR,
40480 + E_INVALID_STATE,
40481 + ("for only insert manipulation unsupported type"));
40482 + }
40483 + p_Manip->opcode = HMAN_OC;
40484 + p_Manip->muramAllocate = TRUE;
40485 + p_Manip->insrt = TRUE;
40486 + }
40487 + else
40488 + if (p_ManipParams->u.hdr.fieldUpdate)
40489 + {
40490 + /* Check parameters */
40491 + if (p_ManipParams->u.hdr.fieldUpdateParams.type
40492 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN)
40493 + {
40494 + if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40495 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
40496 + && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri
40497 + > 7))
40498 + RETURN_ERROR(
40499 + MAJOR, E_INVALID_VALUE,
40500 + ("vpri should get values of 0-7 "));
40501 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40502 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
40503 + {
40504 + int i;
40505 +
40506 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal
40507 + > 7)
40508 + RETURN_ERROR(
40509 + MAJOR,
40510 + E_INVALID_VALUE,
40511 + ("vpriDefVal should get values of 0-7 "));
40512 + for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS;
40513 + i++)
40514 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]
40515 + & 0xf0)
40516 + RETURN_ERROR(
40517 + MAJOR,
40518 + E_INVALID_VALUE,
40519 + ("dscpToVpriTabl value out of range (0-15)"));
40520 + }
40521 +
40522 + }
40523 +
40524 + p_Manip->opcode = HMAN_OC;
40525 + p_Manip->muramAllocate = TRUE;
40526 + p_Manip->fieldUpdate = TRUE;
40527 + }
40528 + else
40529 + if (p_ManipParams->u.hdr.custom)
40530 + {
40531 + if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE)
40532 + {
40533 +
40534 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) ||
40535 + (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8))
40536 + RETURN_ERROR(
40537 + MAJOR, E_INVALID_VALUE,
40538 + ("size should get values of 1-8 "));
40539 +
40540 + if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7)
40541 + RETURN_ERROR(
40542 + MAJOR, E_INVALID_VALUE,
40543 + ("srcOffset should be <= 7"));
40544 +
40545 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset +
40546 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8)
40547 + RETURN_ERROR(
40548 + MAJOR, E_INVALID_VALUE,
40549 + ("(srcOffset + size) should be <= 8"));
40550 +
40551 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset +
40552 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256)
40553 + RETURN_ERROR(
40554 + MAJOR, E_INVALID_VALUE,
40555 + ("(dstOffset + size) should be <= 256"));
40556 +
40557 + }
40558 +
40559 + p_Manip->opcode = HMAN_OC;
40560 + p_Manip->muramAllocate = TRUE;
40561 + p_Manip->custom = TRUE;
40562 + }
40563 + break;
40564 + case e_FM_PCD_MANIP_REASSEM:
40565 + if (p_ManipParams->h_NextManip)
40566 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40567 + ("next manip with reassembly"));
40568 + switch (p_ManipParams->u.reassem.hdr)
40569 + {
40570 + case (HEADER_TYPE_IPv4):
40571 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4;
40572 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40573 + break;
40574 + case (HEADER_TYPE_IPv6):
40575 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6;
40576 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40577 + break;
40578 +#if (DPAA_VERSION >= 11)
40579 + case (HEADER_TYPE_CAPWAP):
40580 + p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP;
40581 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40582 + break;
40583 +#endif /* (DPAA_VERSION >= 11) */
40584 + default:
40585 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40586 + ("header for reassembly"));
40587 + }
40588 + break;
40589 + case e_FM_PCD_MANIP_FRAG:
40590 + if (p_ManipParams->h_NextManip)
40591 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40592 + ("next manip with fragmentation"));
40593 + switch (p_ManipParams->u.frag.hdr)
40594 + {
40595 + case (HEADER_TYPE_IPv4):
40596 + case (HEADER_TYPE_IPv6):
40597 + p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION;
40598 + break;
40599 +#if (DPAA_VERSION >= 11)
40600 + case (HEADER_TYPE_CAPWAP):
40601 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40602 + break;
40603 +#endif /* (DPAA_VERSION >= 11) */
40604 + default:
40605 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40606 + ("header for fragmentation"));
40607 + }
40608 + p_Manip->muramAllocate = TRUE;
40609 + break;
40610 + case e_FM_PCD_MANIP_SPECIAL_OFFLOAD:
40611 + switch (p_ManipParams->u.specialOffload.type)
40612 + {
40613 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC):
40614 + p_Manip->opcode = HMAN_OC_IPSEC_MANIP;
40615 + p_Manip->muramAllocate = TRUE;
40616 + break;
40617 +#if (DPAA_VERSION >= 11)
40618 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP):
40619 + p_Manip->opcode = HMAN_OC_CAPWAP_MANIP;
40620 + p_Manip->muramAllocate = TRUE;
40621 + break;
40622 +#endif /* (DPAA_VERSION >= 11) */
40623 + default:
40624 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40625 + ("special offload type"));
40626 + }
40627 + break;
40628 + default:
40629 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type"));
40630 + }
40631 +
40632 + return E_OK;
40633 +}
40634 +#endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40635 +
40636 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40637 +
40638 +static t_Error UpdateIndxStats(t_Handle h_FmPcd,
40639 + t_Handle h_FmPort,
40640 + t_FmPcdManip *p_Manip)
40641 +{
40642 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
40643 + uint32_t tmpReg32 = 0;
40644 + t_AdOfTypeContLookup *p_Ad;
40645 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
40646 + t_Error err;
40647 +
40648 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
40649 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40650 +
40651 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40652 + if (p_Manip->h_FmPcd != h_FmPcd)
40653 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40654 + ("handler of PCD previously was initiated by different value"));
40655 +
40656 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
40657 +
40658 + if (!p_Manip->p_StatsTbl)
40659 + {
40660 +
40661 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40662 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40663 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40664 + if (err)
40665 + RETURN_ERROR(MAJOR, err, NO_MSG);
40666 +
40667 + tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
40668 +
40669 + p_Manip->p_StatsTbl =
40670 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40671 + (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
40672 + 4);
40673 + if (!p_Manip->p_StatsTbl)
40674 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table"));
40675 +
40676 + MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4));
40677 +
40678 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
40679 +
40680 + if (p_Manip->cnia)
40681 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
40682 +
40683 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD;
40684 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40685 + }
40686 + else
40687 + {
40688 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40689 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40690 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40691 + if (err)
40692 + RETURN_ERROR(MAJOR, err, NO_MSG);
40693 + }
40694 +
40695 + return E_OK;
40696 +}
40697 +
40698 +static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip)
40699 +{
40700 + t_AdOfTypeContLookup *p_Ad;
40701 + uint32_t tmpReg32 = 0;
40702 + uint8_t prsArrayOffset = 0;
40703 + t_Error err;
40704 +
40705 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
40706 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
40707 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40708 +
40709 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40710 + if (p_Manip->rmv)
40711 + {
40712 + err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset);
40713 + if (err)
40714 + RETURN_ERROR(MAJOR, err, NO_MSG);
40715 +
40716 + tmpReg32 |= (uint32_t)prsArrayOffset << 24;
40717 + tmpReg32 |= HMAN_RMV_HDR;
40718 + }
40719 +
40720 + if (p_Manip->insrt)
40721 + tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
40722 +
40723 + tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40724 +
40725 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40726 +
40727 + tmpReg32 = 0;
40728 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40729 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40730 +
40731 + return E_OK;
40732 +}
40733 +
40734 +static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip,
40735 + bool caamUsed)
40736 +{
40737 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40738 + uint32_t tmpReg32 = 0;
40739 +
40740 + SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE);
40741 +
40742 + p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
40743 +
40744 + tmpReg32 = 0;
40745 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40746 + *(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
40747 +
40748 + tmpReg32 = 0;
40749 + tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
40750 + tmpReg32 |= (uint32_t)0x16 << 16;
40751 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
40752 +
40753 + if (caamUsed)
40754 + *(uint32_t *)&p_Ad->gmask = 0xf0000000;
40755 +
40756 + return E_OK;
40757 +}
40758 +
40759 +static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
40760 +{
40761 + t_AdOfTypeContLookup *p_Ad;
40762 + uint32_t tmpReg32 = 0;
40763 + t_Error err = E_OK;
40764 +
40765 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40766 +
40767 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40768 +
40769 + tmpReg32 = 0;
40770 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
40771 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40772 +
40773 + tmpReg32 = 0;
40774 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40775 +
40776 +
40777 + if (p_Manip->h_Frag)
40778 + {
40779 + p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
40780 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
40781 + }
40782 +
40783 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40784 +
40785 + return err;
40786 +}
40787 +
40788 +static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,
40789 + t_FmPcdManip *p_Manip,
40790 + t_FmPcd *p_FmPcd,
40791 + uint8_t poolId)
40792 +{
40793 + t_Handle p_Table;
40794 + uint32_t tmpReg32 = 0;
40795 + int i = 0;
40796 + uint8_t log2Num;
40797 + uint8_t numOfSets;
40798 + uint32_t j = 0;
40799 + uint32_t bitFor1Micro;
40800 +
40801 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
40802 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
40803 +
40804 + if (!p_FmPcd->h_Hc)
40805 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
40806 + if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
40807 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
40808 + if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
40809 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
40810 + if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
40811 + DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly"));
40812 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
40813 + {
40814 + if ((p_ManipParams->maxNumFramesInProcess < 4) ||
40815 + (p_ManipParams->maxNumFramesInProcess > 512))
40816 + 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"));
40817 + }
40818 + else
40819 + {
40820 + if ((p_ManipParams->maxNumFramesInProcess < 8) ||
40821 + (p_ManipParams->maxNumFramesInProcess > 2048))
40822 + 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"));
40823 + }
40824 +
40825 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
40826 + if (bitFor1Micro == 0)
40827 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
40828 +
40829 + p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
40830 +
40831 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40832 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
40833 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
40834 + if (!p_Manip->h_Frag)
40835 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table"));
40836 +
40837 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
40838 +
40839 + p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag;
40840 +
40841 + p_Manip->capwapFragParams.p_AutoLearnHashTbl =
40842 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40843 + (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
40844 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
40845 +
40846 + if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl)
40847 + RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table"));
40848 +
40849 + MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
40850 +
40851 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
40852 +
40853 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
40854 +
40855 + tmpReg32 = 0;
40856 + if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
40857 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
40858 + if (p_ManipParams->haltOnDuplicationFrag)
40859 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
40860 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
40861 + {
40862 + i = 8;
40863 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
40864 + }
40865 + else
40866 + i = 4;
40867 +
40868 + numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
40869 + LOG2(numOfSets, log2Num);
40870 + tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
40871 +
40872 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
40873 +
40874 + for (j=0; j<p_ManipParams->maxNumFramesInProcess*2; j++)
40875 + if (((j / i) % 2)== 0)
40876 + WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
40877 +
40878 + tmpReg32 = 0x00008000;
40879 + tmpReg32 |= (uint32_t)poolId << 16;
40880 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
40881 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
40882 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
40883 +
40884 + p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
40885 +
40886 + p_Manip->capwapFragParams.sgBpid = poolId;
40887 +
40888 + p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
40889 + p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
40890 + p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro;
40891 +
40892 + tmpReg32 = 0;
40893 + tmpReg32 |= (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
40894 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
40895 +
40896 + return E_OK;
40897 +}
40898 +
40899 +static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,
40900 + t_FmPcdManip *p_Manip,
40901 + t_FmPcd *p_FmPcd,
40902 + uint8_t poolId)
40903 +{
40904 + t_AdOfTypeContLookup *p_Ad;
40905 + uint32_t tmpReg32 = 0;
40906 +
40907 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40908 +
40909 + p_Manip->updateParams |= OFFSET_OF_DATA;
40910 +
40911 + p_Manip->frag = TRUE;
40912 +
40913 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40914 + FM_PCD_CC_AD_ENTRY_SIZE,
40915 + FM_PCD_CC_AD_TABLE_ALIGN);
40916 + if (!p_Manip->h_Frag)
40917 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor"));
40918 +
40919 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
40920 +
40921 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
40922 +
40923 + tmpReg32 = 0;
40924 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
40925 +
40926 + if (p_ManipParams->headerOptionsCompr)
40927 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
40928 + tmpReg32 |= ((uint32_t)poolId << 8);
40929 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40930 +
40931 + tmpReg32 = 0;
40932 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40933 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40934 +
40935 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
40936 + p_Manip->capwapFragParams.sgBpid = poolId;
40937 +
40938 + return E_OK;
40939 +}
40940 +
40941 +static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
40942 +{
40943 + t_AdOfTypeContLookup *p_Ad;
40944 + uint32_t tmpReg32 = 0;
40945 +
40946 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40947 +
40948 + UNUSED(p_FmPcd);
40949 +
40950 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40951 +
40952 + tmpReg32 = 0;
40953 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
40954 + if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
40955 + tmpReg32 |= (uint32_t)0x16 << 16;
40956 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40957 +
40958 + tmpReg32 = 0;
40959 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40960 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40961 +
40962 + return E_OK;
40963 +}
40964 +
40965 +static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
40966 +{
40967 + t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate;
40968 + uint8_t tmpReg8 = 0xff;
40969 + t_AdOfTypeContLookup *p_Ad;
40970 + bool ipModify = FALSE;
40971 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
40972 + uint16_t tmpReg16 = 0;
40973 + t_Error err = E_OK;
40974 + uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0;
40975 + uint8_t *p_Template = NULL;
40976 +
40977 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
40978 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
40979 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40980 + SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
40981 +
40982 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40983 + if (p_Manip->insrt)
40984 + {
40985 + if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
40986 + (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
40987 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
40988 +
40989 + if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
40990 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
40991 +
40992 + if (p_InsrtByTemplate->size > 128)
40993 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
40994 +
40995 + if (p_InsrtByTemplate->size)
40996 + {
40997 + p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40998 + p_InsrtByTemplate->size,
40999 + FM_PCD_CC_AD_TABLE_ALIGN);
41000 + if(!p_Manip->p_Template)
41001 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
41002 +
41003 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
41004 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
41005 + *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
41006 + }
41007 +
41008 + tmpReg32 = 0;
41009 +
41010 + p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
41011 +
41012 + if (!p_Template)
41013 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
41014 +
41015 + memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
41016 +
41017 + if (p_InsrtByTemplate->modifyOuterIp)
41018 + {
41019 + ipModify = TRUE;
41020 +
41021 + tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
41022 +
41023 + if((tmpReg8 & 0xf0) == 0x40)
41024 + tmpReg8 = 4;
41025 + else if((tmpReg8 & 0xf0) == 0x60)
41026 + tmpReg8 = 6;
41027 + else
41028 + tmpReg8 = 0xff;
41029 +
41030 + if (tmpReg8 != 0xff)
41031 + {
41032 + if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
41033 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
41034 + if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
41035 + {
41036 +
41037 + if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
41038 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
41039 + extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
41040 + blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
41041 + extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
41042 + /*IP header template - IP totalLength -
41043 + (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
41044 + in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
41045 + second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
41046 + }
41047 + if (blockSize)
41048 + {
41049 + if (!POWER_OF_2(blockSize))
41050 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
41051 + }
41052 +
41053 + }
41054 + if (tmpReg8 == 4)
41055 + {
41056 + if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
41057 + 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"));
41058 +
41059 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
41060 +
41061 + if (blockSize)
41062 + blockSize -= 1;
41063 +
41064 + if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
41065 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
41066 +
41067 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND
41068 + 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
41069 +
41070 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00;
41071 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
41072 +
41073 + /*IP header template - relevant only for ipv4 CheckSum = 0*/
41074 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
41075 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
41076 +
41077 + /*UDP checksum has to be 0*/
41078 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
41079 + {
41080 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
41081 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
41082 +
41083 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
41084 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
41085 +
41086 + }
41087 +
41088 + if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
41089 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
41090 +
41091 + tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
41092 + }
41093 + else if (tmpReg8 == 6)
41094 + {
41095 + /*TODO - add check for maximum value of blockSize;*/
41096 + if (blockSize)
41097 + LOG2(blockSize, log2Num);
41098 + tmpRegNia |= (uint32_t)log2Num << 24;
41099 +
41100 + // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength
41101 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40);
41102 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
41103 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
41104 + {
41105 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
41106 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
41107 + if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88)
41108 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite"));
41109 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00;
41110 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08;
41111 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00;
41112 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
41113 + }
41114 + }
41115 + else
41116 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
41117 + }
41118 +
41119 + tmpReg32 = tmpReg16 = tmpReg8 = 0;
41120 + /*TODO - check it*/
41121 + if (p_InsrtByTemplate->modifyOuterVlan)
41122 + {
41123 + if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
41124 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
41125 +
41126 + memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
41127 + if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
41128 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
41129 +
41130 + memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
41131 + tmpReg8 &= 0x1f;
41132 + tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
41133 +
41134 + p_Template[14] = tmpReg8;
41135 + }
41136 +
41137 + MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
41138 +
41139 + XX_Free(p_Template);
41140 + }
41141 +
41142 + tmpReg32 = 0;
41143 + if (p_Manip->h_Frag)
41144 + {
41145 + tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
41146 + tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
41147 + }
41148 + else
41149 + tmpReg32 = 0xffff0000;
41150 +
41151 + if (ipModify)
41152 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
41153 + else
41154 + tmpReg32 |= (uint32_t)0x0000ff00;
41155 +
41156 + tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
41157 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
41158 +
41159 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41160 + *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
41161 +
41162 + return err;
41163 +}
41164 +
41165 +static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams)
41166 +{
41167 +
41168 + switch (p_StatsParams->type)
41169 + {
41170 + case (e_FM_PCD_STATS_PER_FLOWID):
41171 + p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS;
41172 + p_Manip->muramAllocate = TRUE;
41173 + break;
41174 + default:
41175 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
41176 + }
41177 +
41178 + return E_OK;
41179 +}
41180 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
41181 +
41182 +static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
41183 +{
41184 + t_AdOfTypeContLookup *p_Ad;
41185 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41186 + uint32_t tmpReg32;
41187 + t_Error err = E_OK;
41188 +
41189 + /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly
41190 + function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then
41191 + two separate IP Reassembly Parameter tables are required.*/
41192 + if ((err = CreateReassTable(p_Manip, hdr)) != E_OK)
41193 + RETURN_ERROR(MAJOR, err, NO_MSG);
41194 +
41195 + /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/
41196 + tmpReg32 = 0;
41197 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41198 +
41199 + /* Gets the required Action descriptor table pointer */
41200 + switch (hdr)
41201 + {
41202 + case HEADER_TYPE_IPv4:
41203 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad;
41204 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41205 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41206 + - (p_FmPcd->physicalMuramBase));
41207 + break;
41208 + case HEADER_TYPE_IPv6:
41209 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad;
41210 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41211 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41212 + - (p_FmPcd->physicalMuramBase));
41213 + break;
41214 + case HEADER_TYPE_CAPWAP:
41215 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad;
41216 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41217 + p_Manip->reassmParams.capwap.p_ReassTbl)
41218 + - (p_FmPcd->physicalMuramBase));
41219 + break;
41220 + default:
41221 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
41222 + }
41223 +
41224 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41225 +
41226 + /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/
41227 + /* mark the Scatter/Gather table offset to be set later on when the port will be known */
41228 + p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK);
41229 +
41230 + if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4))
41231 + {
41232 +#if (DPAA_VERSION == 10)
41233 + tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8);
41234 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
41235 +#endif /* (DPAA_VERSION == 10) */
41236 +#if (DPAA_VERSION >= 11)
41237 + if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0)
41238 + {
41239 + tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK
41240 + | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid);
41241 + WRITE_UINT32(p_Ad->gmask, tmpReg32);
41242 + }
41243 +#endif /* (DPAA_VERSION >= 11) */
41244 + /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/
41245 + tmpReg32 = 0;
41246 + tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
41247 + }
41248 +#if (DPAA_VERSION >= 11)
41249 + else
41250 + if (hdr == HEADER_TYPE_CAPWAP)
41251 + {
41252 + tmpReg32 = 0;
41253 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY;
41254 + }
41255 +#endif /* (DPAA_VERSION >= 11) */
41256 +
41257 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41258 +
41259 + p_Manip->reassm = TRUE;
41260 +
41261 + return E_OK;
41262 +}
41263 +
41264 +static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
41265 +{
41266 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41267 +
41268 + /* Allocation if IPv4 Action descriptor */
41269 + p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart(
41270 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41271 + FM_PCD_CC_AD_TABLE_ALIGN);
41272 + if (!p_Manip->reassmParams.ip.h_Ipv4Ad)
41273 + {
41274 + ReleaseManipHandler(p_Manip, p_FmPcd);
41275 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41276 + ("Allocation of IPv4 table descriptor"));
41277 + }
41278 +
41279 + memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41280 +
41281 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41282 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4);
41283 +}
41284 +
41285 +static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
41286 +{
41287 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41288 +
41289 + /* Allocation if IPv6 Action descriptor */
41290 + p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart(
41291 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41292 + FM_PCD_CC_AD_TABLE_ALIGN);
41293 + if (!p_Manip->reassmParams.ip.h_Ipv6Ad)
41294 + {
41295 + ReleaseManipHandler(p_Manip, p_FmPcd);
41296 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41297 + ("Allocation of IPv6 table descriptor"));
41298 + }
41299 +
41300 + memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41301 +
41302 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41303 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6);
41304 +}
41305 +
41306 +static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
41307 + t_FmPcdManip *p_Manip)
41308 +{
41309 + uint32_t maxSetNumber = 10000;
41310 + t_FmPcdManipReassemIpParams reassmManipParams =
41311 + p_ManipReassmParams->u.ipReassem;
41312 + t_Error res;
41313 +
41314 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
41315 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
41316 + E_INVALID_HANDLE);
41317 +
41318 + /* Check validation of user's parameter.*/
41319 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
41320 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
41321 + RETURN_ERROR(
41322 + MAJOR, E_INVALID_VALUE,
41323 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
41324 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
41325 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
41326 + if (reassmManipParams.maxNumFramesInProcess
41327 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
41328 + RETURN_ERROR(
41329 + MAJOR,
41330 + E_INVALID_VALUE,
41331 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
41332 +
41333 + if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6)
41334 + && (reassmManipParams.minFragSize[1] < 256))
41335 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256"));
41336 +
41337 + /* Saves user's reassembly manipulation parameters */
41338 + p_Manip->reassmParams.ip.relativeSchemeId[0] =
41339 + reassmManipParams.relativeSchemeId[0];
41340 + p_Manip->reassmParams.ip.relativeSchemeId[1] =
41341 + reassmManipParams.relativeSchemeId[1];
41342 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] =
41343 + reassmManipParams.numOfFramesPerHashEntry[0];
41344 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] =
41345 + reassmManipParams.numOfFramesPerHashEntry[1];
41346 + p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0];
41347 + p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1];
41348 + p_Manip->reassmParams.maxNumFramesInProcess =
41349 + reassmManipParams.maxNumFramesInProcess;
41350 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
41351 + p_Manip->reassmParams.fqidForTimeOutFrames =
41352 + reassmManipParams.fqidForTimeOutFrames;
41353 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
41354 + reassmManipParams.timeoutThresholdForReassmProcess;
41355 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
41356 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
41357 +#if (DPAA_VERSION == 10)
41358 + p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid;
41359 +#endif /* (DPAA_VERSION == 10) */
41360 +#if (DPAA_VERSION >= 11)
41361 + if (reassmManipParams.nonConsistentSpFqid != 0)
41362 + {
41363 + p_Manip->reassmParams.ip.nonConsistentSpFqid =
41364 + reassmManipParams.nonConsistentSpFqid;
41365 + }
41366 +#endif /* (DPAA_VERSION >= 11) */
41367 +
41368 + /* Creates and initializes the IP Reassembly common parameter table */
41369 + CreateReassCommonTable(p_Manip);
41370 +
41371 + /* Creation of IPv4 reassembly manipulation */
41372 + if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41373 + || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4))
41374 + {
41375 + res = SetIpv4ReassmManip(p_Manip);
41376 + if (res != E_OK)
41377 + return res;
41378 + }
41379 +
41380 + /* Creation of IPv6 reassembly manipulation */
41381 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41382 + {
41383 + res = SetIpv6ReassmManip(p_Manip);
41384 + if (res != E_OK)
41385 + return res;
41386 + }
41387 +
41388 + return E_OK;
41389 +}
41390 +
41391 +static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd,
41392 + t_FmPcdKgSchemeParams *p_Scheme,
41393 + t_Handle h_CcTree, bool ipv4,
41394 + uint8_t groupId)
41395 +{
41396 + uint32_t j;
41397 + uint8_t res;
41398 +
41399 + /* Configures scheme's network environment parameters */
41400 + p_Scheme->netEnvParams.numOfDistinctionUnits = 2;
41401 + if (ipv4)
41402 + res = FmPcdNetEnvGetUnitId(
41403 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41404 + HEADER_TYPE_IPv4, FALSE, 0);
41405 + else
41406 + res = FmPcdNetEnvGetUnitId(
41407 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41408 + HEADER_TYPE_IPv6, FALSE, 0);
41409 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41410 + p_Scheme->netEnvParams.unitIds[0] = res;
41411 +
41412 + res = FmPcdNetEnvGetUnitId(
41413 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41414 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
41415 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41416 + p_Scheme->netEnvParams.unitIds[1] = res;
41417 +
41418 + /* Configures scheme's next engine parameters*/
41419 + p_Scheme->nextEngine = e_FM_PCD_CC;
41420 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
41421 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
41422 + p_Scheme->useHash = TRUE;
41423 +
41424 + /* Configures scheme's key*/
41425 + if (ipv4 == TRUE)
41426 + {
41427 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4;
41428 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41429 + e_FM_PCD_EXTRACT_BY_HDR;
41430 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41431 + e_FM_PCD_EXTRACT_FULL_FIELD;
41432 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41433 + HEADER_TYPE_IPv4;
41434 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 =
41435 + NET_HEADER_FIELD_IPv4_DST_IP;
41436 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41437 + e_FM_PCD_EXTRACT_BY_HDR;
41438 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41439 + e_FM_PCD_EXTRACT_FULL_FIELD;
41440 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41441 + HEADER_TYPE_IPv4;
41442 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 =
41443 + NET_HEADER_FIELD_IPv4_SRC_IP;
41444 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41445 + e_FM_PCD_EXTRACT_BY_HDR;
41446 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41447 + e_FM_PCD_EXTRACT_FULL_FIELD;
41448 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41449 + HEADER_TYPE_IPv4;
41450 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 =
41451 + NET_HEADER_FIELD_IPv4_PROTO;
41452 + p_Scheme->keyExtractAndHashParams.extractArray[3].type =
41453 + e_FM_PCD_EXTRACT_BY_HDR;
41454 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr =
41455 + HEADER_TYPE_IPv4;
41456 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type =
41457 + e_FM_PCD_EXTRACT_FROM_HDR;
41458 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation =
41459 + FALSE;
41460 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size =
41461 + 2;
41462 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset =
41463 + 4;
41464 + }
41465 + else /* IPv6 */
41466 + {
41467 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3;
41468 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41469 + e_FM_PCD_EXTRACT_BY_HDR;
41470 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41471 + e_FM_PCD_EXTRACT_FULL_FIELD;
41472 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41473 + HEADER_TYPE_IPv6;
41474 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 =
41475 + NET_HEADER_FIELD_IPv6_DST_IP;
41476 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41477 + e_FM_PCD_EXTRACT_BY_HDR;
41478 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41479 + e_FM_PCD_EXTRACT_FULL_FIELD;
41480 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41481 + HEADER_TYPE_IPv6;
41482 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 =
41483 + NET_HEADER_FIELD_IPv6_SRC_IP;
41484 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41485 + e_FM_PCD_EXTRACT_BY_HDR;
41486 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41487 + HEADER_TYPE_USER_DEFINED_SHIM2;
41488 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41489 + e_FM_PCD_EXTRACT_FROM_HDR;
41490 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size =
41491 + 4;
41492 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset =
41493 + 4;
41494 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation =
41495 + TRUE;
41496 + }
41497 +
41498 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304;
41499 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314;
41500 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts =
41501 + FM_PCD_KG_NUM_OF_DEFAULT_GROUPS;
41502 + for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++)
41503 + {
41504 + p_Scheme->keyExtractAndHashParams.dflts[j].type =
41505 + (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */
41506 + p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect =
41507 + e_FM_PCD_KG_DFLT_GBL_0;
41508 + }
41509 +}
41510 +
41511 +static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip,
41512 + t_FmPcdManipReassemIpStats *p_Stats)
41513 +{
41514 + ASSERT_COND(p_Manip);
41515 + ASSERT_COND(p_Stats);
41516 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
41517 +
41518 + p_Stats->timeout =
41519 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
41520 + p_Stats->rfdPoolBusy =
41521 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
41522 + p_Stats->internalBufferBusy =
41523 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
41524 + p_Stats->externalBufferBusy =
41525 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
41526 + p_Stats->sgFragments =
41527 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
41528 + p_Stats->dmaSemaphoreDepletion =
41529 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
41530 +#if (DPAA_VERSION >= 11)
41531 + p_Stats->nonConsistentSp =
41532 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
41533 +#endif /* (DPAA_VERSION >= 11) */
41534 +
41535 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41536 + {
41537 + p_Stats->specificHdrStatistics[0].successfullyReassembled =
41538 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter);
41539 + p_Stats->specificHdrStatistics[0].validFragments =
41540 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter);
41541 + p_Stats->specificHdrStatistics[0].processedFragments =
41542 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter);
41543 + p_Stats->specificHdrStatistics[0].malformedFragments =
41544 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter);
41545 + p_Stats->specificHdrStatistics[0].autoLearnBusy =
41546 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter);
41547 + p_Stats->specificHdrStatistics[0].discardedFragments =
41548 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter);
41549 + p_Stats->specificHdrStatistics[0].moreThan16Fragments =
41550 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter);
41551 + }
41552 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41553 + {
41554 + p_Stats->specificHdrStatistics[1].successfullyReassembled =
41555 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter);
41556 + p_Stats->specificHdrStatistics[1].validFragments =
41557 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter);
41558 + p_Stats->specificHdrStatistics[1].processedFragments =
41559 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter);
41560 + p_Stats->specificHdrStatistics[1].malformedFragments =
41561 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter);
41562 + p_Stats->specificHdrStatistics[1].autoLearnBusy =
41563 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter);
41564 + p_Stats->specificHdrStatistics[1].discardedFragments =
41565 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter);
41566 + p_Stats->specificHdrStatistics[1].moreThan16Fragments =
41567 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter);
41568 + }
41569 + return E_OK;
41570 +}
41571 +
41572 +static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip,
41573 + t_FmPcdManipFragIpStats *p_Stats)
41574 +{
41575 + t_AdOfTypeContLookup *p_Ad;
41576 +
41577 + ASSERT_COND(p_Manip);
41578 + ASSERT_COND(p_Stats);
41579 + ASSERT_COND(p_Manip->h_Ad);
41580 + ASSERT_COND(p_Manip->fragParams.p_Frag);
41581 +
41582 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41583 +
41584 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
41585 + p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase)
41586 + & 0x00ffffff;
41587 + p_Stats->generatedFragments =
41588 + GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr);
41589 +
41590 + return E_OK;
41591 +}
41592 +
41593 +static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams,
41594 + t_FmPcdManip *p_Manip)
41595 +{
41596 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
41597 + t_FmPcd *p_FmPcd;
41598 +#if (DPAA_VERSION == 10)
41599 + t_Error err = E_OK;
41600 +#endif /* (DPAA_VERSION == 10) */
41601 +
41602 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
41603 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
41604 + E_INVALID_VALUE);
41605 +
41606 + p_FmPcd = p_Manip->h_FmPcd;
41607 + /* Allocation of fragmentation Action Descriptor */
41608 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
41609 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
41610 + FM_PCD_CC_AD_TABLE_ALIGN);
41611 + if (!p_Manip->fragParams.p_Frag)
41612 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41613 + ("MURAM alloc for Fragmentation table descriptor"));
41614 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41615 +
41616 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
41617 + pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION;
41618 +
41619 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
41620 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
41621 + ccAdBaseReg |= (p_ManipParams->dontFragAction
41622 + << FM_PCD_MANIP_IP_FRAG_DF_SHIFT);
41623 +
41624 +
41625 + /* Set Scatter/Gather BPid */
41626 + if (p_ManipParams->sgBpidEn)
41627 + {
41628 + ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN;
41629 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
41630 + << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT)
41631 + & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK);
41632 + }
41633 +
41634 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
41635 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr))
41636 + - p_FmPcd->physicalMuramBase);
41637 +#if (DPAA_VERSION == 10)
41638 + gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41639 +#else
41640 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41641 +#endif /* (DPAA_VERSION == 10) */
41642 +
41643 + /* Set all Ad registers */
41644 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
41645 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
41646 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
41647 +
41648 + /* Saves user's fragmentation manipulation parameters */
41649 + p_Manip->frag = TRUE;
41650 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
41651 +
41652 +#if (DPAA_VERSION == 10)
41653 + p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid;
41654 +
41655 + /* scratch buffer pool initialization */
41656 + if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK)
41657 + {
41658 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
41659 + p_Manip->fragParams.p_Frag = NULL;
41660 + RETURN_ERROR(MAJOR, err, NO_MSG);
41661 + }
41662 +#endif /* (DPAA_VERSION == 10) */
41663 +
41664 + return E_OK;
41665 +}
41666 +
41667 +static t_Error IPManip(t_FmPcdManip *p_Manip)
41668 +{
41669 + t_Error err = E_OK;
41670 + t_FmPcd *p_FmPcd;
41671 + t_AdOfTypeContLookup *p_Ad;
41672 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41673 +
41674 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41675 + p_FmPcd = p_Manip->h_FmPcd;
41676 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
41677 +
41678 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41679 +
41680 + tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION;
41681 + if (p_Manip->frag == TRUE)
41682 + {
41683 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
41684 + - (p_FmPcd->physicalMuramBase));
41685 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
41686 + << FM_PCD_MANIP_IP_MTU_SHIFT;
41687 + }
41688 +
41689 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41690 + tmpReg32 |= HMAN_OC_IP_MANIP;
41691 +
41692 +#if (DPAA_VERSION >= 11)
41693 + tmpRegNia |= FM_PCD_MANIP_IP_CNIA;
41694 +#endif /* (DPAA_VERSION >= 11) */
41695 +
41696 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41697 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
41698 + WRITE_UINT32(p_Ad->gmask, 0);
41699 + /* Total frame counter - MUST be initialized to zero.*/
41700 +
41701 + return err;
41702 +}
41703 +
41704 +static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
41705 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
41706 + t_Handle h_Ad, bool validate)
41707 +{
41708 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41709 + t_Error err;
41710 +
41711 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41712 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION),
41713 + E_INVALID_STATE);
41714 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
41715 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
41716 +
41717 + UNUSED(h_FmPcd);
41718 + UNUSED(h_Ad);
41719 + UNUSED(h_PcdParams);
41720 + UNUSED(validate);
41721 + UNUSED(p_Manip);
41722 +
41723 + fmPortGetSetCcParams.setCcParams.type = 0;
41724 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
41725 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
41726 + RETURN_ERROR(MAJOR, err, NO_MSG);
41727 +
41728 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
41729 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
41730 +
41731 + return E_OK;
41732 +}
41733 +
41734 +static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams,
41735 + t_FmPcdManip *p_Manip)
41736 +{
41737 + t_AdOfTypeContLookup *p_Ad;
41738 + t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams;
41739 + t_Error err = E_OK;
41740 + uint32_t tmpReg32 = 0;
41741 + uint32_t power;
41742 +
41743 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41744 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
41745 +
41746 + p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec;
41747 +
41748 + SANITY_CHECK_RETURN_ERROR(
41749 + !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption,
41750 + E_INVALID_VALUE);
41751 + SANITY_CHECK_RETURN_ERROR(
41752 + !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption,
41753 + E_INVALID_VALUE);
41754 + SANITY_CHECK_RETURN_ERROR(
41755 + !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen,
41756 + E_INVALID_VALUE);
41757 + SANITY_CHECK_RETURN_ERROR(
41758 + !p_IPSecParams->arwSize || p_IPSecParams->arwAddr,
41759 + E_INVALID_VALUE);
41760 + SANITY_CHECK_RETURN_ERROR(
41761 + !p_IPSecParams->arwSize || p_IPSecParams->decryption,
41762 + E_INVALID_VALUE);
41763 + SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE);
41764 +
41765 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41766 +
41767 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41768 + tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0;
41769 + tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0;
41770 + tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0;
41771 + tmpReg32 |=
41772 + (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0;
41773 + tmpReg32 |=
41774 + (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0;
41775 + if (p_IPSecParams->arwSize)
41776 + tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM)
41777 + & (FM_MURAM_SIZE-1));
41778 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41779 +
41780 + tmpReg32 = 0;
41781 + if (p_IPSecParams->arwSize) {
41782 + NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power);
41783 + LOG2(power, power);
41784 + tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT;
41785 + }
41786 +
41787 + if (p_ManipParams->h_NextManip)
41788 + tmpReg32 |=
41789 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)-
41790 + (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4;
41791 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
41792 +
41793 + tmpReg32 = HMAN_OC_IPSEC_MANIP;
41794 + tmpReg32 |= p_IPSecParams->outerIPHdrLen
41795 + << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT;
41796 + if (p_ManipParams->h_NextManip)
41797 + tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN;
41798 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41799 +
41800 + return err;
41801 +}
41802 +
41803 +static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip)
41804 +{
41805 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41806 +
41807 + /* Allocation if CAPWAP Action descriptor */
41808 + p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart(
41809 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41810 + FM_PCD_CC_AD_TABLE_ALIGN);
41811 + if (!p_Manip->reassmParams.capwap.h_Ad)
41812 + {
41813 + ReleaseManipHandler(p_Manip, p_FmPcd);
41814 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41815 + ("Allocation of CAPWAP table descriptor"));
41816 + }
41817 +
41818 + memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41819 +
41820 + /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */
41821 + return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP);
41822 +}
41823 +
41824 +static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd,
41825 + t_FmPcdKgSchemeParams *p_Scheme,
41826 + t_Handle h_CcTree, uint8_t groupId)
41827 +{
41828 + uint8_t res;
41829 +
41830 + /* Configures scheme's network environment parameters */
41831 + p_Scheme->netEnvParams.numOfDistinctionUnits = 1;
41832 + res = FmPcdNetEnvGetUnitId(
41833 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41834 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
41835 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41836 + p_Scheme->netEnvParams.unitIds[0] = res;
41837 +
41838 + /* Configures scheme's next engine parameters*/
41839 + p_Scheme->nextEngine = e_FM_PCD_CC;
41840 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
41841 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
41842 + p_Scheme->useHash = TRUE;
41843 +
41844 + /* Configures scheme's key*/
41845 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2;
41846 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41847 + e_FM_PCD_EXTRACT_NON_HDR;
41848 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src =
41849 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT;
41850 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action =
41851 + e_FM_PCD_ACTION_NONE;
41852 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20;
41853 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4;
41854 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41855 + e_FM_PCD_EXTRACT_NON_HDR;
41856 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src =
41857 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE;
41858 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action =
41859 + e_FM_PCD_ACTION_NONE;
41860 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0;
41861 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1;
41862 +
41863 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0;
41864 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0;
41865 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1;
41866 + p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
41867 + p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0;
41868 +}
41869 +
41870 +#if (DPAA_VERSION >= 11)
41871 +static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip,
41872 + t_FmPcdManipReassemCapwapStats *p_Stats)
41873 +{
41874 + ASSERT_COND(p_Manip);
41875 + ASSERT_COND(p_Stats);
41876 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
41877 +
41878 + p_Stats->timeout =
41879 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
41880 + p_Stats->rfdPoolBusy =
41881 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
41882 + p_Stats->internalBufferBusy =
41883 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
41884 + p_Stats->externalBufferBusy =
41885 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
41886 + p_Stats->sgFragments =
41887 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
41888 + p_Stats->dmaSemaphoreDepletion =
41889 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
41890 + p_Stats->exceedMaxReassemblyFrameLen =
41891 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
41892 +
41893 + p_Stats->successfullyReassembled =
41894 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter);
41895 + p_Stats->validFragments =
41896 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter);
41897 + p_Stats->processedFragments =
41898 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter);
41899 + p_Stats->malformedFragments =
41900 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter);
41901 + p_Stats->autoLearnBusy =
41902 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter);
41903 + p_Stats->discardedFragments =
41904 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter);
41905 + p_Stats->moreThan16Fragments =
41906 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter);
41907 +
41908 + return E_OK;
41909 +}
41910 +
41911 +static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip,
41912 + t_FmPcdManipFragCapwapStats *p_Stats)
41913 +{
41914 + t_AdOfTypeContLookup *p_Ad;
41915 +
41916 + ASSERT_COND(p_Manip);
41917 + ASSERT_COND(p_Stats);
41918 + ASSERT_COND(p_Manip->h_Ad);
41919 + ASSERT_COND(p_Manip->fragParams.p_Frag);
41920 +
41921 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41922 +
41923 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
41924 +
41925 + return E_OK;
41926 +}
41927 +
41928 +static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
41929 + t_FmPcdManip *p_Manip)
41930 +{
41931 + uint32_t maxSetNumber = 10000;
41932 + t_FmPcdManipReassemCapwapParams reassmManipParams =
41933 + p_ManipReassmParams->u.capwapReassem;
41934 + t_Error res;
41935 +
41936 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
41937 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
41938 + E_INVALID_HANDLE);
41939 +
41940 + /* Check validation of user's parameter.*/
41941 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
41942 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
41943 + RETURN_ERROR(
41944 + MAJOR, E_INVALID_VALUE,
41945 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
41946 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
41947 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
41948 + if (reassmManipParams.maxNumFramesInProcess
41949 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
41950 + RETURN_ERROR(
41951 + MAJOR,
41952 + E_INVALID_VALUE,
41953 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
41954 +
41955 + /* Saves user's reassembly manipulation parameters */
41956 + p_Manip->reassmParams.capwap.relativeSchemeId =
41957 + reassmManipParams.relativeSchemeId;
41958 + p_Manip->reassmParams.capwap.numOfFramesPerHashEntry =
41959 + reassmManipParams.numOfFramesPerHashEntry;
41960 + p_Manip->reassmParams.capwap.maxRessembledsSize =
41961 + reassmManipParams.maxReassembledFrameLength;
41962 + p_Manip->reassmParams.maxNumFramesInProcess =
41963 + reassmManipParams.maxNumFramesInProcess;
41964 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
41965 + p_Manip->reassmParams.fqidForTimeOutFrames =
41966 + reassmManipParams.fqidForTimeOutFrames;
41967 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
41968 + reassmManipParams.timeoutThresholdForReassmProcess;
41969 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
41970 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
41971 +
41972 + /* Creates and initializes the Reassembly common parameter table */
41973 + CreateReassCommonTable(p_Manip);
41974 +
41975 + res = SetCapwapReassmManip(p_Manip);
41976 + if (res != E_OK)
41977 + return res;
41978 +
41979 + return E_OK;
41980 +}
41981 +
41982 +static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams,
41983 + t_FmPcdManip *p_Manip)
41984 +{
41985 + t_FmPcd *p_FmPcd;
41986 + t_AdOfTypeContLookup *p_Ad;
41987 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
41988 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41989 +
41990 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
41991 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
41992 + E_INVALID_VALUE);
41993 + p_FmPcd = p_Manip->h_FmPcd;
41994 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
41995 +
41996 + /* Allocation of fragmentation Action Descriptor */
41997 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
41998 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
41999 + FM_PCD_CC_AD_TABLE_ALIGN);
42000 + if (!p_Manip->fragParams.p_Frag)
42001 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42002 + ("MURAM alloc for Fragmentation table descriptor"));
42003 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42004 +
42005 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
42006 + pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
42007 +
42008 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
42009 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
42010 + ccAdBaseReg |=
42011 + (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN :
42012 + 0;
42013 +
42014 + /* Set Scatter/Gather BPid */
42015 + if (p_ManipParams->sgBpidEn)
42016 + {
42017 + ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN;
42018 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
42019 + << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT)
42020 + & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK);
42021 + }
42022 +
42023 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
42024 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr))
42025 + - p_FmPcd->physicalMuramBase);
42026 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
42027 +
42028 + /* Set all Ad registers */
42029 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
42030 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
42031 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
42032 +
42033 + /* Saves user's fragmentation manipulation parameters */
42034 + p_Manip->frag = TRUE;
42035 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
42036 +
42037 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42038 +
42039 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
42040 + - (p_FmPcd->physicalMuramBase));
42041 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
42042 + << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT;
42043 +
42044 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42045 + tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK;
42046 +
42047 + tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA;
42048 +
42049 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42050 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
42051 + WRITE_UINT32(p_Ad->gmask, 0);
42052 + /* Total frame counter - MUST be initialized to zero.*/
42053 +
42054 + return E_OK;
42055 +}
42056 +
42057 +static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
42058 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
42059 + t_Handle h_Ad, bool validate)
42060 +{
42061 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
42062 + t_Error err;
42063 +
42064 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
42065 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION),
42066 + E_INVALID_STATE);
42067 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
42068 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
42069 +
42070 + UNUSED(h_FmPcd);
42071 + UNUSED(h_Ad);
42072 + UNUSED(h_PcdParams);
42073 + UNUSED(validate);
42074 + UNUSED(p_Manip);
42075 +
42076 + fmPortGetSetCcParams.setCcParams.type = 0;
42077 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
42078 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
42079 + RETURN_ERROR(MAJOR, err, NO_MSG);
42080 +
42081 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
42082 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
42083 +
42084 + return E_OK;
42085 +}
42086 +
42087 +static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams,
42088 + t_FmPcdManip *p_Manip)
42089 +{
42090 + t_AdOfTypeContLookup *p_Ad;
42091 + t_FmPcdManipSpecialOffloadCapwapParams *p_Params;
42092 + t_Error err = E_OK;
42093 + uint32_t tmpReg32 = 0;
42094 +
42095 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
42096 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
42097 +
42098 + p_Params = &p_ManipParams->u.specialOffload.u.capwap;
42099 +
42100 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42101 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42102 + tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0;
42103 + /* TODO - add 'qosSrc' */
42104 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42105 +
42106 + tmpReg32 = HMAN_OC_CAPWAP_MANIP;
42107 + if (p_ManipParams->h_NextManip)
42108 + {
42109 + WRITE_UINT32(
42110 + p_Ad->matchTblPtr,
42111 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
42112 +
42113 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN;
42114 + }
42115 +
42116 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42117 +
42118 + return err;
42119 +}
42120 +#endif /* (DPAA_VERSION >= 11) */
42121 +
42122 +static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params,
42123 + bool stats)
42124 +{
42125 + t_FmPcdManip *p_Manip;
42126 + t_Error err;
42127 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42128 +
42129 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
42130 + if (!p_Manip)
42131 + {
42132 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
42133 + return NULL;
42134 + }
42135 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
42136 +
42137 + p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type;
42138 + memcpy((uint8_t*)&p_Manip->manipParams, p_Params,
42139 + sizeof(p_Manip->manipParams));
42140 +
42141 + if (!stats)
42142 + err = CheckManipParamsAndSetType(p_Manip,
42143 + (t_FmPcdManipParams *)p_Params);
42144 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42145 + else
42146 + err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
42147 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42148 + else
42149 + {
42150 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!"));
42151 + XX_Free(p_Manip);
42152 + return NULL;
42153 + }
42154 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42155 + if (err)
42156 + {
42157 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type"));
42158 + XX_Free(p_Manip);
42159 + return NULL;
42160 + }
42161 +
42162 + if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY))
42163 + {
42164 + /* In Case of reassembly manipulation the reassembly action descriptor will
42165 + be defines later on */
42166 + if (p_Manip->muramAllocate)
42167 + {
42168 + p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(
42169 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
42170 + FM_PCD_CC_AD_TABLE_ALIGN);
42171 + if (!p_Manip->h_Ad)
42172 + {
42173 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor"));
42174 + ReleaseManipHandler(p_Manip, p_FmPcd);
42175 + XX_Free(p_Manip);
42176 + return NULL;
42177 + }
42178 +
42179 + MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42180 + }
42181 + else
42182 + {
42183 + p_Manip->h_Ad = (t_Handle)XX_Malloc(
42184 + FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42185 + if (!p_Manip->h_Ad)
42186 + {
42187 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
42188 + ReleaseManipHandler(p_Manip, p_FmPcd);
42189 + XX_Free(p_Manip);
42190 + return NULL;
42191 + }
42192 +
42193 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42194 + }
42195 + }
42196 +
42197 + p_Manip->h_FmPcd = h_FmPcd;
42198 +
42199 + return p_Manip;
42200 +}
42201 +
42202 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
42203 + t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst)
42204 +{
42205 + t_CcNodeInformation *p_CcNodeInformation;
42206 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL;
42207 + t_List *p_Pos;
42208 + int i = 0;
42209 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
42210 + t_CcNodeInformation ccNodeInfo;
42211 +
42212 + LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst)
42213 + {
42214 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
42215 + p_NodePtrOnCurrentMdfManip =
42216 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
42217 +
42218 + ASSERT_COND(p_NodePtrOnCurrentMdfManip);
42219 +
42220 + /* Search in the previous node which exact index points on this current modified node for getting AD */
42221 + for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++)
42222 + {
42223 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine
42224 + == e_FM_PCD_CC)
42225 + {
42226 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip
42227 + == (t_Handle)p_CrntMdfManip)
42228 + {
42229 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj)
42230 + p_AdTablePtOnCrntCurrentMdfNode =
42231 + p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
42232 + else
42233 + p_AdTablePtOnCrntCurrentMdfNode =
42234 + PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
42235 +
42236 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
42237 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
42238 + EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL);
42239 + }
42240 + }
42241 + }
42242 +
42243 + ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys);
42244 + }
42245 +}
42246 +
42247 +static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd,
42248 + t_FmPcd *p_FmPcd)
42249 +{
42250 + t_Error err;
42251 +
42252 + /* Copy the HMTD */
42253 + MemCpy8(p_Dest, (uint8_t*)p_Src, 16);
42254 + /* Replace the HMCT table pointer */
42255 + WRITE_UINT32(
42256 + ((t_Hmtd *)p_Dest)->hmcdBasePtr,
42257 + (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase));
42258 + /* Call Host Command to replace HMTD by a new HMTD */
42259 + err = FmHcPcdCcDoDynamicChange(
42260 + p_FmPcd->h_Hc,
42261 + (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase),
42262 + (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase));
42263 + if (err)
42264 + REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners."));
42265 +}
42266 +
42267 +static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42268 + t_Handle h_FmPort, t_Handle h_Manip,
42269 + t_Handle h_Ad, bool validate, int level,
42270 + t_Handle h_FmTree)
42271 +{
42272 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42273 + t_Error err = E_OK;
42274 +
42275 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42276 +
42277 + UNUSED(level);
42278 + UNUSED(h_FmTree);
42279 +
42280 + switch (p_Manip->opcode)
42281 + {
42282 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42283 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42284 + err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort,
42285 + p_Manip,
42286 + h_Ad,
42287 + validate);
42288 + break;
42289 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42290 + if (!p_Manip->h_Frag)
42291 + break;
42292 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42293 + err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
42294 + break;
42295 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42296 + if (p_Manip->h_Frag)
42297 + err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
42298 + break;
42299 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42300 + err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
42301 + break;
42302 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42303 + case (HMAN_OC_IP_REASSEMBLY):
42304 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42305 + validate);
42306 + break;
42307 + case (HMAN_OC_IP_FRAGMENTATION):
42308 + err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42309 + h_Ad, validate);
42310 + break;
42311 +#if (DPAA_VERSION >= 11)
42312 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42313 + err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42314 + h_Ad, validate);
42315 + break;
42316 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42317 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42318 + validate);
42319 + break;
42320 +#endif /* (DPAA_VERSION >= 11) */
42321 + default:
42322 + return E_OK;
42323 + }
42324 +
42325 + return err;
42326 +}
42327 +
42328 +static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad,
42329 + bool validate, int level,
42330 + t_Handle h_FmTree)
42331 +{
42332 +
42333 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42334 + t_Error err = E_OK;
42335 +
42336 + UNUSED(level);
42337 +
42338 + switch (p_Manip->opcode)
42339 + {
42340 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42341 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42342 + RETURN_ERROR(
42343 + MAJOR,
42344 + E_INVALID_STATE,
42345 + ("modify node with this type of manipulation is not suppported"));
42346 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42347 +
42348 + if (p_Manip->h_Frag)
42349 + {
42350 + if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS)
42351 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)
42352 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
42353 + RETURN_ERROR(
42354 + MAJOR,
42355 + E_INVALID_STATE,
42356 + ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function"));
42357 + }
42358 + break;
42359 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42360 + if (p_Manip->h_Frag)
42361 + err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
42362 + break;
42363 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42364 + default:
42365 + return E_OK;
42366 + }
42367 +
42368 + return err;
42369 +}
42370 +
42371 +/*****************************************************************************/
42372 +/* Inter-module API routines */
42373 +/*****************************************************************************/
42374 +
42375 +t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42376 + t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad,
42377 + bool validate, int level, t_Handle h_FmTree,
42378 + bool modify)
42379 +{
42380 + t_Error err;
42381 +
42382 + if (!modify)
42383 + err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip,
42384 + h_Ad, validate, level, h_FmTree);
42385 + else
42386 + err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
42387 +
42388 + return err;
42389 +}
42390 +
42391 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
42392 +{
42393 +
42394 + uint32_t intFlags;
42395 +
42396 + intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock);
42397 + if (add)
42398 + ((t_FmPcdManip *)h_Manip)->owner++;
42399 + else
42400 + {
42401 + ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
42402 + ((t_FmPcdManip *)h_Manip)->owner--;
42403 + }
42404 + XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags);
42405 +}
42406 +
42407 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)
42408 +{
42409 + ASSERT_COND(h_Manip);
42410 + return &((t_FmPcdManip *)h_Manip)->nodesLst;
42411 +}
42412 +
42413 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip)
42414 +{
42415 + ASSERT_COND(h_Manip);
42416 + return ((t_FmPcdManip *)h_Manip)->h_Spinlock;
42417 +}
42418 +
42419 +t_Error FmPcdManipCheckParamsForCcNextEngine(
42420 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
42421 + uint32_t *requiredAction)
42422 +{
42423 + t_FmPcdManip *p_Manip;
42424 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42425 + t_Error err = E_OK;
42426 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/
42427 + bool pointFromCc = TRUE;
42428 +
42429 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
42430 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip,
42431 + E_NULL_POINTER);
42432 +
42433 + p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
42434 + *requiredAction = 0;
42435 +
42436 + while (p_Manip)
42437 + {
42438 + switch (p_Manip->opcode)
42439 + {
42440 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42441 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42442 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42443 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42444 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42445 + p_Manip->cnia = TRUE;
42446 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42447 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42448 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42449 + p_Manip->ownerTmp++;
42450 + break;
42451 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42452 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42453 + && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42454 + RETURN_ERROR(
42455 + MAJOR,
42456 + E_INVALID_STATE,
42457 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
42458 + p_Manip->ownerTmp++;
42459 + break;
42460 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42461 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC)
42462 + && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
42463 + != CC_PC_GENERIC_IC_HASH_INDEXED))
42464 + 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"));
42465 + err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip,
42466 + FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
42467 + if (err)
42468 + RETURN_ERROR(MAJOR, err, NO_MSG);
42469 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42470 + break;
42471 + #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42472 + case (HMAN_OC_IP_FRAGMENTATION):
42473 + case (HMAN_OC_IP_REASSEMBLY):
42474 +#if (DPAA_VERSION >= 11)
42475 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42476 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42477 +#endif /* (DPAA_VERSION >= 11) */
42478 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42479 + RETURN_ERROR(
42480 + MAJOR,
42481 + E_INVALID_STATE,
42482 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42483 + p_Manip->ownerTmp++;
42484 + break;
42485 + case (HMAN_OC_IPSEC_MANIP):
42486 +#if (DPAA_VERSION >= 11)
42487 + case (HMAN_OC_CAPWAP_MANIP):
42488 +#endif /* (DPAA_VERSION >= 11) */
42489 + p_Manip->ownerTmp++;
42490 + break;
42491 + case (HMAN_OC):
42492 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
42493 + && MANIP_IS_CASCADED(p_Manip))
42494 + RETURN_ERROR(
42495 + MINOR,
42496 + E_INVALID_STATE,
42497 + ("Can't have a cascaded manipulation when and Next Engine is CC"));
42498 + if (!MANIP_IS_FIRST(p_Manip) && pointFromCc)
42499 + RETURN_ERROR(
42500 + MAJOR,
42501 + E_INVALID_STATE,
42502 + ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)"));
42503 + break;
42504 + default:
42505 + RETURN_ERROR(
42506 + MAJOR, E_INVALID_STATE,
42507 + ("invalid type of header manipulation for this state"));
42508 + }
42509 + p_Manip = p_Manip->h_NextManip;
42510 + pointFromCc = FALSE;
42511 + }
42512 + return E_OK;
42513 +}
42514 +
42515 +
42516 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip,
42517 + t_Handle h_FmPcdCcNode)
42518 +{
42519 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42520 + t_Error err = E_OK;
42521 +
42522 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42523 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
42524 +
42525 + switch (p_Manip->opcode)
42526 + {
42527 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42528 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42529 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42530 + RETURN_ERROR(
42531 + MAJOR,
42532 + E_INVALID_VALUE,
42533 + ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
42534 + break;
42535 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42536 + if (p_Manip->h_Frag)
42537 + {
42538 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42539 + RETURN_ERROR(
42540 + MAJOR,
42541 + E_INVALID_VALUE,
42542 + ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
42543 + err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
42544 + if (err)
42545 + RETURN_ERROR(MAJOR, err, NO_MSG);
42546 + }
42547 + break;
42548 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42549 + default:
42550 + break;
42551 + }
42552 +
42553 + return err;
42554 +}
42555 +
42556 +void FmPcdManipUpdateAdResultForCc(
42557 + t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
42558 + t_Handle p_Ad, t_Handle *p_AdNewPtr)
42559 +{
42560 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42561 +
42562 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42563 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42564 +
42565 + ASSERT_COND(p_Manip);
42566 + ASSERT_COND(p_CcNextEngineParams);
42567 + ASSERT_COND(p_Ad);
42568 + ASSERT_COND(p_AdNewPtr);
42569 +
42570 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42571 +
42572 + /* According to "type", either build & initialize a new AD (p_AdNew) or initialize
42573 + * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */
42574 + switch (p_Manip->opcode)
42575 + {
42576 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42577 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42578 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42579 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42580 + *p_AdNewPtr = p_Manip->h_Ad;
42581 + break;
42582 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42583 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42584 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,
42585 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
42586 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,
42587 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
42588 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,
42589 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
42590 + *p_AdNewPtr = NULL;
42591 + break;
42592 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42593 + case (HMAN_OC_IPSEC_MANIP):
42594 +#if (DPAA_VERSION >= 11)
42595 + case (HMAN_OC_CAPWAP_MANIP):
42596 +#endif /* (DPAA_VERSION >= 11) */
42597 + *p_AdNewPtr = p_Manip->h_Ad;
42598 + break;
42599 + case (HMAN_OC_IP_FRAGMENTATION):
42600 +#if (DPAA_VERSION >= 11)
42601 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42602 +#endif /* (DPAA_VERSION >= 11) */
42603 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE)
42604 + && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid))
42605 + {
42606 + memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad,
42607 + sizeof(t_AdOfTypeContLookup));
42608 +#if (DPAA_VERSION >= 11)
42609 + WRITE_UINT32(
42610 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42611 + GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA);
42612 +#endif /* (DPAA_VERSION >= 11) */
42613 + *p_AdNewPtr = NULL;
42614 + }
42615 + else
42616 + *p_AdNewPtr = p_Manip->h_Ad;
42617 + break;
42618 + case (HMAN_OC_IP_REASSEMBLY):
42619 + if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip))
42620 + {
42621 + if (!p_Manip->reassmParams.ip.ipv6Assigned)
42622 + {
42623 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad;
42624 + p_Manip->reassmParams.ip.ipv6Assigned = TRUE;
42625 + FmPcdManipUpdateOwner(h_Manip, FALSE);
42626 + }
42627 + else
42628 + {
42629 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42630 + p_Manip->reassmParams.ip.ipv6Assigned = FALSE;
42631 + }
42632 + }
42633 + else
42634 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42635 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42636 + sizeof(t_AdOfTypeContLookup));
42637 + *p_AdNewPtr = NULL;
42638 + break;
42639 +#if (DPAA_VERSION >= 11)
42640 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42641 + *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad;
42642 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42643 + sizeof(t_AdOfTypeContLookup));
42644 + *p_AdNewPtr = NULL;
42645 + break;
42646 +#endif /* (DPAA_VERSION >= 11) */
42647 + case (HMAN_OC):
42648 + /* Allocate and initialize HMTD */
42649 + *p_AdNewPtr = p_Manip->h_Ad;
42650 + break;
42651 + default:
42652 + break;
42653 + }
42654 +}
42655 +
42656 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad,
42657 + t_Handle *p_AdNewPtr,
42658 + uint32_t adTableOffset)
42659 +{
42660 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42661 +
42662 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42663 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42664 + ASSERT_COND(p_Manip);
42665 +
42666 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42667 +
42668 + switch (p_Manip->opcode)
42669 + {
42670 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42671 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42672 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42673 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
42674 + WRITE_UINT32(
42675 + ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr,
42676 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
42677 + WRITE_UINT32(
42678 + ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets,
42679 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
42680 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask,
42681 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
42682 + WRITE_UINT32(
42683 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42684 + (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
42685 + *p_AdNewPtr = NULL;
42686 + break;
42687 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42688 + case (HMAN_OC):
42689 + /* Initialize HMTD within the match table*/
42690 + MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42691 + /* copy the existing HMTD *//* ask Alla - memcpy??? */
42692 + memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd));
42693 + /* update NADEN to be "1"*/
42694 + WRITE_UINT16(
42695 + ((t_Hmtd *)p_Ad)->cfg,
42696 + (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN));
42697 + /* update next action descriptor */
42698 + WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx,
42699 + (uint16_t)(adTableOffset >> 4));
42700 + /* mark that Manip's HMTD is not used */
42701 + *p_AdNewPtr = NULL;
42702 + break;
42703 +
42704 + default:
42705 + break;
42706 + }
42707 +}
42708 +
42709 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
42710 + t_Handle h_CcTree, t_Handle h_Manip,
42711 + bool isIpv4, uint8_t groupId)
42712 +{
42713 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42714 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
42715 + t_Handle h_Scheme;
42716 +
42717 + ASSERT_COND(p_FmPcd);
42718 + ASSERT_COND(h_NetEnv);
42719 + ASSERT_COND(p_Manip);
42720 +
42721 + /* scheme was already build, no need to check for IPv6 */
42722 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
42723 + return E_OK;
42724 +
42725 + if (isIpv4) {
42726 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]);
42727 + if (h_Scheme) {
42728 + /* scheme was found */
42729 + p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme;
42730 + return E_OK;
42731 + }
42732 + } else {
42733 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]);
42734 + if (h_Scheme) {
42735 + /* scheme was found */
42736 + p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme;
42737 + return E_OK;
42738 + }
42739 + }
42740 +
42741 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
42742 + if (!p_SchemeParams)
42743 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42744 + ("Memory allocation failed for scheme"));
42745 +
42746 + /* Configures the IPv4 or IPv6 scheme*/
42747 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
42748 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
42749 + p_SchemeParams->id.relativeSchemeId = (uint8_t)(
42750 + (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] :
42751 + p_Manip->reassmParams.ip.relativeSchemeId[1]);
42752 + p_SchemeParams->schemeCounter.update = TRUE;
42753 +#if (DPAA_VERSION >= 11)
42754 + p_SchemeParams->alwaysDirect = TRUE;
42755 + p_SchemeParams->bypassFqidGeneration = TRUE;
42756 +#else
42757 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1;
42758 + p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/
42759 +#endif /* (DPAA_VERSION >= 11) */
42760 +
42761 + setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId);
42762 +
42763 + /* Sets the new scheme */
42764 + if (isIpv4)
42765 + p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet(
42766 + p_FmPcd, p_SchemeParams);
42767 + else
42768 + p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet(
42769 + p_FmPcd, p_SchemeParams);
42770 +
42771 + XX_Free(p_SchemeParams);
42772 +
42773 + return E_OK;
42774 +}
42775 +
42776 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)
42777 +{
42778 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42779 +
42780 + ASSERT_COND(p_Manip);
42781 +
42782 + if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) &&
42783 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme))
42784 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme);
42785 +
42786 + if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) &&
42787 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme))
42788 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme);
42789 +
42790 + return E_OK;
42791 +}
42792 +
42793 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip)
42794 +{
42795 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42796 +
42797 + ASSERT_COND(p_Manip);
42798 +
42799 + return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6);
42800 +}
42801 +
42802 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
42803 + t_Handle h_CcTree, t_Handle h_Manip,
42804 + uint8_t groupId)
42805 +{
42806 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42807 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
42808 +
42809 + ASSERT_COND(p_FmPcd);
42810 + ASSERT_COND(h_NetEnv);
42811 + ASSERT_COND(p_Manip);
42812 +
42813 + /* scheme was already build, no need to check for IPv6 */
42814 + if (p_Manip->reassmParams.capwap.h_Scheme)
42815 + return E_OK;
42816 +
42817 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
42818 + if (!p_SchemeParams)
42819 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42820 + ("Memory allocation failed for scheme"));
42821 +
42822 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
42823 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
42824 + p_SchemeParams->id.relativeSchemeId =
42825 + (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId;
42826 + p_SchemeParams->schemeCounter.update = TRUE;
42827 + p_SchemeParams->bypassFqidGeneration = TRUE;
42828 +
42829 + setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId);
42830 +
42831 + p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd,
42832 + p_SchemeParams);
42833 +
42834 + XX_Free(p_SchemeParams);
42835 +
42836 + return E_OK;
42837 +}
42838 +
42839 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip)
42840 +{
42841 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42842 +
42843 + ASSERT_COND(p_Manip);
42844 +
42845 + if (p_Manip->reassmParams.capwap.h_Scheme)
42846 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme);
42847 +
42848 + return E_OK;
42849 +}
42850 +
42851 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42852 +t_Handle FmPcdManipApplSpecificBuild(void)
42853 +{
42854 + t_FmPcdManip *p_Manip;
42855 +
42856 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
42857 + if (!p_Manip)
42858 + {
42859 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
42860 + return NULL;
42861 + }
42862 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
42863 +
42864 + p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
42865 + p_Manip->muramAllocate = FALSE;
42866 +
42867 + p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42868 + if (!p_Manip->h_Ad)
42869 + {
42870 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
42871 + XX_Free(p_Manip);
42872 + return NULL;
42873 + }
42874 +
42875 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42876 +
42877 + /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/
42878 + /*Application specific = type of flowId index, move internal frame header from data to IC,
42879 + SEC errors check*/
42880 + if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK)
42881 + {
42882 + XX_Free(p_Manip->h_Ad);
42883 + XX_Free(p_Manip);
42884 + return NULL;
42885 + }
42886 + return p_Manip;
42887 +}
42888 +
42889 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip)
42890 +{
42891 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42892 + ASSERT_COND(h_Manip);
42893 +
42894 + return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE);
42895 +}
42896 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42897 +/*********************** End of inter-module routines ************************/
42898 +
42899 +/****************************************/
42900 +/* API Init unit functions */
42901 +/****************************************/
42902 +
42903 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd,
42904 + t_FmPcdManipParams *p_ManipParams)
42905 +{
42906 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42907 + t_FmPcdManip *p_Manip;
42908 + t_Error err;
42909 +
42910 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
42911 + SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL);
42912 +
42913 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
42914 + if (!p_Manip)
42915 + return NULL;
42916 +
42917 + if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY)
42918 + || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION)
42919 + || (p_Manip->opcode == HMAN_OC)
42920 + || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP)
42921 +#if (DPAA_VERSION >= 11)
42922 + || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP)
42923 + || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION)
42924 + || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
42925 +#endif /* (DPAA_VERSION >= 11) */
42926 + ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd)))
42927 + {
42928 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
42929 + XX_Free(p_Manip);
42930 + return NULL;
42931 + }
42932 + p_Manip->h_Spinlock = XX_InitSpinlock();
42933 + if (!p_Manip->h_Spinlock)
42934 + {
42935 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
42936 + ReleaseManipHandler(p_Manip, p_FmPcd);
42937 + XX_Free(p_Manip);
42938 + return NULL;
42939 + }INIT_LIST(&p_Manip->nodesLst);
42940 +
42941 + switch (p_Manip->opcode)
42942 + {
42943 + case (HMAN_OC_IP_REASSEMBLY):
42944 + /* IpReassembly */
42945 + err = IpReassembly(&p_ManipParams->u.reassem, p_Manip);
42946 + break;
42947 + case (HMAN_OC_IP_FRAGMENTATION):
42948 + /* IpFragmentation */
42949 + err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip);
42950 + if (err)
42951 + break;
42952 + err = IPManip(p_Manip);
42953 + break;
42954 + case (HMAN_OC_IPSEC_MANIP):
42955 + err = IPSecManip(p_ManipParams, p_Manip);
42956 + break;
42957 +#if (DPAA_VERSION >= 11)
42958 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42959 + /* CapwapReassembly */
42960 + err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip);
42961 + break;
42962 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42963 + /* CapwapFragmentation */
42964 + err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag,
42965 + p_Manip);
42966 + break;
42967 + case (HMAN_OC_CAPWAP_MANIP):
42968 + err = CapwapManip(p_ManipParams, p_Manip);
42969 + break;
42970 +#endif /* (DPAA_VERSION >= 11) */
42971 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42972 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42973 + /* HmanType1 */
42974 + err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip);
42975 + break;
42976 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42977 + err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams,
42978 + p_Manip,
42979 + p_FmPcd,
42980 + p_ManipParams->fragOrReasmParams.sgBpid);
42981 + if (err)
42982 + {
42983 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
42984 + ReleaseManipHandler(p_Manip, p_FmPcd);
42985 + XX_Free(p_Manip);
42986 + return NULL;
42987 + }
42988 + if (p_Manip->insrt)
42989 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
42990 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42991 + /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
42992 + err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd);
42993 + break;
42994 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42995 + err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams,
42996 + p_Manip,
42997 + p_FmPcd,
42998 + p_ManipParams->fragOrReasmParams.sgBpid);
42999 + if (err)
43000 + {
43001 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43002 + ReleaseManipHandler(p_Manip, p_FmPcd);
43003 + XX_Free(p_Manip);
43004 + return NULL;
43005 + }
43006 + if (p_Manip->rmv)
43007 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
43008 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
43009 + /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
43010 + err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
43011 + break;
43012 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
43013 + /*Application Specific type 1*/
43014 + err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE);
43015 + break;
43016 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43017 + case (HMAN_OC):
43018 + /* New Manip */
43019 + err = CreateManipActionNew(p_Manip, p_ManipParams);
43020 + break;
43021 + default:
43022 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43023 + ReleaseManipHandler(p_Manip, p_FmPcd);
43024 + XX_Free(p_Manip);
43025 + return NULL;
43026 + }
43027 +
43028 + if (err)
43029 + {
43030 + REPORT_ERROR(MAJOR, err, NO_MSG);
43031 + ReleaseManipHandler(p_Manip, p_FmPcd);
43032 + XX_Free(p_Manip);
43033 + return NULL;
43034 + }
43035 +
43036 + if (p_ManipParams->h_NextManip)
43037 + {
43038 + /* in the check routine we've verified that h_NextManip has no owners
43039 + * and that only supported types are allowed. */
43040 + p_Manip->h_NextManip = p_ManipParams->h_NextManip;
43041 + /* save a "prev" pointer in h_NextManip */
43042 + MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip);
43043 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE);
43044 + }
43045 +
43046 + return p_Manip;
43047 +}
43048 +
43049 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip,
43050 + t_FmPcdManipParams *p_ManipParams)
43051 +{
43052 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip;
43053 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd);
43054 + t_Error err;
43055 + uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL;
43056 + t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos;
43057 + t_CcNodeInformation *p_CcNodeInfo;
43058 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
43059 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
43060 +
43061 + INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip);
43062 +
43063 + if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR)
43064 + || (p_Manip->type != e_FM_PCD_MANIP_HDR))
43065 + RETURN_ERROR(
43066 + MINOR,
43067 + E_NOT_SUPPORTED,
43068 + ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation."));
43069 +
43070 + ASSERT_COND(p_Manip->opcode == HMAN_OC);
43071 + ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip);
43072 + memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams,
43073 + sizeof(p_Manip->manipParams));
43074 + p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip;
43075 +
43076 + /* The replacement of the HdrManip depends on the node type.*/
43077 + /*
43078 + * (1) If this is an independent node, all its owners should be updated.
43079 + *
43080 + * (2) If it is the head of a cascaded chain (it does not have a "prev" but
43081 + * it has a "next" and it has a "cascaded" indication), the next
43082 + * node remains unchanged, and the behavior is as in (1).
43083 + *
43084 + * (3) If it is not the head, but a part of a cascaded chain, in can be
43085 + * also replaced as a regular node with just one owner.
43086 + *
43087 + * (4) If it is a part of a chain implemented as a unified table, the
43088 + * whole table is replaced and the owners of the head node must be updated.
43089 + *
43090 + */
43091 + /* lock shadow */
43092 + if (!p_FmPcd->p_CcShadow)
43093 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
43094 +
43095 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
43096 + return ERROR_CODE(E_BUSY);
43097 +
43098 + /* this routine creates a new manip action in the CC Shadow. */
43099 + err = CreateManipActionShadow(p_Manip, p_ManipParams);
43100 + if (err)
43101 + RETURN_ERROR(MINOR, err, NO_MSG);
43102 +
43103 + /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC)
43104 + * replace only HMTD and no lcok is required. Otherwise
43105 + * lock the whole PCD
43106 + * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */
43107 + if (!FmPcdLockTryLockAll(p_FmPcd))
43108 + {
43109 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
43110 + return ERROR_CODE(E_BUSY);
43111 + }
43112 +
43113 + p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
43114 +
43115 + p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip,
43116 + e_MANIP_HANDLER_TABLE_OWNER);
43117 + ASSERT_COND(p_FirstManip);
43118 +
43119 + if (!LIST_IsEmpty(&p_FirstManip->nodesLst))
43120 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
43121 + p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip);
43122 +
43123 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
43124 + ASSERT_COND(p_Hmtd);
43125 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct,
43126 + ((t_FmPcd*)(p_Manip->h_FmPcd)));
43127 +
43128 + LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43129 + {
43130 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43131 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43132 + p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43133 + }
43134 +
43135 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
43136 + ASSERT_COND(p_WholeHmct);
43137 +
43138 + /* re-build the HMCT n the original location */
43139 + err = CreateManipActionBackToOrig(p_Manip, p_ManipParams);
43140 + if (err)
43141 + {
43142 + RELEASE_LOCK(p_FmPcd->shadowLock);
43143 + RETURN_ERROR(MINOR, err, NO_MSG);
43144 + }
43145 +
43146 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
43147 + ASSERT_COND(p_Hmtd);
43148 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct,
43149 + ((t_FmPcd*)p_Manip->h_FmPcd));
43150 +
43151 + /* If LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list.
43152 + * For each p_Hmct (from list+fixed):
43153 + * call Host Command to replace HMTD by a new one */LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43154 + {
43155 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43156 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43157 + p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43158 + }
43159 +
43160 +
43161 + ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip);
43162 +
43163 + FmPcdLockUnlockAll(p_FmPcd);
43164 +
43165 + /* unlock shadow */
43166 + RELEASE_LOCK(p_FmPcd->shadowLock);
43167 +
43168 + return E_OK;
43169 +}
43170 +
43171 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode)
43172 +{
43173 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43174 +
43175 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43176 +
43177 + if (p_Manip->owner)
43178 + RETURN_ERROR(
43179 + MAJOR,
43180 + E_INVALID_STATE,
43181 + ("This manipulation node not be removed because this node is occupied, first - unbind this node "));
43182 +
43183 + if (p_Manip->h_NextManip)
43184 + {
43185 + MANIP_SET_PREV(p_Manip->h_NextManip, NULL);
43186 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE);
43187 + }
43188 +
43189 + if (p_Manip->p_Hmct
43190 + && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip)))
43191 + FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram,
43192 + p_Manip->p_Hmct);
43193 +
43194 + if (p_Manip->h_Spinlock)
43195 + {
43196 + XX_FreeSpinlock(p_Manip->h_Spinlock);
43197 + p_Manip->h_Spinlock = NULL;
43198 + }
43199 +
43200 + ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd);
43201 +
43202 + XX_Free(h_ManipNode);
43203 +
43204 + return E_OK;
43205 +}
43206 +
43207 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode,
43208 + t_FmPcdManipStats *p_FmPcdManipStats)
43209 +{
43210 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43211 +
43212 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43213 + SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER);
43214 +
43215 + switch (p_Manip->opcode)
43216 + {
43217 + case (HMAN_OC_IP_REASSEMBLY):
43218 + return IpReassemblyStats(p_Manip,
43219 + &p_FmPcdManipStats->u.reassem.u.ipReassem);
43220 + case (HMAN_OC_IP_FRAGMENTATION):
43221 + return IpFragmentationStats(p_Manip,
43222 + &p_FmPcdManipStats->u.frag.u.ipFrag);
43223 +#if (DPAA_VERSION >= 11)
43224 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43225 + return CapwapReassemblyStats(
43226 + p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem);
43227 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43228 + return CapwapFragmentationStats(
43229 + p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag);
43230 +#endif /* (DPAA_VERSION >= 11) */
43231 + default:
43232 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
43233 + ("no statistics to this type of manip"));
43234 + }
43235 +
43236 + return E_OK;
43237 +}
43238 +
43239 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43240 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
43241 +{
43242 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
43243 + t_FmPcdManip *p_Manip;
43244 + t_Error err;
43245 +
43246 + SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
43247 + SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
43248 +
43249 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
43250 + if (!p_Manip)
43251 + return NULL;
43252 +
43253 + switch (p_Manip->opcode)
43254 + {
43255 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
43256 + /* Indexed statistics */
43257 + err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
43258 + break;
43259 + default:
43260 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
43261 + ReleaseManipHandler(p_Manip, p_FmPcd);
43262 + XX_Free(p_Manip);
43263 + return NULL;
43264 + }
43265 +
43266 + if (err)
43267 + {
43268 + REPORT_ERROR(MAJOR, err, NO_MSG);
43269 + ReleaseManipHandler(p_Manip, p_FmPcd);
43270 + XX_Free(p_Manip);
43271 + return NULL;
43272 + }
43273 +
43274 + return p_Manip;
43275 +}
43276 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43277 --- /dev/null
43278 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
43279 @@ -0,0 +1,555 @@
43280 +/*
43281 + * Copyright 2008-2012 Freescale Semiconductor Inc.
43282 + *
43283 + * Redistribution and use in source and binary forms, with or without
43284 + * modification, are permitted provided that the following conditions are met:
43285 + * * Redistributions of source code must retain the above copyright
43286 + * notice, this list of conditions and the following disclaimer.
43287 + * * Redistributions in binary form must reproduce the above copyright
43288 + * notice, this list of conditions and the following disclaimer in the
43289 + * documentation and/or other materials provided with the distribution.
43290 + * * Neither the name of Freescale Semiconductor nor the
43291 + * names of its contributors may be used to endorse or promote products
43292 + * derived from this software without specific prior written permission.
43293 + *
43294 + *
43295 + * ALTERNATIVELY, this software may be distributed under the terms of the
43296 + * GNU General Public License ("GPL") as published by the Free Software
43297 + * Foundation, either version 2 of that License or (at your option) any
43298 + * later version.
43299 + *
43300 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
43301 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43302 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43303 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
43304 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43305 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43306 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43307 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43308 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43309 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43310 + */
43311 +
43312 +
43313 +/******************************************************************************
43314 + @File fm_manip.h
43315 +
43316 + @Description FM PCD manip...
43317 +*//***************************************************************************/
43318 +#ifndef __FM_MANIP_H
43319 +#define __FM_MANIP_H
43320 +
43321 +#include "std_ext.h"
43322 +#include "error_ext.h"
43323 +#include "list_ext.h"
43324 +
43325 +#include "fm_cc.h"
43326 +
43327 +
43328 +/***********************************************************************/
43329 +/* Header manipulations defines */
43330 +/***********************************************************************/
43331 +
43332 +#define NUM_OF_SCRATCH_POOL_BUFFERS 1000 /*TODO - Change it!!*/
43333 +
43334 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43335 +#define HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR 0x2e
43336 +#define HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER 0x31
43337 +#define HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX 0x2f
43338 +#define HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST 0x30
43339 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x11 /* dummy */
43340 +#define HMAN_OC_CAPWAP_INDEXED_STATS 0x32 /* dummy */
43341 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43342 +#else
43343 +#define HMAN_OC_CAPWAP_MANIP 0x2F
43344 +#define HMAN_OC_CAPWAP_FRAG_CHECK 0x2E
43345 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43346 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x30
43347 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43348 +#define HMAN_OC_IP_MANIP 0x34
43349 +#define HMAN_OC_IP_FRAGMENTATION 0x74
43350 +#define HMAN_OC_IP_REASSEMBLY 0xB4
43351 +#define HMAN_OC_IPSEC_MANIP 0xF4
43352 +#define HMAN_OC 0x35
43353 +
43354 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43355 +#define HMAN_RMV_HDR 0x80000000
43356 +#define HMAN_INSRT_INT_FRM_HDR 0x40000000
43357 +
43358 +#define UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP 6
43359 +#define UDP_CHECKSUM_FIELD_SIZE 2
43360 +#define UDP_LENGTH_FIELD_OFFSET_FROM_UDP 4
43361 +
43362 +#define IPv4_DSCECN_FIELD_OFFSET_FROM_IP 1
43363 +#define IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2
43364 +#define IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10
43365 +#define VLAN_TAG_FIELD_OFFSET_FROM_ETH 12
43366 +#define IPv4_ID_FIELD_OFFSET_FROM_IP 4
43367 +
43368 +#define IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP 4
43369 +#define IPv6_NEXT_HEADER_OFFSET_FROM_IP 6
43370 +
43371 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 0x80
43372 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN 8
43373 +#define FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE 32
43374 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE 4
43375 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE 8
43376 +
43377 +
43378 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES 0x40000000
43379 +#define FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG 0x10000000
43380 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS 0x08000000
43381 +#define FM_PCD_MANIP_CAPWAP_REASM_PR_COPY 0x00800000
43382 +
43383 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN 0x80000000
43384 +
43385 +#define FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE 4
43386 +#define FM_PCD_MANIP_INDEXED_STATS_CNIA 0x20000000
43387 +#define FM_PCD_MANIP_INDEXED_STATS_DPD 0x10000000
43388 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43389 +
43390 +#if (DPAA_VERSION >= 11)
43391 +#define FM_PCD_MANIP_CAPWAP_DTLS 0x00040000
43392 +#define FM_PCD_MANIP_CAPWAP_NADEN 0x20000000
43393 +
43394 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT 16
43395 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_NO_FRAGMENTATION 0xFFFF0000
43396 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA 0x20000000
43397 +
43398 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN 0x04000000
43399 +#define FM_PCD_MANIP_CAPWAP_FRAG_SCRATCH_BPID 24
43400 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN 0x08000000
43401 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK 0xFF000000
43402 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT 24
43403 +#endif /* (DPAA_VERSION >= 11) */
43404 +
43405 +#define FM_PCD_MANIP_REASM_TABLE_SIZE 0x40
43406 +#define FM_PCD_MANIP_REASM_TABLE_ALIGN 8
43407 +
43408 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE 64
43409 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN 8
43410 +#define FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000
43411 +#define FM_PCD_MANIP_REASM_COUPLING_ENABLE 0x40000000
43412 +#define FM_PCD_MANIP_REASM_COUPLING_MASK 0xFF000000
43413 +#define FM_PCD_MANIP_REASM_COUPLING_SHIFT 24
43414 +#define FM_PCD_MANIP_REASM_LIODN_MASK 0x0000003F
43415 +#define FM_PCD_MANIP_REASM_LIODN_SHIFT 56
43416 +#define FM_PCD_MANIP_REASM_ELIODN_MASK 0x000003c0
43417 +#define FM_PCD_MANIP_REASM_ELIODN_SHIFT 38
43418 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_MASK 0x000000FF
43419 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT 24
43420 +#define FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH 1024
43421 +
43422 +#define FM_PCD_MANIP_IP_MTU_SHIFT 16
43423 +#define FM_PCD_MANIP_IP_NO_FRAGMENTATION 0xFFFF0000
43424 +#define FM_PCD_MANIP_IP_CNIA 0x20000000
43425 +
43426 +#define FM_PCD_MANIP_IP_FRAG_DF_SHIFT 28
43427 +#define FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID 24
43428 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_EN 0x08000000
43429 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK 0xFF000000
43430 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT 24
43431 +
43432 +#define FM_PCD_MANIP_IPSEC_DEC 0x10000000
43433 +#define FM_PCD_MANIP_IPSEC_VIPV_EN 0x08000000
43434 +#define FM_PCD_MANIP_IPSEC_ECN_EN 0x04000000
43435 +#define FM_PCD_MANIP_IPSEC_DSCP_EN 0x02000000
43436 +#define FM_PCD_MANIP_IPSEC_VIPL_EN 0x01000000
43437 +#define FM_PCD_MANIP_IPSEC_NADEN 0x20000000
43438 +
43439 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_MASK 0x00FF0000
43440 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT 16
43441 +
43442 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_MASK 0xFFFF0000
43443 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT 16
43444 +
43445 +#define e_FM_MANIP_IP_INDX 1
43446 +
43447 +#define HMCD_OPCODE_GENERIC_RMV 0x01
43448 +#define HMCD_OPCODE_GENERIC_INSRT 0x02
43449 +#define HMCD_OPCODE_GENERIC_REPLACE 0x05
43450 +#define HMCD_OPCODE_L2_RMV 0x08
43451 +#define HMCD_OPCODE_L2_INSRT 0x09
43452 +#define HMCD_OPCODE_VLAN_PRI_UPDATE 0x0B
43453 +#define HMCD_OPCODE_IPV4_UPDATE 0x0C
43454 +#define HMCD_OPCODE_IPV6_UPDATE 0x10
43455 +#define HMCD_OPCODE_TCP_UDP_UPDATE 0x0E
43456 +#define HMCD_OPCODE_TCP_UDP_CHECKSUM 0x14
43457 +#define HMCD_OPCODE_REPLACE_IP 0x12
43458 +#define HMCD_OPCODE_RMV_TILL 0x15
43459 +#define HMCD_OPCODE_UDP_INSRT 0x16
43460 +#define HMCD_OPCODE_IP_INSRT 0x17
43461 +#define HMCD_OPCODE_CAPWAP_RMV 0x18
43462 +#define HMCD_OPCODE_CAPWAP_INSRT 0x18
43463 +#define HMCD_OPCODE_GEN_FIELD_REPLACE 0x19
43464 +
43465 +#define HMCD_LAST 0x00800000
43466 +
43467 +#define HMCD_DSCP_VALUES 64
43468 +
43469 +#define HMCD_BASIC_SIZE 4
43470 +#define HMCD_PTR_SIZE 4
43471 +#define HMCD_PARAM_SIZE 4
43472 +#define HMCD_IPV4_ADDR_SIZE 4
43473 +#define HMCD_IPV6_ADDR_SIZE 0x10
43474 +#define HMCD_L4_HDR_SIZE 8
43475 +
43476 +#define HMCD_CAPWAP_INSRT 0x00010000
43477 +#define HMCD_INSRT_UDP_LITE 0x00010000
43478 +#define HMCD_IP_ID_MASK 0x0000FFFF
43479 +#define HMCD_IP_SIZE_MASK 0x0000FF00
43480 +#define HMCD_IP_SIZE_SHIFT 8
43481 +#define HMCD_IP_LAST_PID_MASK 0x000000FF
43482 +#define HMCD_IP_OR_QOS 0x00010000
43483 +#define HMCD_IP_L4_CS_CALC 0x00040000
43484 +#define HMCD_IP_DF_MODE 0x00400000
43485 +
43486 +
43487 +#define HMCD_OC_SHIFT 24
43488 +
43489 +#define HMCD_RMV_OFFSET_SHIFT 0
43490 +#define HMCD_RMV_SIZE_SHIFT 8
43491 +
43492 +#define HMCD_INSRT_OFFSET_SHIFT 0
43493 +#define HMCD_INSRT_SIZE_SHIFT 8
43494 +
43495 +#define HMTD_CFG_TYPE 0x4000
43496 +#define HMTD_CFG_EXT_HMCT 0x0080
43497 +#define HMTD_CFG_PRS_AFTER_HM 0x0040
43498 +#define HMTD_CFG_NEXT_AD_EN 0x0020
43499 +
43500 +#define HMCD_RMV_L2_ETHERNET 0
43501 +#define HMCD_RMV_L2_STACKED_QTAGS 1
43502 +#define HMCD_RMV_L2_ETHERNET_AND_MPLS 2
43503 +#define HMCD_RMV_L2_MPLS 3
43504 +#define HMCD_RMV_L2_PPPOE 4
43505 +
43506 +#define HMCD_INSRT_L2_MPLS 0
43507 +#define HMCD_INSRT_N_UPDATE_L2_MPLS 1
43508 +#define HMCD_INSRT_L2_PPPOE 2
43509 +#define HMCD_INSRT_L2_SIZE_SHIFT 24
43510 +
43511 +#define HMCD_L2_MODE_SHIFT 16
43512 +
43513 +#define HMCD_VLAN_PRI_REP_MODE_SHIFT 16
43514 +#define HMCD_VLAN_PRI_UPDATE 0
43515 +#define HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI 1
43516 +
43517 +#define HMCD_IPV4_UPDATE_TTL 0x00000001
43518 +#define HMCD_IPV4_UPDATE_TOS 0x00000002
43519 +#define HMCD_IPV4_UPDATE_DST 0x00000020
43520 +#define HMCD_IPV4_UPDATE_SRC 0x00000040
43521 +#define HMCD_IPV4_UPDATE_ID 0x00000080
43522 +#define HMCD_IPV4_UPDATE_TOS_SHIFT 8
43523 +
43524 +#define HMCD_IPV6_UPDATE_HL 0x00000001
43525 +#define HMCD_IPV6_UPDATE_TC 0x00000002
43526 +#define HMCD_IPV6_UPDATE_DST 0x00000040
43527 +#define HMCD_IPV6_UPDATE_SRC 0x00000080
43528 +#define HMCD_IPV6_UPDATE_TC_SHIFT 8
43529 +
43530 +#define HMCD_TCP_UDP_UPDATE_DST 0x00004000
43531 +#define HMCD_TCP_UDP_UPDATE_SRC 0x00008000
43532 +#define HMCD_TCP_UDP_UPDATE_SRC_SHIFT 16
43533 +
43534 +#define HMCD_IP_REPLACE_REPLACE_IPV4 0x00000000
43535 +#define HMCD_IP_REPLACE_REPLACE_IPV6 0x00010000
43536 +#define HMCD_IP_REPLACE_TTL_HL 0x00200000
43537 +#define HMCD_IP_REPLACE_ID 0x00400000
43538 +
43539 +#define HMCD_IP_REPLACE_L3HDRSIZE_SHIFT 24
43540 +
43541 +#define HMCD_GEN_FIELD_SIZE_SHIFT 16
43542 +#define HMCD_GEN_FIELD_SRC_OFF_SHIFT 8
43543 +#define HMCD_GEN_FIELD_DST_OFF_SHIFT 0
43544 +#define HMCD_GEN_FIELD_MASK_EN 0x00400000
43545 +
43546 +#define HMCD_GEN_FIELD_MASK_OFF_SHIFT 16
43547 +#define HMCD_GEN_FIELD_MASK_SHIFT 24
43548 +
43549 +#define DSCP_TO_VLAN_TABLE_SIZE 32
43550 +
43551 +#define MANIP_GET_HMCT_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->tableSize)
43552 +#define MANIP_GET_DATA_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->dataSize)
43553 +
43554 +#define MANIP_GET_HMCT_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Hmct)
43555 +#define MANIP_GET_DATA_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Data)
43556 +
43557 +#define MANIP_SET_HMCT_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Hmct = h_NewPtr)
43558 +#define MANIP_SET_DATA_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Data = h_NewPtr)
43559 +
43560 +#define MANIP_GET_HMTD_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->h_Ad)
43561 +#define MANIP_DONT_REPARSE(h_Manip) (((t_FmPcdManip *)h_Manip)->dontParseAfterManip)
43562 +#define MANIP_SET_PREV(h_Manip, h_Prev) (((t_FmPcdManip *)h_Manip)->h_PrevManip = h_Prev)
43563 +#define MANIP_GET_OWNERS(h_Manip) (((t_FmPcdManip *)h_Manip)->owner)
43564 +#define MANIP_GET_TYPE(h_Manip) (((t_FmPcdManip *)h_Manip)->type)
43565 +#define MANIP_SET_UNIFIED_TBL_PTR_INDICATION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedTablePtr = TRUE)
43566 +#define MANIP_GET_MURAM(h_Manip) (((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram)
43567 +#define MANIP_FREE_HMTD(h_Manip) \
43568 + {if (((t_FmPcdManip *)h_Manip)->muramAllocate) \
43569 + FM_MURAM_FreeMem(((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram, ((t_FmPcdManip *)h_Manip)->h_Ad);\
43570 + else \
43571 + XX_Free(((t_FmPcdManip *)h_Manip)->h_Ad); \
43572 + ((t_FmPcdManip *)h_Manip)->h_Ad = NULL; \
43573 + }
43574 +/* position regarding Manip SW structure */
43575 +#define MANIP_IS_FIRST(h_Manip) (!(((t_FmPcdManip *)h_Manip)->h_PrevManip))
43576 +#define MANIP_IS_CASCADED(h_Manip) (((t_FmPcdManip *)h_Manip)->cascaded)
43577 +#define MANIP_IS_UNIFIED(h_Manip) (!(((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE))
43578 +#define MANIP_IS_UNIFIED_NON_FIRST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID) || \
43579 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST))
43580 +#define MANIP_IS_UNIFIED_NON_LAST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) ||\
43581 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID))
43582 +#define MANIP_IS_UNIFIED_FIRST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST)
43583 +#define MANIP_IS_UNIFIED_LAST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST)
43584 +
43585 +#define MANIP_UPDATE_UNIFIED_POSITION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition = \
43586 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)? \
43587 + e_MANIP_UNIFIED_LAST : e_MANIP_UNIFIED_MID)
43588 +
43589 +typedef enum e_ManipUnifiedPosition {
43590 + e_MANIP_UNIFIED_NONE = 0,
43591 + e_MANIP_UNIFIED_FIRST,
43592 + e_MANIP_UNIFIED_MID,
43593 + e_MANIP_UNIFIED_LAST
43594 +} e_ManipUnifiedPosition;
43595 +
43596 +typedef enum e_ManipInfo {
43597 + e_MANIP_HMTD,
43598 + e_MANIP_HMCT,
43599 + e_MANIP_HANDLER_TABLE_OWNER
43600 +}e_ManipInfo;
43601 +/***********************************************************************/
43602 +/* Memory map */
43603 +/***********************************************************************/
43604 +#if defined(__MWERKS__) && !defined(__GNUC__)
43605 +#pragma pack(push,1)
43606 +#endif /* defined(__MWERKS__) && ... */
43607 +
43608 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43609 +typedef struct t_CapwapReasmPram {
43610 + volatile uint32_t mode;
43611 + volatile uint32_t autoLearnHashTblPtr;
43612 + volatile uint32_t intStatsTblPtr;
43613 + volatile uint32_t reasmFrmDescPoolTblPtr;
43614 + volatile uint32_t reasmFrmDescIndexPoolTblPtr;
43615 + volatile uint32_t timeOutTblPtr;
43616 + volatile uint32_t bufferPoolIdAndRisc1SetIndexes;
43617 + volatile uint32_t risc23SetIndexes;
43618 + volatile uint32_t risc4SetIndexesAndExtendedStatsTblPtr;
43619 + volatile uint32_t extendedStatsTblPtr;
43620 + volatile uint32_t expirationDelay;
43621 + volatile uint32_t totalProcessedFragCounter;
43622 + volatile uint32_t totalUnsuccessfulReasmFramesCounter;
43623 + volatile uint32_t totalDuplicatedFragCounter;
43624 + volatile uint32_t totalMalformdFragCounter;
43625 + volatile uint32_t totalTimeOutCounter;
43626 + volatile uint32_t totalSetBusyCounter;
43627 + volatile uint32_t totalRfdPoolBusyCounter;
43628 + volatile uint32_t totalDiscardedFragsCounter;
43629 + volatile uint32_t totalMoreThan16FramesCounter;
43630 + volatile uint32_t internalBufferBusy;
43631 + volatile uint32_t externalBufferBusy;
43632 + volatile uint32_t reserved1[4];
43633 +} t_CapwapReasmPram;
43634 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43635 +
43636 +typedef _Packed struct t_ReassTbl {
43637 + volatile uint16_t waysNumAndSetSize;
43638 + volatile uint16_t autoLearnHashKeyMask;
43639 + volatile uint32_t reassCommonPrmTblPtr;
43640 + volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi;
43641 + volatile uint32_t autoLearnHashTblPtrLow;
43642 + volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi;
43643 + volatile uint32_t autoLearnSetLockTblPtrLow;
43644 + volatile uint16_t minFragSize; /* Not relevant for CAPWAP*/
43645 + volatile uint16_t maxReassemblySize; /* Only relevant for CAPWAP*/
43646 + volatile uint32_t totalSuccessfullyReasmFramesCounter;
43647 + volatile uint32_t totalValidFragmentCounter;
43648 + volatile uint32_t totalProcessedFragCounter;
43649 + volatile uint32_t totalMalformdFragCounter;
43650 + volatile uint32_t totalSetBusyCounter;
43651 + volatile uint32_t totalDiscardedFragsCounter;
43652 + volatile uint32_t totalMoreThan16FramesCounter;
43653 + volatile uint32_t reserved2[2];
43654 +} _PackedType t_ReassTbl;
43655 +
43656 +typedef struct t_ReassCommonTbl {
43657 + volatile uint32_t timeoutModeAndFqid;
43658 + volatile uint32_t reassFrmDescIndexPoolTblPtr;
43659 + volatile uint32_t liodnAndReassFrmDescPoolPtrHi;
43660 + volatile uint32_t reassFrmDescPoolPtrLow;
43661 + volatile uint32_t timeOutTblPtr;
43662 + volatile uint32_t expirationDelay;
43663 + volatile uint32_t internalBufferManagement;
43664 + volatile uint32_t reserved2;
43665 + volatile uint32_t totalTimeOutCounter;
43666 + volatile uint32_t totalRfdPoolBusyCounter;
43667 + volatile uint32_t totalInternalBufferBusy;
43668 + volatile uint32_t totalExternalBufferBusy;
43669 + volatile uint32_t totalSgFragmentCounter;
43670 + volatile uint32_t totalDmaSemaphoreDepletionCounter;
43671 + volatile uint32_t totalNCSPCounter;
43672 + volatile uint32_t discardMask;
43673 +} t_ReassCommonTbl;
43674 +
43675 +typedef _Packed struct t_Hmtd {
43676 + volatile uint16_t cfg;
43677 + volatile uint8_t eliodnOffset;
43678 + volatile uint8_t extHmcdBasePtrHi;
43679 + volatile uint32_t hmcdBasePtr;
43680 + volatile uint16_t nextAdIdx;
43681 + volatile uint8_t res1;
43682 + volatile uint8_t opCode;
43683 + volatile uint32_t res2;
43684 +} _PackedType t_Hmtd;
43685 +
43686 +#if defined(__MWERKS__) && !defined(__GNUC__)
43687 +#pragma pack(pop)
43688 +#endif /* defined(__MWERKS__) && ... */
43689 +
43690 +
43691 +/***********************************************************************/
43692 +/* Driver's internal structures */
43693 +/***********************************************************************/
43694 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43695 +typedef struct
43696 +{
43697 + t_Handle p_AutoLearnHashTbl;
43698 + t_Handle p_ReassmFrmDescrPoolTbl;
43699 + t_Handle p_ReassmFrmDescrIndxPoolTbl;
43700 + t_Handle p_TimeOutTbl;
43701 + uint16_t maxNumFramesInProcess;
43702 + uint8_t numOfTasks;
43703 + //uint8_t poolId;
43704 + uint8_t prOffset;
43705 + uint16_t dataOffset;
43706 + uint8_t sgBpid;
43707 + uint8_t hwPortId;
43708 + uint32_t fqidForTimeOutFrames;
43709 + uint32_t timeoutRoutineRequestTime;
43710 + uint32_t bitFor1Micro;
43711 +} t_CapwapFragParams;
43712 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43713 +
43714 +typedef struct
43715 +{
43716 + t_AdOfTypeContLookup *p_Frag;
43717 +#if (DPAA_VERSION == 10)
43718 + uint8_t scratchBpid;
43719 +#endif /* (DPAA_VERSION == 10) */
43720 +} t_FragParams;
43721 +
43722 +typedef struct t_ReassmParams
43723 +{
43724 + e_NetHeaderType hdr; /* Header selection */
43725 + t_ReassCommonTbl *p_ReassCommonTbl;
43726 + uintptr_t reassFrmDescrIndxPoolTblAddr;
43727 + uintptr_t reassFrmDescrPoolTblAddr;
43728 + uintptr_t timeOutTblAddr;
43729 + uintptr_t internalBufferPoolManagementIndexAddr;
43730 + uintptr_t internalBufferPoolAddr;
43731 + uint32_t maxNumFramesInProcess;
43732 + uint8_t sgBpid;
43733 + uint8_t dataMemId;
43734 + uint16_t dataLiodnOffset;
43735 + uint32_t fqidForTimeOutFrames;
43736 + e_FmPcdManipReassemTimeOutMode timeOutMode;
43737 + uint32_t timeoutThresholdForReassmProcess;
43738 + union {
43739 + struct {
43740 + t_Handle h_Ipv4Ad;
43741 + t_Handle h_Ipv6Ad;
43742 + bool ipv6Assigned;
43743 + t_ReassTbl *p_Ipv4ReassTbl;
43744 + t_ReassTbl *p_Ipv6ReassTbl;
43745 + uintptr_t ipv4AutoLearnHashTblAddr;
43746 + uintptr_t ipv6AutoLearnHashTblAddr;
43747 + uintptr_t ipv4AutoLearnSetLockTblAddr;
43748 + uintptr_t ipv6AutoLearnSetLockTblAddr;
43749 + uint16_t minFragSize[2];
43750 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
43751 + uint8_t relativeSchemeId[2];
43752 + t_Handle h_Ipv4Scheme;
43753 + t_Handle h_Ipv6Scheme;
43754 + uint32_t nonConsistentSpFqid;
43755 + } ip;
43756 + struct {
43757 + t_Handle h_Ad;
43758 + t_ReassTbl *p_ReassTbl;
43759 + uintptr_t autoLearnHashTblAddr;
43760 + uintptr_t autoLearnSetLockTblAddr;
43761 + uint16_t maxRessembledsSize;
43762 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
43763 + uint8_t relativeSchemeId;
43764 + t_Handle h_Scheme;
43765 + } capwap;
43766 + };
43767 +} t_ReassmParams;
43768 +
43769 +typedef struct{
43770 + e_FmPcdManipType type;
43771 + t_FmPcdManipParams manipParams;
43772 + bool muramAllocate;
43773 + t_Handle h_Ad;
43774 + uint32_t opcode;
43775 + bool rmv;
43776 + bool insrt;
43777 + t_Handle h_NextManip;
43778 + t_Handle h_PrevManip;
43779 + e_FmPcdManipType nextManipType;
43780 + /* HdrManip parameters*/
43781 + uint8_t *p_Hmct;
43782 + uint8_t *p_Data;
43783 + bool dontParseAfterManip;
43784 + bool fieldUpdate;
43785 + bool custom;
43786 + uint16_t tableSize;
43787 + uint8_t dataSize;
43788 + bool cascaded;
43789 + e_ManipUnifiedPosition unifiedPosition;
43790 + /* end HdrManip */
43791 + uint8_t *p_Template;
43792 + uint16_t owner;
43793 + uint32_t updateParams;
43794 + uint32_t shadowUpdateParams;
43795 + bool frag;
43796 + bool reassm;
43797 + uint16_t sizeForFragmentation;
43798 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43799 + t_Handle h_Frag;
43800 + t_CapwapFragParams capwapFragParams;
43801 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43802 + union {
43803 + t_ReassmParams reassmParams;
43804 + t_FragParams fragParams;
43805 + };
43806 + uint8_t icOffset;
43807 + uint16_t ownerTmp;
43808 + bool cnia;
43809 + t_Handle p_StatsTbl;
43810 + t_Handle h_FmPcd;
43811 + t_List nodesLst;
43812 + t_Handle h_Spinlock;
43813 +} t_FmPcdManip;
43814 +
43815 +typedef struct t_FmPcdCcSavedManipParams
43816 +{
43817 + union
43818 + {
43819 + struct
43820 + {
43821 + uint16_t dataOffset;
43822 + //uint8_t poolId;
43823 + }capwapParams;
43824 + struct
43825 + {
43826 + uint16_t dataOffset;
43827 + uint8_t poolId;
43828 + }ipParams;
43829 + };
43830 +
43831 +} t_FmPcdCcSavedManipParams;
43832 +
43833 +
43834 +#endif /* __FM_MANIP_H */
43835 --- /dev/null
43836 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
43837 @@ -0,0 +1,2095 @@
43838 +/*
43839 + * Copyright 2008-2012 Freescale Semiconductor Inc.
43840 + *
43841 + * Redistribution and use in source and binary forms, with or without
43842 + * modification, are permitted provided that the following conditions are met:
43843 + * * Redistributions of source code must retain the above copyright
43844 + * notice, this list of conditions and the following disclaimer.
43845 + * * Redistributions in binary form must reproduce the above copyright
43846 + * notice, this list of conditions and the following disclaimer in the
43847 + * documentation and/or other materials provided with the distribution.
43848 + * * Neither the name of Freescale Semiconductor nor the
43849 + * names of its contributors may be used to endorse or promote products
43850 + * derived from this software without specific prior written permission.
43851 + *
43852 + *
43853 + * ALTERNATIVELY, this software may be distributed under the terms of the
43854 + * GNU General Public License ("GPL") as published by the Free Software
43855 + * Foundation, either version 2 of that License or (at your option) any
43856 + * later version.
43857 + *
43858 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
43859 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43860 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43861 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
43862 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43863 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43864 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43865 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43866 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43867 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43868 + */
43869 +
43870 +
43871 +/******************************************************************************
43872 + @File fm_pcd.c
43873 +
43874 + @Description FM PCD ...
43875 +*//***************************************************************************/
43876 +#include "std_ext.h"
43877 +#include "error_ext.h"
43878 +#include "string_ext.h"
43879 +#include "xx_ext.h"
43880 +#include "sprint_ext.h"
43881 +#include "debug_ext.h"
43882 +#include "net_ext.h"
43883 +#include "fm_ext.h"
43884 +#include "fm_pcd_ext.h"
43885 +
43886 +#include "fm_common.h"
43887 +#include "fm_pcd.h"
43888 +#include "fm_pcd_ipc.h"
43889 +#include "fm_hc.h"
43890 +#include "fm_muram_ext.h"
43891 +
43892 +
43893 +/****************************************/
43894 +/* static functions */
43895 +/****************************************/
43896 +
43897 +static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd)
43898 +{
43899 + if (!p_FmPcd->h_Fm)
43900 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized"));
43901 +
43902 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
43903 + {
43904 + if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs)
43905 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
43906 +
43907 + if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs)
43908 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
43909 +
43910 + if (!p_FmPcd->f_Exception)
43911 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized"));
43912 +
43913 + if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg))
43914 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized"));
43915 +
43916 + if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT)
43917 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191"));
43918 + }
43919 +
43920 + return E_OK;
43921 +}
43922 +
43923 +static volatile bool blockingFlag = FALSE;
43924 +static void IpcMsgCompletionCB(t_Handle h_FmPcd,
43925 + uint8_t *p_Msg,
43926 + uint8_t *p_Reply,
43927 + uint32_t replyLength,
43928 + t_Error status)
43929 +{
43930 + UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
43931 + blockingFlag = FALSE;
43932 +}
43933 +
43934 +static t_Error IpcMsgHandlerCB(t_Handle h_FmPcd,
43935 + uint8_t *p_Msg,
43936 + uint32_t msgLength,
43937 + uint8_t *p_Reply,
43938 + uint32_t *p_ReplyLength)
43939 +{
43940 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
43941 + t_Error err = E_OK;
43942 + t_FmPcdIpcMsg *p_IpcMsg = (t_FmPcdIpcMsg*)p_Msg;
43943 + t_FmPcdIpcReply *p_IpcReply = (t_FmPcdIpcReply*)p_Reply;
43944 +
43945 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
43946 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
43947 +
43948 +#ifdef DISABLE_SANITY_CHECKS
43949 + UNUSED(msgLength);
43950 +#endif /* DISABLE_SANITY_CHECKS */
43951 +
43952 + ASSERT_COND(p_Msg);
43953 +
43954 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE));
43955 + *p_ReplyLength = 0;
43956 +
43957 + switch (p_IpcMsg->msgId)
43958 + {
43959 + case (FM_PCD_MASTER_IS_ALIVE):
43960 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
43961 + p_IpcReply->error = E_OK;
43962 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
43963 + break;
43964 + case (FM_PCD_MASTER_IS_ENABLED):
43965 + /* count partitions registrations */
43966 + if (p_FmPcd->enabled)
43967 + p_FmPcd->numOfEnabledGuestPartitionsPcds++;
43968 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled;
43969 + p_IpcReply->error = E_OK;
43970 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
43971 + break;
43972 + case (FM_PCD_GUEST_DISABLE):
43973 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds)
43974 + {
43975 + p_FmPcd->numOfEnabledGuestPartitionsPcds--;
43976 + p_IpcReply->error = E_OK;
43977 + }
43978 + else
43979 + {
43980 + REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition"));
43981 + p_IpcReply->error = E_INVALID_STATE;
43982 + }
43983 + *p_ReplyLength = sizeof(uint32_t);
43984 + break;
43985 + case (FM_PCD_GET_COUNTER):
43986 + {
43987 + e_FmPcdCounters inCounter;
43988 + uint32_t outCounter;
43989 +
43990 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
43991 + outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter);
43992 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
43993 + p_IpcReply->error = E_OK;
43994 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
43995 + break;
43996 + }
43997 + case (FM_PCD_ALLOC_KG_SCHEMES):
43998 + {
43999 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
44000 +
44001 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
44002 + err = FmPcdKgAllocSchemes(h_FmPcd,
44003 + ipcSchemesParams.numOfSchemes,
44004 + ipcSchemesParams.guestId,
44005 + p_IpcReply->replyBody);
44006 + p_IpcReply->error = err;
44007 + *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t);
44008 + break;
44009 + }
44010 + case (FM_PCD_FREE_KG_SCHEMES):
44011 + {
44012 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
44013 +
44014 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
44015 + err = FmPcdKgFreeSchemes(h_FmPcd,
44016 + ipcSchemesParams.numOfSchemes,
44017 + ipcSchemesParams.guestId,
44018 + ipcSchemesParams.schemesIds);
44019 + p_IpcReply->error = err;
44020 + *p_ReplyLength = sizeof(uint32_t);
44021 + break;
44022 + }
44023 + case (FM_PCD_ALLOC_KG_CLSPLAN):
44024 + {
44025 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
44026 +
44027 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
44028 + err = KgAllocClsPlanEntries(h_FmPcd,
44029 + ipcKgClsPlanParams.numOfClsPlanEntries,
44030 + ipcKgClsPlanParams.guestId,
44031 + p_IpcReply->replyBody);
44032 + p_IpcReply->error = err;
44033 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44034 + break;
44035 + }
44036 + case (FM_PCD_FREE_KG_CLSPLAN):
44037 + {
44038 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
44039 +
44040 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
44041 + KgFreeClsPlanEntries(h_FmPcd,
44042 + ipcKgClsPlanParams.numOfClsPlanEntries,
44043 + ipcKgClsPlanParams.guestId,
44044 + ipcKgClsPlanParams.clsPlanBase);
44045 + *p_ReplyLength = sizeof(uint32_t);
44046 + break;
44047 + }
44048 + case (FM_PCD_ALLOC_PROFILES):
44049 + {
44050 + t_FmIpcResourceAllocParams ipcAllocParams;
44051 + uint16_t base;
44052 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44053 + base = PlcrAllocProfilesForPartition(h_FmPcd,
44054 + ipcAllocParams.base,
44055 + ipcAllocParams.num,
44056 + ipcAllocParams.guestId);
44057 + memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t));
44058 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
44059 + break;
44060 + }
44061 + case (FM_PCD_FREE_PROFILES):
44062 + {
44063 + t_FmIpcResourceAllocParams ipcAllocParams;
44064 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44065 + PlcrFreeProfilesForPartition(h_FmPcd,
44066 + ipcAllocParams.base,
44067 + ipcAllocParams.num,
44068 + ipcAllocParams.guestId);
44069 + break;
44070 + }
44071 + case (FM_PCD_SET_PORT_PROFILES):
44072 + {
44073 + t_FmIpcResourceAllocParams ipcAllocParams;
44074 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44075 + PlcrSetPortProfiles(h_FmPcd,
44076 + ipcAllocParams.guestId,
44077 + ipcAllocParams.num,
44078 + ipcAllocParams.base);
44079 + break;
44080 + }
44081 + case (FM_PCD_CLEAR_PORT_PROFILES):
44082 + {
44083 + t_FmIpcResourceAllocParams ipcAllocParams;
44084 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44085 + PlcrClearPortProfiles(h_FmPcd,
44086 + ipcAllocParams.guestId);
44087 + break;
44088 + }
44089 + case (FM_PCD_GET_SW_PRS_OFFSET):
44090 + {
44091 + t_FmPcdIpcSwPrsLable ipcSwPrsLable;
44092 + uint32_t swPrsOffset;
44093 +
44094 + memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable));
44095 + swPrsOffset =
44096 + FmPcdGetSwPrsOffset(h_FmPcd,
44097 + (e_NetHeaderType)ipcSwPrsLable.enumHdr,
44098 + ipcSwPrsLable.indexPerHdr);
44099 + memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t));
44100 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
44101 + break;
44102 + }
44103 + case (FM_PCD_PRS_INC_PORT_STATS):
44104 + {
44105 + t_FmPcdIpcPrsIncludePort ipcPrsIncludePort;
44106 +
44107 + memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort));
44108 + PrsIncludePortInStatistics(h_FmPcd,
44109 + ipcPrsIncludePort.hardwarePortId,
44110 + ipcPrsIncludePort.include);
44111 + break;
44112 + }
44113 + default:
44114 + *p_ReplyLength = 0;
44115 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
44116 + }
44117 + return E_OK;
44118 +}
44119 +
44120 +static uint32_t NetEnvLock(t_Handle h_NetEnv)
44121 +{
44122 + ASSERT_COND(h_NetEnv);
44123 + return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock);
44124 +}
44125 +
44126 +static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags)
44127 +{
44128 + ASSERT_COND(h_NetEnv);
44129 + XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags);
44130 +}
44131 +
44132 +static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44133 +{
44134 + uint32_t intFlags;
44135 +
44136 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44137 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst);
44138 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44139 +}
44140 +
44141 +static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd)
44142 +{
44143 + t_FmPcdLock *p_Lock = NULL;
44144 + uint32_t intFlags;
44145 +
44146 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44147 + if (!LIST_IsEmpty(&p_FmPcd->freeLocksLst))
44148 + {
44149 + p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next);
44150 + LIST_DelAndInit(&p_Lock->node);
44151 + }
44152 + if (p_FmPcd->h_Spinlock)
44153 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44154 +
44155 + return p_Lock;
44156 +}
44157 +
44158 +static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44159 +{
44160 + uint32_t intFlags;
44161 +
44162 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44163 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst);
44164 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44165 +}
44166 +
44167 +static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd)
44168 +{
44169 + t_FmPcdLock *p_Lock;
44170 + int i;
44171 +
44172 + for (i=0; i<10; i++)
44173 + {
44174 + p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock));
44175 + if (!p_Lock)
44176 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!"));
44177 + memset(p_Lock, 0, sizeof(t_FmPcdLock));
44178 + INIT_LIST(&p_Lock->node);
44179 + p_Lock->h_Spinlock = XX_InitSpinlock();
44180 + if (!p_Lock->h_Spinlock)
44181 + {
44182 + XX_Free(p_Lock);
44183 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!"));
44184 + }
44185 + EnqueueLockToFreeLst(p_FmPcd, p_Lock);
44186 + }
44187 +
44188 + return E_OK;
44189 +}
44190 +
44191 +static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd)
44192 +{
44193 + t_FmPcdLock *p_Lock;
44194 +
44195 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44196 + while (p_Lock)
44197 + {
44198 + XX_FreeSpinlock(p_Lock->h_Spinlock);
44199 + XX_Free(p_Lock);
44200 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44201 + }
44202 +}
44203 +
44204 +
44205 +
44206 +/*****************************************************************************/
44207 +/* Inter-module API routines */
44208 +/*****************************************************************************/
44209 +
44210 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId)
44211 +{
44212 + ASSERT_COND(p_FmPcd);
44213 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId;
44214 +}
44215 +
44216 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams)
44217 +{
44218 + uint8_t netEnvId = p_GrpParams->netEnvId;
44219 + int i, k, j;
44220 +
44221 + ASSERT_COND(p_FmPcd);
44222 + if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN)
44223 + {
44224 + p_GrpParams->grpExists = TRUE;
44225 + p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId;
44226 + return E_OK;
44227 + }
44228 +
44229 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44230 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44231 + {
44232 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44233 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44234 + {
44235 + /* if an option exists, add it to the opts list */
44236 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44237 + {
44238 + /* check if this option already exists, add if it doesn't */
44239 + for (j = 0;j<p_GrpParams->numOfOptions;j++)
44240 + {
44241 + if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44242 + break;
44243 + }
44244 + p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i];
44245 + if (j == p_GrpParams->numOfOptions)
44246 + {
44247 + p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt;
44248 + p_GrpParams->numOfOptions++;
44249 + }
44250 + }
44251 + }
44252 + }
44253 +
44254 + if (p_GrpParams->numOfOptions == 0)
44255 + {
44256 + if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN)
44257 + {
44258 + p_GrpParams->grpExists = TRUE;
44259 + p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId;
44260 + }
44261 + }
44262 +
44263 + return E_OK;
44264 +
44265 +}
44266 +
44267 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector)
44268 +{
44269 + uint8_t j,k;
44270 +
44271 + *p_Vector = 0;
44272 +
44273 + ASSERT_COND(p_FmPcd);
44274 + for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44275 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++)
44276 + {
44277 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44278 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44279 + {
44280 + if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt)
44281 + *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j];
44282 + }
44283 + }
44284 +
44285 + if (!*p_Vector)
44286 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module"));
44287 + else
44288 + return E_OK;
44289 +}
44290 +
44291 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params)
44292 +{
44293 + int i;
44294 +
44295 + ASSERT_COND(p_FmPcd);
44296 + ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS);
44297 +
44298 + p_Params->vector = 0;
44299 + for (i=0; i<p_Params->numOfDistinctionUnits ;i++)
44300 + {
44301 + if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE)
44302 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module"));
44303 + ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]);
44304 + p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]];
44305 + }
44306 +
44307 + return E_OK;
44308 +}
44309 +
44310 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector)
44311 +{
44312 + int i=0, k;
44313 +
44314 + ASSERT_COND(p_FmPcd);
44315 + /* check whether a given unit may be used by non-clsPlan users. */
44316 + /* first, recognize the unit by its vector */
44317 + while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)
44318 + {
44319 + if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector)
44320 + {
44321 + for (k=0;
44322 + ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44323 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE));
44324 + k++)
44325 + /* check that no option exists */
44326 + if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44327 + return FALSE;
44328 + break;
44329 + }
44330 + i++;
44331 + }
44332 + /* assert that a unit was found to mach the vector */
44333 + ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE);
44334 +
44335 + return TRUE;
44336 +}
44337 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44338 +{
44339 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44340 + int i, k;
44341 +
44342 + ASSERT_COND(p_FmPcd);
44343 +
44344 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44345 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44346 + {
44347 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44348 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44349 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr)
44350 + return TRUE;
44351 + }
44352 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44353 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++)
44354 + {
44355 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44356 + return TRUE;
44357 + }
44358 +
44359 + return FALSE;
44360 +}
44361 +
44362 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt)
44363 +{
44364 + uint8_t i, k;
44365 +
44366 + ASSERT_COND(p_FmPcd);
44367 +
44368 + if (interchangeable)
44369 + {
44370 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44371 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44372 + {
44373 + for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44374 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
44375 + {
44376 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) &&
44377 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt))
44378 +
44379 + return i;
44380 + }
44381 + }
44382 + }
44383 + else
44384 + {
44385 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44386 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44387 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) &&
44388 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) &&
44389 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE))
44390 + return i;
44391 +
44392 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44393 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44394 + if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) &&
44395 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt))
44396 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44397 + }
44398 +
44399 + return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS;
44400 +}
44401 +
44402 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
44403 +{
44404 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44405 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = {0};
44406 + uint8_t result;
44407 + t_Error err = E_OK;
44408 +
44409 + ASSERT_COND(p_FmPcd);
44410 + ASSERT_COND(h_ReasmCommonPramTbl);
44411 +
44412 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
44413 + ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/
44414 +
44415 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK)
44416 + RETURN_ERROR(MAJOR, err, NO_MSG);
44417 +
44418 + switch (result)
44419 + {
44420 + case (0):
44421 + return E_OK;
44422 + case (1):
44423 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44424 + case (2):
44425 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44426 + case (3):
44427 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT"));
44428 + default:
44429 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
44430 + }
44431 +
44432 + return E_OK;
44433 +}
44434 +
44435 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44436 +{
44437 + int i;
44438 +
44439 + ASSERT_COND(p_FmPcd);
44440 + ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS);
44441 +
44442 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS)
44443 + && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44444 + {
44445 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44446 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44447 + }
44448 +
44449 + return HEADER_TYPE_NONE;
44450 +}
44451 +
44452 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId)
44453 +{
44454 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44455 + uint16_t swPortIndex = 0;
44456 +
44457 + ASSERT_COND(h_FmPcd);
44458 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
44459 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort;
44460 +}
44461 +
44462 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum)
44463 +{
44464 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44465 +
44466 + ASSERT_COND(h_FmPcd);
44467 + return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum];
44468 +}
44469 +
44470 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId)
44471 +{
44472 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44473 +
44474 + ASSERT_COND(h_FmPcd);
44475 + return p_FmPcd->netEnvs[netEnvId].macsecVector;
44476 +}
44477 +
44478 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv)
44479 +{
44480 + return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId;
44481 +}
44482 +
44483 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44484 +{
44485 + uint32_t intFlags;
44486 +
44487 + ASSERT_COND(h_FmPcd);
44488 +
44489 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44490 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++;
44491 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44492 +}
44493 +
44494 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44495 +{
44496 + uint32_t intFlags;
44497 +
44498 + ASSERT_COND(h_FmPcd);
44499 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners);
44500 +
44501 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44502 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--;
44503 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44504 +}
44505 +
44506 +uint32_t FmPcdLock(t_Handle h_FmPcd)
44507 +{
44508 + ASSERT_COND(h_FmPcd);
44509 + return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
44510 +}
44511 +
44512 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags)
44513 +{
44514 + ASSERT_COND(h_FmPcd);
44515 + XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags);
44516 +}
44517 +
44518 +t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd)
44519 +{
44520 + t_FmPcdLock *p_Lock;
44521 + ASSERT_COND(h_FmPcd);
44522 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44523 + if (!p_Lock)
44524 + {
44525 + FillFreeLocksLst(h_FmPcd);
44526 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44527 + }
44528 +
44529 + if (p_Lock)
44530 + EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock);
44531 + return p_Lock;
44532 +}
44533 +
44534 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock)
44535 +{
44536 + uint32_t intFlags;
44537 + ASSERT_COND(h_FmPcd);
44538 + intFlags = FmPcdLock(h_FmPcd);
44539 + LIST_DelAndInit(&p_Lock->node);
44540 + FmPcdUnlock(h_FmPcd, intFlags);
44541 + EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock);
44542 +}
44543 +
44544 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd)
44545 +{
44546 + uint32_t intFlags;
44547 + t_List *p_Pos, *p_SavedPos=NULL;
44548 +
44549 + ASSERT_COND(h_FmPcd);
44550 + intFlags = FmPcdLock(h_FmPcd);
44551 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44552 + {
44553 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44554 + if (!FmPcdLockTryLock(p_Lock))
44555 + {
44556 + p_SavedPos = p_Pos;
44557 + break;
44558 + }
44559 + }
44560 + if (p_SavedPos)
44561 + {
44562 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44563 + {
44564 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44565 + if (p_Pos == p_SavedPos)
44566 + break;
44567 + FmPcdLockUnlock(p_Lock);
44568 + }
44569 + }
44570 + FmPcdUnlock(h_FmPcd, intFlags);
44571 +
44572 + CORE_MemoryBarrier();
44573 +
44574 + if (p_SavedPos)
44575 + return FALSE;
44576 +
44577 + return TRUE;
44578 +}
44579 +
44580 +void FmPcdLockUnlockAll(t_Handle h_FmPcd)
44581 +{
44582 + uint32_t intFlags;
44583 + t_List *p_Pos;
44584 +
44585 + ASSERT_COND(h_FmPcd);
44586 + intFlags = FmPcdLock(h_FmPcd);
44587 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44588 + {
44589 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44590 + p_Lock->flag = FALSE;
44591 + }
44592 + FmPcdUnlock(h_FmPcd, intFlags);
44593 +
44594 + CORE_MemoryBarrier();
44595 +}
44596 +
44597 +t_Error FmPcdHcSync(t_Handle h_FmPcd)
44598 +{
44599 + ASSERT_COND(h_FmPcd);
44600 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc);
44601 +
44602 + return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc);
44603 +}
44604 +
44605 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
44606 +{
44607 + ASSERT_COND(h_FmPcd);
44608 + return ((t_FmPcd*)h_FmPcd)->h_Hc;
44609 +}
44610 +
44611 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd)
44612 +{
44613 + ASSERT_COND(h_FmPcd);
44614 + return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport;
44615 +}
44616 +/*********************** End of inter-module routines ************************/
44617 +
44618 +
44619 +/****************************************/
44620 +/* API Init unit functions */
44621 +/****************************************/
44622 +
44623 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams)
44624 +{
44625 + t_FmPcd *p_FmPcd = NULL;
44626 + t_FmPhysAddr physicalMuramBase;
44627 + uint8_t i;
44628 +
44629 + SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL);
44630 +
44631 + p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd));
44632 + if (!p_FmPcd)
44633 + {
44634 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD"));
44635 + return NULL;
44636 + }
44637 + memset(p_FmPcd, 0, sizeof(t_FmPcd));
44638 +
44639 + p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam));
44640 + if (!p_FmPcd->p_FmPcdDriverParam)
44641 + {
44642 + XX_Free(p_FmPcd);
44643 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param"));
44644 + return NULL;
44645 + }
44646 + memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam));
44647 +
44648 + p_FmPcd->h_Fm = p_FmPcdParams->h_Fm;
44649 + p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm);
44650 + p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm);
44651 + if (p_FmPcd->h_FmMuram)
44652 + {
44653 + FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase);
44654 + p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32));
44655 + }
44656 +
44657 + for (i = 0; i<FM_MAX_NUM_OF_PORTS; i++)
44658 + p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN;
44659 +
44660 + if (p_FmPcdParams->useHostCommand)
44661 + {
44662 + t_FmHcParams hcParams;
44663 +
44664 + memset(&hcParams, 0, sizeof(hcParams));
44665 + hcParams.h_Fm = p_FmPcd->h_Fm;
44666 + hcParams.h_FmPcd = (t_Handle)p_FmPcd;
44667 + memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams));
44668 + p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams);
44669 + if (!p_FmPcd->h_Hc)
44670 + {
44671 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC"));
44672 + FM_PCD_Free(p_FmPcd);
44673 + return NULL;
44674 + }
44675 + }
44676 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
44677 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition."));
44678 +
44679 + if (p_FmPcdParams->kgSupport)
44680 + {
44681 + p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams);
44682 + if (!p_FmPcd->p_FmPcdKg)
44683 + {
44684 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen"));
44685 + FM_PCD_Free(p_FmPcd);
44686 + return NULL;
44687 + }
44688 + }
44689 +
44690 + if (p_FmPcdParams->plcrSupport)
44691 + {
44692 + p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams);
44693 + if (!p_FmPcd->p_FmPcdPlcr)
44694 + {
44695 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer"));
44696 + FM_PCD_Free(p_FmPcd);
44697 + return NULL;
44698 + }
44699 + }
44700 +
44701 + if (p_FmPcdParams->prsSupport)
44702 + {
44703 + p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams);
44704 + if (!p_FmPcd->p_FmPcdPrs)
44705 + {
44706 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser"));
44707 + FM_PCD_Free(p_FmPcd);
44708 + return NULL;
44709 + }
44710 + }
44711 +
44712 + p_FmPcd->h_Spinlock = XX_InitSpinlock();
44713 + if (!p_FmPcd->h_Spinlock)
44714 + {
44715 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock"));
44716 + FM_PCD_Free(p_FmPcd);
44717 + return NULL;
44718 + }
44719 + INIT_LIST(&p_FmPcd->freeLocksLst);
44720 + INIT_LIST(&p_FmPcd->acquiredLocksLst);
44721 +
44722 + p_FmPcd->numOfEnabledGuestPartitionsPcds = 0;
44723 +
44724 + p_FmPcd->f_Exception = p_FmPcdParams->f_Exception;
44725 + p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId;
44726 + p_FmPcd->h_App = p_FmPcdParams->h_App;
44727 +
44728 + p_FmPcd->p_CcShadow = NULL;
44729 + p_FmPcd->ccShadowSize = 0;
44730 + p_FmPcd->ccShadowAlign = 0;
44731 +
44732 + p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock();
44733 + if (!p_FmPcd->h_ShadowSpinlock)
44734 + {
44735 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock"));
44736 + FM_PCD_Free(p_FmPcd);
44737 + return NULL;
44738 + }
44739 +
44740 + return p_FmPcd;
44741 +}
44742 +
44743 +t_Error FM_PCD_Init(t_Handle h_FmPcd)
44744 +{
44745 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44746 + t_Error err = E_OK;
44747 + t_FmPcdIpcMsg msg;
44748 +
44749 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44750 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
44751 +
44752 + FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo);
44753 +
44754 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
44755 + {
44756 + memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44757 + if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10)
44758 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44759 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44760 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11))
44761 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44762 +
44763 + p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName);
44764 + if (p_FmPcd->h_IpcSession)
44765 + {
44766 + t_FmPcdIpcReply reply;
44767 + uint32_t replyLength;
44768 + uint8_t isMasterAlive = 0;
44769 +
44770 + memset(&msg, 0, sizeof(msg));
44771 + memset(&reply, 0, sizeof(reply));
44772 + msg.msgId = FM_PCD_MASTER_IS_ALIVE;
44773 + msg.msgBody[0] = p_FmPcd->guestId;
44774 + blockingFlag = TRUE;
44775 +
44776 + do
44777 + {
44778 + replyLength = sizeof(uint32_t) + sizeof(isMasterAlive);
44779 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
44780 + (uint8_t*)&msg,
44781 + sizeof(msg.msgId)+sizeof(p_FmPcd->guestId),
44782 + (uint8_t*)&reply,
44783 + &replyLength,
44784 + IpcMsgCompletionCB,
44785 + h_FmPcd)) != E_OK)
44786 + REPORT_ERROR(MAJOR, err, NO_MSG);
44787 + while (blockingFlag) ;
44788 + if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive)))
44789 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
44790 + isMasterAlive = *(uint8_t*)(reply.replyBody);
44791 + } while (!isMasterAlive);
44792 + }
44793 + }
44794 +
44795 + CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters);
44796 +
44797 + if (p_FmPcd->p_FmPcdKg)
44798 + {
44799 + err = KgInit(p_FmPcd);
44800 + if (err)
44801 + RETURN_ERROR(MAJOR, err, NO_MSG);
44802 + }
44803 +
44804 + if (p_FmPcd->p_FmPcdPlcr)
44805 + {
44806 + err = PlcrInit(p_FmPcd);
44807 + if (err)
44808 + RETURN_ERROR(MAJOR, err, NO_MSG);
44809 + }
44810 +
44811 + if (p_FmPcd->p_FmPcdPrs)
44812 + {
44813 + err = PrsInit(p_FmPcd);
44814 + if (err)
44815 + RETURN_ERROR(MAJOR, err, NO_MSG);
44816 + }
44817 +
44818 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
44819 + {
44820 + /* register to inter-core messaging mechanism */
44821 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44822 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10)
44823 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44824 + err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE);
44825 + if (err)
44826 + RETURN_ERROR(MAJOR, err, NO_MSG);
44827 + }
44828 +
44829 + /* IPv6 Frame-Id used for fragmentation */
44830 + p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4));
44831 + if (!p_FmPcd->ipv6FrameIdAddr)
44832 + {
44833 + FM_PCD_Free(p_FmPcd);
44834 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id"));
44835 + }
44836 + IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0, 4);
44837 +
44838 + /* CAPWAP Frame-Id used for fragmentation */
44839 + p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4));
44840 + if (!p_FmPcd->capwapFrameIdAddr)
44841 + {
44842 + FM_PCD_Free(p_FmPcd);
44843 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id"));
44844 + }
44845 + IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0, 2);
44846 +
44847 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
44848 + p_FmPcd->p_FmPcdDriverParam = NULL;
44849 +
44850 + FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd);
44851 +
44852 + return E_OK;
44853 +}
44854 +
44855 +t_Error FM_PCD_Free(t_Handle h_FmPcd)
44856 +{
44857 + t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd;
44858 + t_Error err = E_OK;
44859 +
44860 + if (p_FmPcd->ipv6FrameIdAddr)
44861 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr));
44862 +
44863 + if (p_FmPcd->capwapFrameIdAddr)
44864 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr));
44865 +
44866 + if (p_FmPcd->enabled)
44867 + FM_PCD_Disable(p_FmPcd);
44868 +
44869 + if (p_FmPcd->p_FmPcdDriverParam)
44870 + {
44871 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
44872 + p_FmPcd->p_FmPcdDriverParam = NULL;
44873 + }
44874 +
44875 + if (p_FmPcd->p_FmPcdKg)
44876 + {
44877 + if ((err = KgFree(p_FmPcd)) != E_OK)
44878 + RETURN_ERROR(MINOR, err, NO_MSG);
44879 + XX_Free(p_FmPcd->p_FmPcdKg);
44880 + p_FmPcd->p_FmPcdKg = NULL;
44881 + }
44882 +
44883 + if (p_FmPcd->p_FmPcdPlcr)
44884 + {
44885 + PlcrFree(p_FmPcd);
44886 + XX_Free(p_FmPcd->p_FmPcdPlcr);
44887 + p_FmPcd->p_FmPcdPlcr = NULL;
44888 + }
44889 +
44890 + if (p_FmPcd->p_FmPcdPrs)
44891 + {
44892 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
44893 + PrsFree(p_FmPcd);
44894 + XX_Free(p_FmPcd->p_FmPcdPrs);
44895 + p_FmPcd->p_FmPcdPrs = NULL;
44896 + }
44897 +
44898 + if (p_FmPcd->h_Hc)
44899 + {
44900 + FmHcFree(p_FmPcd->h_Hc);
44901 + p_FmPcd->h_Hc = NULL;
44902 + }
44903 +
44904 + XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName);
44905 +
44906 + FmUnregisterPcd(p_FmPcd->h_Fm);
44907 +
44908 + ReleaseFreeLocksLst(p_FmPcd);
44909 +
44910 + if (p_FmPcd->h_Spinlock)
44911 + XX_FreeSpinlock(p_FmPcd->h_Spinlock);
44912 +
44913 + if (p_FmPcd->h_ShadowSpinlock)
44914 + XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock);
44915 +
44916 + XX_Free(p_FmPcd);
44917 +
44918 + return E_OK;
44919 +}
44920 +
44921 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
44922 +{
44923 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44924 + uint32_t bitMask = 0;
44925 +
44926 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44927 +
44928 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
44929 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!"));
44930 +
44931 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
44932 + if (bitMask)
44933 + {
44934 + if (enable)
44935 + p_FmPcd->exceptions |= bitMask;
44936 + else
44937 + p_FmPcd->exceptions &= ~bitMask;
44938 + }
44939 + else
44940 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
44941 +
44942 + return E_OK;
44943 +}
44944 +
44945 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId)
44946 +{
44947 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44948 +
44949 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44950 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
44951 +
44952 + return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId);
44953 +}
44954 +
44955 +t_Error FM_PCD_Enable(t_Handle h_FmPcd)
44956 +{
44957 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44958 + t_Error err = E_OK;
44959 +
44960 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
44961 +
44962 + if (p_FmPcd->enabled)
44963 + return E_OK;
44964 +
44965 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
44966 + p_FmPcd->h_IpcSession)
44967 + {
44968 + uint8_t enabled;
44969 + t_FmPcdIpcMsg msg;
44970 + t_FmPcdIpcReply reply;
44971 + uint32_t replyLength;
44972 +
44973 + memset(&reply, 0, sizeof(reply));
44974 + memset(&msg, 0, sizeof(msg));
44975 + msg.msgId = FM_PCD_MASTER_IS_ENABLED;
44976 + replyLength = sizeof(uint32_t) + sizeof(enabled);
44977 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
44978 + (uint8_t*)&msg,
44979 + sizeof(msg.msgId),
44980 + (uint8_t*)&reply,
44981 + &replyLength,
44982 + NULL,
44983 + NULL)) != E_OK)
44984 + RETURN_ERROR(MAJOR, err, NO_MSG);
44985 + if (replyLength != sizeof(uint32_t) + sizeof(enabled))
44986 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
44987 + p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody));
44988 + if (!p_FmPcd->enabled)
44989 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!"));
44990 +
44991 + return E_OK;
44992 + }
44993 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
44994 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
44995 + ("running in guest-mode without IPC!"));
44996 +
44997 + if (p_FmPcd->p_FmPcdKg)
44998 + KgEnable(p_FmPcd);
44999 +
45000 + if (p_FmPcd->p_FmPcdPlcr)
45001 + PlcrEnable(p_FmPcd);
45002 +
45003 + if (p_FmPcd->p_FmPcdPrs)
45004 + PrsEnable(p_FmPcd);
45005 +
45006 + p_FmPcd->enabled = TRUE;
45007 +
45008 + return E_OK;
45009 +}
45010 +
45011 +t_Error FM_PCD_Disable(t_Handle h_FmPcd)
45012 +{
45013 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45014 + t_Error err = E_OK;
45015 +
45016 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45017 +
45018 + if (!p_FmPcd->enabled)
45019 + return E_OK;
45020 +
45021 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45022 + p_FmPcd->h_IpcSession)
45023 + {
45024 + t_FmPcdIpcMsg msg;
45025 + t_FmPcdIpcReply reply;
45026 + uint32_t replyLength;
45027 +
45028 + memset(&reply, 0, sizeof(reply));
45029 + memset(&msg, 0, sizeof(msg));
45030 + msg.msgId = FM_PCD_GUEST_DISABLE;
45031 + replyLength = sizeof(uint32_t);
45032 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45033 + (uint8_t*)&msg,
45034 + sizeof(msg.msgId),
45035 + (uint8_t*)&reply,
45036 + &replyLength,
45037 + NULL,
45038 + NULL)) != E_OK)
45039 + RETURN_ERROR(MAJOR, err, NO_MSG);
45040 + if (replyLength != sizeof(uint32_t))
45041 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45042 + if (reply.error == E_OK)
45043 + p_FmPcd->enabled = FALSE;
45044 +
45045 + return (t_Error)(reply.error);
45046 + }
45047 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
45048 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
45049 + ("running in guest-mode without IPC!"));
45050 +
45051 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0)
45052 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
45053 + ("Trying to disable a master partition PCD while"
45054 + "guest partitions are still enabled!"));
45055 +
45056 + if (p_FmPcd->p_FmPcdKg)
45057 + KgDisable(p_FmPcd);
45058 +
45059 + if (p_FmPcd->p_FmPcdPlcr)
45060 + PlcrDisable(p_FmPcd);
45061 +
45062 + if (p_FmPcd->p_FmPcdPrs)
45063 + PrsDisable(p_FmPcd);
45064 +
45065 + p_FmPcd->enabled = FALSE;
45066 +
45067 + return E_OK;
45068 +}
45069 +
45070 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams)
45071 +{
45072 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45073 + uint32_t intFlags, specialUnits = 0;
45074 + uint8_t bitId = 0;
45075 + uint8_t i, j, k;
45076 + uint8_t netEnvCurrId;
45077 + uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0;
45078 + bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE;
45079 + uint8_t hdrNum;
45080 + t_FmPcdNetEnvParams *p_ModifiedNetEnvParams;
45081 +
45082 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL);
45083 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
45084 + SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL);
45085 +
45086 + intFlags = FmPcdLock(p_FmPcd);
45087 +
45088 + /* find a new netEnv */
45089 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
45090 + if (!p_FmPcd->netEnvs[i].used)
45091 + break;
45092 +
45093 + if (i== FM_MAX_NUM_OF_PORTS)
45094 + {
45095 + REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS));
45096 + FmPcdUnlock(p_FmPcd, intFlags);
45097 + return NULL;
45098 + }
45099 +
45100 + p_FmPcd->netEnvs[i].used = TRUE;
45101 + FmPcdUnlock(p_FmPcd, intFlags);
45102 +
45103 + /* As anyone doesn't have handle of this netEnv yet, no need
45104 + to protect it with spinlocks */
45105 +
45106 + p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams));
45107 + if (!p_ModifiedNetEnvParams)
45108 + {
45109 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams"));
45110 + return NULL;
45111 + }
45112 +
45113 + memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams));
45114 + p_NetEnvParams = p_ModifiedNetEnvParams;
45115 +
45116 + netEnvCurrId = (uint8_t)i;
45117 +
45118 + /* clear from previous use */
45119 + memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit));
45120 + memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases));
45121 + memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit));
45122 +
45123 + p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId;
45124 + p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd;
45125 +
45126 + p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45127 +
45128 + /* check that header with opt is not interchanged with the same header */
45129 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45130 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45131 + {
45132 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45133 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45134 + {
45135 + /* if an option exists, check that other headers are not the same header
45136 + without option */
45137 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt)
45138 + {
45139 + for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45140 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++)
45141 + {
45142 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) &&
45143 + !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt)
45144 + {
45145 + REPORT_ERROR(MINOR, E_FULL,
45146 + ("Illegal unit - header with opt may not be interchangeable with the same header without opt"));
45147 + XX_Free(p_ModifiedNetEnvParams);
45148 + return NULL;
45149 + }
45150 + }
45151 + }
45152 + }
45153 + }
45154 +
45155 + /* Specific headers checking */
45156 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45157 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45158 + {
45159 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45160 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45161 + {
45162 + /* Some headers pairs may not be defined on different units as the parser
45163 + doesn't distinguish */
45164 + /* IPSEC_AH and IPSEC_SPI can't be 2 units, */
45165 + /* check that header with opt is not interchanged with the same header */
45166 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH)
45167 + {
45168 + if (ipsecEspExists && (ipsecEspUnit != i))
45169 + {
45170 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45171 + XX_Free(p_ModifiedNetEnvParams);
45172 + return NULL;
45173 + }
45174 + else
45175 + {
45176 + ipsecAhUnit = i;
45177 + ipsecAhExists = TRUE;
45178 + }
45179 + }
45180 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP)
45181 + {
45182 + if (ipsecAhExists && (ipsecAhUnit != i))
45183 + {
45184 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45185 + XX_Free(p_ModifiedNetEnvParams);
45186 + return NULL;
45187 + }
45188 + else
45189 + {
45190 + ipsecEspUnit = i;
45191 + ipsecEspExists = TRUE;
45192 + }
45193 + }
45194 + /* ENCAP_ESP */
45195 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP)
45196 + {
45197 + /* IPSec UDP encapsulation is currently set to use SHIM1 */
45198 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP;
45199 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45200 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45201 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45202 + }
45203 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
45204 + /* UDP_LITE */
45205 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE)
45206 + {
45207 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE;
45208 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP;
45209 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP;
45210 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45211 + }
45212 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
45213 +
45214 + /* IP FRAG */
45215 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) &&
45216 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1))
45217 + {
45218 + /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if
45219 + * IPv4 exists. If so we don't need to set an extra unit
45220 + * We consider as "having IPv4" any IPv4 without interchangable headers
45221 + * but including any options. */
45222 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4;
45223 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1;
45224 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45225 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45226 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45227 +
45228 + /* check if IPv4 header exists by itself */
45229 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45230 + {
45231 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4;
45232 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45233 + }
45234 + }
45235 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) &&
45236 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1))
45237 + {
45238 + /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if
45239 + * IPv4 exists. If so we don't need to set an extra unit
45240 + * We consider as "having IPv6" any IPv6 without interchangable headers
45241 + * but including any options. */
45242 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6;
45243 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1;
45244 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45245 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45246 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45247 +
45248 + /* check if IPv6 header exists by itself */
45249 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45250 + {
45251 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6;
45252 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45253 + }
45254 + }
45255 +#if (DPAA_VERSION >= 11)
45256 + /* CAPWAP FRAG */
45257 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) &&
45258 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1))
45259 + {
45260 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP;
45261 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1;
45262 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45263 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45264 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45265 + }
45266 +#endif /* (DPAA_VERSION >= 11) */
45267 + }
45268 + }
45269 +
45270 + /* if private header (shim), check that no other headers specified */
45271 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45272 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45273 + {
45274 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45275 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE)
45276 + {
45277 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers"));
45278 + XX_Free(p_ModifiedNetEnvParams);
45279 + return NULL;
45280 + }
45281 + }
45282 +
45283 + for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++)
45284 + {
45285 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45286 + switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)
45287 + {
45288 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
45289 + if (shim1Selected)
45290 + {
45291 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP"));
45292 + XX_Free(p_ModifiedNetEnvParams);
45293 + return NULL;
45294 + }
45295 + shim1Selected = TRUE;
45296 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001;
45297 + break;
45298 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
45299 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002;
45300 + break;
45301 + default:
45302 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported"));
45303 + }
45304 + else
45305 + {
45306 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++);
45307 +
45308 + if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45309 + p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45310 + }
45311 + }
45312 +
45313 + /* define a set of hardware parser LCV's according to the defined netenv */
45314 +
45315 + /* set an array of LCV's for each header in the netEnv */
45316 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45317 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45318 + {
45319 + /* private headers have no LCV in the hard parser */
45320 + if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45321 + {
45322 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45323 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45324 + {
45325 + hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr);
45326 + if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
45327 + {
45328 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
45329 + XX_Free(p_ModifiedNetEnvParams);
45330 + return NULL;
45331 + }
45332 + p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45333 + }
45334 + }
45335 + }
45336 + XX_Free(p_ModifiedNetEnvParams);
45337 +
45338 + p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock();
45339 + if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock)
45340 + {
45341 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock"));
45342 + return NULL;
45343 + }
45344 + return &p_FmPcd->netEnvs[netEnvCurrId];
45345 +}
45346 +
45347 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv)
45348 +{
45349 + t_FmPcdNetEnv *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv;
45350 + t_FmPcd *p_FmPcd = p_NetEnv->h_FmPcd;
45351 + uint32_t intFlags;
45352 + uint8_t netEnvId = p_NetEnv->netEnvId;
45353 +
45354 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE);
45355 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45356 +
45357 + /* check that no port is bound to this netEnv */
45358 + if (p_FmPcd->netEnvs[netEnvId].owners)
45359 + {
45360 + RETURN_ERROR(MINOR, E_INVALID_STATE,
45361 + ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to"));
45362 + }
45363 +
45364 + intFlags = FmPcdLock(p_FmPcd);
45365 +
45366 + p_FmPcd->netEnvs[netEnvId].used = FALSE;
45367 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45368 +
45369 + memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45370 + memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45371 + memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS);
45372 +
45373 + if (p_FmPcd->netEnvs[netEnvId].h_Spinlock)
45374 + XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock);
45375 +
45376 + FmPcdUnlock(p_FmPcd, intFlags);
45377 + return E_OK;
45378 +}
45379 +
45380 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd)
45381 +{
45382 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45383 +
45384 + SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE);
45385 +
45386 + FmHcTxConf(p_FmPcd->h_Hc, p_Fd);
45387 +}
45388 +
45389 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd)
45390 +{
45391 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45392 + t_FmCtrlCodeRevisionInfo revInfo;
45393 + t_Error err;
45394 +
45395 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45396 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45397 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE);
45398 +
45399 + if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK)
45400 + {
45401 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
45402 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
45403 + }
45404 + if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
45405 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
45406 +
45407 + if (!p_FmPcd->h_Hc)
45408 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode"));
45409 +
45410 + p_FmPcd->advancedOffloadSupport = TRUE;
45411 +
45412 + return E_OK;
45413 +}
45414 +
45415 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter)
45416 +{
45417 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45418 + uint32_t outCounter = 0;
45419 + t_Error err;
45420 +
45421 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
45422 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
45423 +
45424 + switch (counter)
45425 + {
45426 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45427 + if (!p_FmPcd->p_FmPcdKg)
45428 + {
45429 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated"));
45430 + return 0;
45431 + }
45432 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45433 + !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs &&
45434 + !p_FmPcd->h_IpcSession)
45435 + {
45436 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45437 + ("running in guest-mode without neither IPC nor mapped register!"));
45438 + return 0;
45439 + }
45440 + break;
45441 +
45442 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45443 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45444 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45445 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45446 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45447 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45448 + if (!p_FmPcd->p_FmPcdPlcr)
45449 + {
45450 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated"));
45451 + return 0;
45452 + }
45453 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45454 + !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45455 + !p_FmPcd->h_IpcSession)
45456 + {
45457 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45458 + ("running in \"guest-mode\" without neither IPC nor mapped register!"));
45459 + return 0;
45460 + }
45461 +
45462 + /* check that counters are enabled */
45463 + if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45464 + !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
45465 + {
45466 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
45467 + return 0;
45468 + }
45469 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs ||
45470 + ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession));
45471 + break;
45472 +
45473 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45474 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45475 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45476 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45477 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45478 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45479 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45480 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45481 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45482 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45483 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45484 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45485 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45486 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45487 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45488 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45489 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45490 + if (!p_FmPcd->p_FmPcdPrs)
45491 + {
45492 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated"));
45493 + return 0;
45494 + }
45495 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45496 + !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs &&
45497 + !p_FmPcd->h_IpcSession)
45498 + {
45499 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45500 + ("running in guest-mode without neither IPC nor mapped register!"));
45501 + return 0;
45502 + }
45503 + break;
45504 + default:
45505 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter"));
45506 + return 0;
45507 + }
45508 +
45509 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45510 + p_FmPcd->h_IpcSession)
45511 + {
45512 + t_FmPcdIpcMsg msg;
45513 + t_FmPcdIpcReply reply;
45514 + uint32_t replyLength;
45515 +
45516 + memset(&msg, 0, sizeof(msg));
45517 + memset(&reply, 0, sizeof(reply));
45518 + msg.msgId = FM_PCD_GET_COUNTER;
45519 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
45520 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
45521 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45522 + (uint8_t*)&msg,
45523 + sizeof(msg.msgId) +sizeof(uint32_t),
45524 + (uint8_t*)&reply,
45525 + &replyLength,
45526 + NULL,
45527 + NULL)) != E_OK)
45528 + RETURN_ERROR(MAJOR, err, NO_MSG);
45529 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
45530 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45531 +
45532 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
45533 + return outCounter;
45534 + }
45535 +
45536 + switch (counter)
45537 + {
45538 + /* Parser statistics */
45539 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45540 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds);
45541 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45542 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs);
45543 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45544 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs);
45545 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45546 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs);
45547 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45548 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs);
45549 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45550 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres);
45551 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45552 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres);
45553 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45554 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres);
45555 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45556 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres);
45557 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45558 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs);
45559 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45560 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs);
45561 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45562 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs);
45563 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45564 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs);
45565 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45566 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs);
45567 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45568 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs);
45569 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45570 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs);
45571 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45572 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs);
45573 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45574 + return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc);
45575 +
45576 + /* Policer statistics */
45577 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45578 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt);
45579 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45580 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt);
45581 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45582 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt);
45583 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45584 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt);
45585 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45586 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt);
45587 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45588 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt);
45589 + }
45590 + return 0;
45591 +}
45592 +
45593 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
45594 +{
45595 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45596 + uint32_t bitMask = 0, tmpReg;
45597 +
45598 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45599 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45600 +
45601 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45602 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!"));
45603 +
45604 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
45605 +
45606 + if (bitMask)
45607 + {
45608 + if (enable)
45609 + p_FmPcd->exceptions |= bitMask;
45610 + else
45611 + p_FmPcd->exceptions &= ~bitMask;
45612 +
45613 + switch (exception)
45614 + {
45615 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45616 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45617 + if (!p_FmPcd->p_FmPcdKg)
45618 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45619 + break;
45620 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45621 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45622 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45623 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45624 + if (!p_FmPcd->p_FmPcdPlcr)
45625 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45626 + break;
45627 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45628 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45629 + if (!p_FmPcd->p_FmPcdPrs)
45630 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working"));
45631 + break;
45632 + }
45633 +
45634 + switch (exception)
45635 + {
45636 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45637 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45638 + if (enable)
45639 + tmpReg |= FM_EX_KG_DOUBLE_ECC;
45640 + else
45641 + tmpReg &= ~FM_EX_KG_DOUBLE_ECC;
45642 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45643 + break;
45644 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45645 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45646 + if (enable)
45647 + tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW;
45648 + else
45649 + tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW;
45650 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45651 + break;
45652 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45653 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer);
45654 + if (enable)
45655 + tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
45656 + else
45657 + tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC;
45658 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg);
45659 + break;
45660 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45661 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever);
45662 + if (enable)
45663 + tmpReg |= FM_PCD_PRS_SINGLE_ECC;
45664 + else
45665 + tmpReg &= ~FM_PCD_PRS_SINGLE_ECC;
45666 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg);
45667 + break;
45668 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45669 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45670 + if (enable)
45671 + tmpReg |= FM_PCD_PLCR_DOUBLE_ECC;
45672 + else
45673 + tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC;
45674 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45675 + break;
45676 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45677 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45678 + if (enable)
45679 + tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
45680 + else
45681 + tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR;
45682 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45683 + break;
45684 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45685 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45686 + if (enable)
45687 + tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45688 + else
45689 + tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45690 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45691 + break;
45692 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45693 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45694 + if (enable)
45695 + tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45696 + else
45697 + tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45698 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45699 + break;
45700 + }
45701 + /* for ECC exceptions driver automatically enables ECC mechanism, if disabled.
45702 + Driver may disable them automatically, depending on driver's status */
45703 + if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45704 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45705 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45706 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45707 + FmEnableRamsEcc(p_FmPcd->h_Fm);
45708 + if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45709 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45710 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45711 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45712 + FmDisableRamsEcc(p_FmPcd->h_Fm);
45713 + }
45714 +
45715 + return E_OK;
45716 +}
45717 +
45718 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception)
45719 +{
45720 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45721 +
45722 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45723 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45724 +
45725 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45726 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!"));
45727 +
45728 + switch (exception)
45729 + {
45730 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45731 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45732 + if (!p_FmPcd->p_FmPcdKg)
45733 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45734 + break;
45735 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45736 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45737 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45738 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45739 + if (!p_FmPcd->p_FmPcdPlcr)
45740 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45741 + break;
45742 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45743 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45744 + if (!p_FmPcd->p_FmPcdPrs)
45745 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working"));
45746 + break;
45747 + default:
45748 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested"));
45749 + }
45750 + switch (exception)
45751 + {
45752 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC:
45753 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC))
45754 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45755 + break;
45756 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC:
45757 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC))
45758 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45759 + break;
45760 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC:
45761 + if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC))
45762 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45763 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC);
45764 + break;
45765 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW:
45766 + if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW))
45767 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45768 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW);
45769 + break;
45770 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC:
45771 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC))
45772 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45773 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC);
45774 + break;
45775 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR:
45776 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR))
45777 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45778 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR);
45779 + break;
45780 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE:
45781 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE))
45782 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45783 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE);
45784 + break;
45785 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE:
45786 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE))
45787 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45788 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE);
45789 + break;
45790 + }
45791 +
45792 + return E_OK;
45793 +}
45794 +
45795 +
45796 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value)
45797 +{
45798 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45799 +
45800 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45801 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45802 +
45803 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45804 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!"));
45805 +
45806 + switch (counter)
45807 + {
45808 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45809 + if (!p_FmPcd->p_FmPcdKg)
45810 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working"));
45811 + break;
45812 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45813 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45814 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45815 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45816 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45817 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45818 + if (!p_FmPcd->p_FmPcdPlcr)
45819 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working"));
45820 + if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
45821 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
45822 + break;
45823 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45824 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45825 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45826 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45827 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45828 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45829 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45830 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45831 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45832 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45833 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45834 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45835 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45836 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45837 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45838 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45839 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45840 + if (!p_FmPcd->p_FmPcdPrs)
45841 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
45842 + break;
45843 + default:
45844 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
45845 + }
45846 + switch (counter)
45847 + {
45848 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45849 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value);
45850 + break;
45851 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45852 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value);
45853 + break;
45854 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45855 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value);
45856 + break;
45857 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45858 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value);
45859 + break;
45860 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45861 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value);
45862 + break;
45863 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45864 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value);
45865 + break;
45866 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45867 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value);
45868 + break;
45869 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45870 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value);
45871 + break;
45872 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45873 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value);
45874 + break;
45875 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45876 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value);
45877 + break;
45878 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45879 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value);
45880 + break;
45881 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45882 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value);
45883 + break;
45884 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45885 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value);
45886 + break;
45887 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45888 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value);
45889 + break;
45890 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45891 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value);
45892 + break;
45893 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45894 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value);
45895 + break;
45896 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45897 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value);
45898 + break;
45899 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45900 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value);
45901 + break;
45902 +
45903 + /*Policer counters*/
45904 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45905 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value);
45906 + break;
45907 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45908 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value);
45909 + break;
45910 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45911 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value);
45912 + break;
45913 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45914 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value);
45915 + break;
45916 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45917 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value);
45918 + break;
45919 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45920 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value);
45921 + break;
45922 + }
45923 +
45924 + return E_OK;
45925 +}
45926 +
45927 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd)
45928 +{
45929 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45930 + return FmHcGetPort(p_FmPcd->h_Hc);
45931 +}
45932 +
45933 --- /dev/null
45934 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
45935 @@ -0,0 +1,543 @@
45936 +/*
45937 + * Copyright 2008-2012 Freescale Semiconductor Inc.
45938 + *
45939 + * Redistribution and use in source and binary forms, with or without
45940 + * modification, are permitted provided that the following conditions are met:
45941 + * * Redistributions of source code must retain the above copyright
45942 + * notice, this list of conditions and the following disclaimer.
45943 + * * Redistributions in binary form must reproduce the above copyright
45944 + * notice, this list of conditions and the following disclaimer in the
45945 + * documentation and/or other materials provided with the distribution.
45946 + * * Neither the name of Freescale Semiconductor nor the
45947 + * names of its contributors may be used to endorse or promote products
45948 + * derived from this software without specific prior written permission.
45949 + *
45950 + *
45951 + * ALTERNATIVELY, this software may be distributed under the terms of the
45952 + * GNU General Public License ("GPL") as published by the Free Software
45953 + * Foundation, either version 2 of that License or (at your option) any
45954 + * later version.
45955 + *
45956 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
45957 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45958 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45959 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
45960 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
45961 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45962 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45963 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45964 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45965 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45966 + */
45967 +
45968 +
45969 +/******************************************************************************
45970 + @File fm_pcd.h
45971 +
45972 + @Description FM PCD ...
45973 +*//***************************************************************************/
45974 +#ifndef __FM_PCD_H
45975 +#define __FM_PCD_H
45976 +
45977 +#include "std_ext.h"
45978 +#include "error_ext.h"
45979 +#include "list_ext.h"
45980 +#include "fm_pcd_ext.h"
45981 +#include "fm_common.h"
45982 +#include "fsl_fman_prs.h"
45983 +#include "fsl_fman_kg.h"
45984 +
45985 +#define __ERR_MODULE__ MODULE_FM_PCD
45986 +
45987 +
45988 +/****************************/
45989 +/* Defaults */
45990 +/****************************/
45991 +#define DEFAULT_plcrAutoRefresh FALSE
45992 +#define DEFAULT_fmPcdKgErrorExceptions (FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW)
45993 +#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
45994 +#define DEFAULT_fmPcdPlcrExceptions 0
45995 +#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC)
45996 +
45997 +#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC
45998 +#define DEFAULT_numOfUsedProfilesPerWindow 16
45999 +#define DEFAULT_numOfSharedPlcrProfiles 4
46000 +
46001 +/****************************/
46002 +/* Network defines */
46003 +/****************************/
46004 +#define UDP_HEADER_SIZE 8
46005 +
46006 +#define ESP_SPI_OFFSET 0
46007 +#define ESP_SPI_SIZE 4
46008 +#define ESP_SEQ_NUM_OFFSET ESP_SPI_SIZE
46009 +#define ESP_SEQ_NUM_SIZE 4
46010 +
46011 +/****************************/
46012 +/* General defines */
46013 +/****************************/
46014 +#define ILLEGAL_CLS_PLAN 0xff
46015 +#define ILLEGAL_NETENV 0xff
46016 +
46017 +#define FM_PCD_MAX_NUM_OF_ALIAS_HDRS 3
46018 +
46019 +/****************************/
46020 +/* Error defines */
46021 +/****************************/
46022 +
46023 +#define FM_PCD_EX_PLCR_DOUBLE_ECC 0x20000000
46024 +#define FM_PCD_EX_PLCR_INIT_ENTRY_ERROR 0x10000000
46025 +#define FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE 0x08000000
46026 +#define FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE 0x04000000
46027 +
46028 +#define GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception) \
46029 +switch (exception){ \
46030 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: \
46031 + bitMask = FM_EX_KG_DOUBLE_ECC; break; \
46032 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: \
46033 + bitMask = FM_PCD_EX_PLCR_DOUBLE_ECC; break; \
46034 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: \
46035 + bitMask = FM_EX_KG_KEYSIZE_OVERFLOW; break; \
46036 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: \
46037 + bitMask = FM_PCD_EX_PLCR_INIT_ENTRY_ERROR; break; \
46038 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: \
46039 + bitMask = FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE; break; \
46040 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: \
46041 + bitMask = FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE; break; \
46042 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: \
46043 + bitMask = FM_PCD_EX_PRS_DOUBLE_ECC; break; \
46044 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: \
46045 + bitMask = FM_PCD_EX_PRS_SINGLE_ECC; break; \
46046 + default: bitMask = 0;break;}
46047 +
46048 +/***********************************************************************/
46049 +/* Policer defines */
46050 +/***********************************************************************/
46051 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
46052 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
46053 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
46054 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
46055 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
46056 +
46057 +/***********************************************************************/
46058 +/* Memory map */
46059 +/***********************************************************************/
46060 +#if defined(__MWERKS__) && !defined(__GNUC__)
46061 +#pragma pack(push,1)
46062 +#endif /* defined(__MWERKS__) && ... */
46063 +
46064 +
46065 +typedef struct {
46066 +/* General Configuration and Status Registers */
46067 + volatile uint32_t fmpl_gcr; /* 0x000 FMPL_GCR - FM Policer General Configuration */
46068 + volatile uint32_t fmpl_gsr; /* 0x004 FMPL_GSR - FM Policer Global Status Register */
46069 + volatile uint32_t fmpl_evr; /* 0x008 FMPL_EVR - FM Policer Event Register */
46070 + volatile uint32_t fmpl_ier; /* 0x00C FMPL_IER - FM Policer Interrupt Enable Register */
46071 + volatile uint32_t fmpl_ifr; /* 0x010 FMPL_IFR - FM Policer Interrupt Force Register */
46072 + volatile uint32_t fmpl_eevr; /* 0x014 FMPL_EEVR - FM Policer Error Event Register */
46073 + volatile uint32_t fmpl_eier; /* 0x018 FMPL_EIER - FM Policer Error Interrupt Enable Register */
46074 + volatile uint32_t fmpl_eifr; /* 0x01C FMPL_EIFR - FM Policer Error Interrupt Force Register */
46075 +/* Global Statistic Counters */
46076 + volatile uint32_t fmpl_rpcnt; /* 0x020 FMPL_RPC - FM Policer RED Packets Counter */
46077 + volatile uint32_t fmpl_ypcnt; /* 0x024 FMPL_YPC - FM Policer YELLOW Packets Counter */
46078 + volatile uint32_t fmpl_rrpcnt; /* 0x028 FMPL_RRPC - FM Policer Recolored RED Packet Counter */
46079 + volatile uint32_t fmpl_rypcnt; /* 0x02C FMPL_RYPC - FM Policer Recolored YELLOW Packet Counter */
46080 + volatile uint32_t fmpl_tpcnt; /* 0x030 FMPL_TPC - FM Policer Total Packet Counter */
46081 + volatile uint32_t fmpl_flmcnt; /* 0x034 FMPL_FLMC - FM Policer Frame Length Mismatch Counter */
46082 + volatile uint32_t fmpl_res0[21]; /* 0x038 - 0x08B Reserved */
46083 +/* Profile RAM Access Registers */
46084 + volatile uint32_t fmpl_par; /* 0x08C FMPL_PAR - FM Policer Profile Action Register*/
46085 + t_FmPcdPlcrProfileRegs profileRegs;
46086 +/* Error Capture Registers */
46087 + volatile uint32_t fmpl_serc; /* 0x100 FMPL_SERC - FM Policer Soft Error Capture */
46088 + volatile uint32_t fmpl_upcr; /* 0x104 FMPL_UPCR - FM Policer Uninitialized Profile Capture Register */
46089 + volatile uint32_t fmpl_res2; /* 0x108 Reserved */
46090 +/* Debug Registers */
46091 + volatile uint32_t fmpl_res3[61]; /* 0x10C-0x200 Reserved Debug*/
46092 +/* Profile Selection Mapping Registers Per Port-ID (n=1-11, 16) */
46093 + volatile uint32_t fmpl_dpmr; /* 0x200 FMPL_DPMR - FM Policer Default Mapping Register */
46094 + volatile uint32_t fmpl_pmr[63]; /*+default 0x204-0x2FF FMPL_PMR1 - FMPL_PMR63, - FM Policer Profile Mapping Registers.
46095 + (for port-ID 1-11, only for supported Port-ID registers) */
46096 +} t_FmPcdPlcrRegs;
46097 +
46098 +#if defined(__MWERKS__) && !defined(__GNUC__)
46099 +#pragma pack(pop)
46100 +#endif /* defined(__MWERKS__) && ... */
46101 +
46102 +
46103 +/***********************************************************************/
46104 +/* Driver's internal structures */
46105 +/***********************************************************************/
46106 +
46107 +typedef struct {
46108 + bool known;
46109 + uint8_t id;
46110 +} t_FmPcdKgSchemesExtractsEntry;
46111 +
46112 +typedef struct {
46113 + t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
46114 +} t_FmPcdKgSchemesExtracts;
46115 +
46116 +typedef struct {
46117 + t_Handle h_Manip;
46118 + bool keepRes;
46119 + e_FmPcdEngine nextEngine;
46120 + uint8_t parseCode;
46121 +} t_FmPcdInfoForManip;
46122 +
46123 +/**************************************************************************//**
46124 + @Description A structure of parameters to communicate
46125 + between the port and PCD regarding the KG scheme.
46126 +*//***************************************************************************/
46127 +typedef struct {
46128 + uint8_t netEnvId; /* in */
46129 + uint8_t numOfDistinctionUnits; /* in */
46130 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */
46131 + uint32_t vector; /* out */
46132 +} t_NetEnvParams;
46133 +
46134 +typedef struct {
46135 + bool allocated;
46136 + uint8_t ownerId; /* guestId for KG in multi-partition only.
46137 + portId for PLCR in any environment */
46138 +} t_FmPcdAllocMng;
46139 +
46140 +typedef struct {
46141 + volatile bool lock;
46142 + bool used;
46143 + uint8_t owners;
46144 + uint8_t netEnvId;
46145 + uint8_t guestId;
46146 + uint8_t baseEntry;
46147 + uint16_t sizeOfGrp;
46148 + protocolOpt_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
46149 +} t_FmPcdKgClsPlanGrp;
46150 +
46151 +typedef struct {
46152 + t_Handle h_FmPcd;
46153 + uint8_t schemeId;
46154 + t_FmPcdLock *p_Lock;
46155 + bool valid;
46156 + uint8_t netEnvId;
46157 + uint8_t owners;
46158 + uint32_t matchVector;
46159 + uint32_t ccUnits;
46160 + bool nextRelativePlcrProfile;
46161 + uint16_t relativeProfileId;
46162 + uint16_t numOfProfiles;
46163 + t_FmPcdKgKeyOrder orderedArray;
46164 + e_FmPcdEngine nextEngine;
46165 + e_FmPcdDoneAction doneAction;
46166 + bool requiredActionFlag;
46167 + uint32_t requiredAction;
46168 + bool extractedOrs;
46169 + uint8_t bitOffsetInPlcrProfile;
46170 + bool directPlcr;
46171 +#if (DPAA_VERSION >= 11)
46172 + bool vspe;
46173 +#endif
46174 +} t_FmPcdKgScheme;
46175 +
46176 +typedef union {
46177 + struct fman_kg_scheme_regs schemeRegs;
46178 + struct fman_kg_pe_regs portRegs;
46179 + struct fman_kg_cp_regs clsPlanRegs;
46180 +} u_FmPcdKgIndirectAccessRegs;
46181 +
46182 +typedef struct {
46183 + struct fman_kg_regs *p_FmPcdKgRegs;
46184 + uint32_t schemeExceptionsBitMask;
46185 + uint8_t numOfSchemes;
46186 + t_Handle h_HwSpinlock;
46187 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46188 + t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES];
46189 + t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS];
46190 + uint8_t emptyClsPlanGrpId;
46191 + t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */
46192 + t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP];
46193 + u_FmPcdKgIndirectAccessRegs *p_IndirectAccessRegs;
46194 +} t_FmPcdKg;
46195 +
46196 +typedef struct {
46197 + uint16_t profilesBase;
46198 + uint16_t numOfProfiles;
46199 + t_Handle h_FmPort;
46200 +} t_FmPcdPlcrMapParam;
46201 +
46202 +typedef struct {
46203 + uint16_t absoluteProfileId;
46204 + t_Handle h_FmPcd;
46205 + bool valid;
46206 + t_FmPcdLock *p_Lock;
46207 + t_FmPcdAllocMng profilesMng;
46208 + bool requiredActionFlag;
46209 + uint32_t requiredAction;
46210 + e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */
46211 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */
46212 +
46213 + e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */
46214 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */
46215 +
46216 + e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */
46217 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */
46218 +} t_FmPcdPlcrProfile;
46219 +
46220 +typedef struct {
46221 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
46222 + uint16_t partPlcrProfilesBase;
46223 + uint16_t partNumOfPlcrProfiles;
46224 + t_FmPcdPlcrProfile profiles[FM_PCD_PLCR_NUM_ENTRIES];
46225 + uint16_t numOfSharedProfiles;
46226 + uint16_t sharedProfilesIds[FM_PCD_PLCR_NUM_ENTRIES];
46227 + t_FmPcdPlcrMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
46228 + t_Handle h_HwSpinlock;
46229 + t_Handle h_SwSpinlock;
46230 +} t_FmPcdPlcr;
46231 +
46232 +typedef struct {
46233 + uint32_t *p_SwPrsCode;
46234 + uint32_t *p_CurrSwPrs;
46235 + uint8_t currLabel;
46236 + struct fman_prs_regs *p_FmPcdPrsRegs;
46237 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
46238 + uint32_t fmPcdPrsPortIdStatistics;
46239 +} t_FmPcdPrs;
46240 +
46241 +typedef struct {
46242 + struct {
46243 + e_NetHeaderType hdr;
46244 + protocolOpt_t opt; /* only one option !! */
46245 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
46246 +} t_FmPcdIntDistinctionUnit;
46247 +
46248 +typedef struct {
46249 + e_NetHeaderType hdr;
46250 + protocolOpt_t opt; /* only one option !! */
46251 + e_NetHeaderType aliasHdr;
46252 +} t_FmPcdNetEnvAliases;
46253 +
46254 +typedef struct {
46255 + uint8_t netEnvId;
46256 + t_Handle h_FmPcd;
46257 + t_Handle h_Spinlock;
46258 + bool used;
46259 + uint8_t owners;
46260 + uint8_t clsPlanGrpId;
46261 + t_FmPcdIntDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46262 + uint32_t unitsVectors[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46263 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
46264 + uint32_t macsecVector;
46265 + t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_ALIAS_HDRS];
46266 +} t_FmPcdNetEnv;
46267 +
46268 +typedef struct {
46269 + struct fman_prs_cfg dfltCfg;
46270 + bool plcrAutoRefresh;
46271 + uint16_t prsMaxParseCycleLimit;
46272 +} t_FmPcdDriverParam;
46273 +
46274 +typedef struct {
46275 + t_Handle h_Fm;
46276 + t_Handle h_FmMuram;
46277 + t_FmRevisionInfo fmRevInfo;
46278 +
46279 + uint64_t physicalMuramBase;
46280 +
46281 + t_Handle h_Spinlock;
46282 + t_List freeLocksLst;
46283 + t_List acquiredLocksLst;
46284 +
46285 + t_Handle h_IpcSession; /* relevant for guest only */
46286 + bool enabled;
46287 + uint8_t guestId; /**< Guest Partition Id */
46288 + uint8_t numOfEnabledGuestPartitionsPcds;
46289 + char fmPcdModuleName[MODULE_NAME_SIZE];
46290 + char fmPcdIpcHandlerModuleName[MODULE_NAME_SIZE]; /* relevant for guest only - this is the master's name */
46291 + t_FmPcdNetEnv netEnvs[FM_MAX_NUM_OF_PORTS];
46292 + t_FmPcdKg *p_FmPcdKg;
46293 + t_FmPcdPlcr *p_FmPcdPlcr;
46294 + t_FmPcdPrs *p_FmPcdPrs;
46295 +
46296 + void *p_CcShadow; /**< CC MURAM shadow */
46297 + uint32_t ccShadowSize;
46298 + uint32_t ccShadowAlign;
46299 + volatile bool shadowLock;
46300 + t_Handle h_ShadowSpinlock;
46301 +
46302 + t_Handle h_Hc;
46303 +
46304 + uint32_t exceptions;
46305 + t_FmPcdExceptionCallback *f_Exception;
46306 + t_FmPcdIdExceptionCallback *f_FmPcdIndexedException;
46307 + t_Handle h_App;
46308 + uintptr_t ipv6FrameIdAddr;
46309 + uintptr_t capwapFrameIdAddr;
46310 + bool advancedOffloadSupport;
46311 +
46312 + t_FmPcdDriverParam *p_FmPcdDriverParam;
46313 +} t_FmPcd;
46314 +
46315 +#if (DPAA_VERSION >= 11)
46316 +typedef uint8_t t_FmPcdFrmReplicUpdateType;
46317 +#define FRM_REPLIC_UPDATE_COUNTER 0x01
46318 +#define FRM_REPLIC_UPDATE_INFO 0x02
46319 +#endif /* (DPAA_VERSION >= 11) */
46320 +/***********************************************************************/
46321 +/* PCD internal routines */
46322 +/***********************************************************************/
46323 +
46324 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector);
46325 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params);
46326 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector);
46327 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams);
46328 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId);
46329 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46330 +uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46331 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt);
46332 +
46333 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, bool isIpv4, uint8_t groupId);
46334 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip);
46335 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, uint8_t groupId);
46336 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip);
46337 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip);
46338 +
46339 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46340 +t_Error KgInit(t_FmPcd *p_FmPcd);
46341 +t_Error KgFree(t_FmPcd *p_FmPcd);
46342 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set);
46343 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId);
46344 +void KgEnable(t_FmPcd *p_FmPcd);
46345 +void KgDisable(t_FmPcd *p_FmPcd);
46346 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First);
46347 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base);
46348 +
46349 +/* only for MULTI partittion */
46350 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46351 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46352 +/* only for SINGLE partittion */
46353 +t_Error KgBindPortToSchemes(t_Handle h_FmPcd , uint8_t hardwarePortId, uint32_t spReg);
46354 +
46355 +t_FmPcdLock *FmPcdAcquireLock(t_Handle h_FmPcd);
46356 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock);
46357 +
46358 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46359 +t_Error PlcrInit(t_FmPcd *p_FmPcd);
46360 +t_Error PlcrFree(t_FmPcd *p_FmPcd);
46361 +void PlcrEnable(t_FmPcd *p_FmPcd);
46362 +void PlcrDisable(t_FmPcd *p_FmPcd);
46363 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46364 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46365 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
46366 + uint8_t hardwarePortId,
46367 + uint16_t numOfProfiles,
46368 + uint16_t base);
46369 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId);
46370 +
46371 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams);
46372 +t_Error PrsInit(t_FmPcd *p_FmPcd);
46373 +void PrsEnable(t_FmPcd *p_FmPcd);
46374 +void PrsDisable(t_FmPcd *p_FmPcd);
46375 +void PrsFree(t_FmPcd *p_FmPcd );
46376 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include);
46377 +
46378 +t_Error FmPcdCcGetGrpParams(t_Handle treeId, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase);
46379 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
46380 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
46381 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode);
46382 +t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, e_FmPcdCcStatsMode supportedStatsMode);
46383 +
46384 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46385 +t_Error FmPcdManipCheckParamsForCcNextEngine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction);
46386 +void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip,
46387 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
46388 + t_Handle p_Ad,
46389 + t_Handle *p_AdNewPtr);
46390 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset);
46391 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46392 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode);
46393 +#ifdef FM_CAPWAP_SUPPORT
46394 +t_Handle FmPcdManipApplSpecificBuild(void);
46395 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip);
46396 +#endif /* FM_CAPWAP_SUPPORT */
46397 +#if (DPAA_VERSION >= 11)
46398 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup);
46399 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, bool add);
46400 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, void *p_Ad, t_Handle *h_AdNew);
46401 +
46402 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
46403 + t_Handle h_ReplicGroup,
46404 + t_List *p_AdTables,
46405 + uint32_t *p_NumOfAdTables);
46406 +#endif /* (DPAA_VERSION >= 11) */
46407 +
46408 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, t_Handle h_Spinlock);
46409 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46410 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46411 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip);
46412 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip);
46413 +
46414 +typedef struct
46415 +{
46416 + t_Handle h_StatsAd;
46417 + t_Handle h_StatsCounters;
46418 +#if (DPAA_VERSION >= 11)
46419 + t_Handle h_StatsFLRs;
46420 +#endif /* (DPAA_VERSION >= 11) */
46421 +} t_FmPcdCcStatsParams;
46422 +
46423 +void NextStepAd(t_Handle h_Ad,
46424 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
46425 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
46426 + t_FmPcd *p_FmPcd);
46427 +void ReleaseLst(t_List *p_List);
46428 +
46429 +static __inline__ t_Handle FmPcdGetMuramHandle(t_Handle h_FmPcd)
46430 +{
46431 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46432 + ASSERT_COND(p_FmPcd);
46433 + return p_FmPcd->h_FmMuram;
46434 +}
46435 +
46436 +static __inline__ uint64_t FmPcdGetMuramPhysBase(t_Handle h_FmPcd)
46437 +{
46438 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46439 + ASSERT_COND(p_FmPcd);
46440 + return p_FmPcd->physicalMuramBase;
46441 +}
46442 +
46443 +static __inline__ uint32_t FmPcdLockSpinlock(t_FmPcdLock *p_Lock)
46444 +{
46445 + ASSERT_COND(p_Lock);
46446 + return XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46447 +}
46448 +
46449 +static __inline__ void FmPcdUnlockSpinlock(t_FmPcdLock *p_Lock, uint32_t flags)
46450 +{
46451 + ASSERT_COND(p_Lock);
46452 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, flags);
46453 +}
46454 +
46455 +static __inline__ bool FmPcdLockTryLock(t_FmPcdLock *p_Lock)
46456 +{
46457 + uint32_t intFlags;
46458 +
46459 + ASSERT_COND(p_Lock);
46460 + intFlags = XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46461 + if (p_Lock->flag)
46462 + {
46463 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46464 + return FALSE;
46465 + }
46466 + p_Lock->flag = TRUE;
46467 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46468 + return TRUE;
46469 +}
46470 +
46471 +static __inline__ void FmPcdLockUnlock(t_FmPcdLock *p_Lock)
46472 +{
46473 + ASSERT_COND(p_Lock);
46474 + p_Lock->flag = FALSE;
46475 +}
46476 +
46477 +
46478 +#endif /* __FM_PCD_H */
46479 --- /dev/null
46480 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
46481 @@ -0,0 +1,280 @@
46482 +/*
46483 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46484 + *
46485 + * Redistribution and use in source and binary forms, with or without
46486 + * modification, are permitted provided that the following conditions are met:
46487 + * * Redistributions of source code must retain the above copyright
46488 + * notice, this list of conditions and the following disclaimer.
46489 + * * Redistributions in binary form must reproduce the above copyright
46490 + * notice, this list of conditions and the following disclaimer in the
46491 + * documentation and/or other materials provided with the distribution.
46492 + * * Neither the name of Freescale Semiconductor nor the
46493 + * names of its contributors may be used to endorse or promote products
46494 + * derived from this software without specific prior written permission.
46495 + *
46496 + *
46497 + * ALTERNATIVELY, this software may be distributed under the terms of the
46498 + * GNU General Public License ("GPL") as published by the Free Software
46499 + * Foundation, either version 2 of that License or (at your option) any
46500 + * later version.
46501 + *
46502 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46503 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46504 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46505 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46506 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46507 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46508 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46509 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46510 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46511 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46512 + */
46513 +
46514 +
46515 +/**************************************************************************//**
46516 + @File fm_pcd_ipc.h
46517 +
46518 + @Description FM PCD Inter-Partition prototypes, structures and definitions.
46519 +*//***************************************************************************/
46520 +#ifndef __FM_PCD_IPC_H
46521 +#define __FM_PCD_IPC_H
46522 +
46523 +#include "std_ext.h"
46524 +
46525 +
46526 +/**************************************************************************//**
46527 + @Group FM_grp Frame Manager API
46528 +
46529 + @Description FM API functions, definitions and enums
46530 +
46531 + @{
46532 +*//***************************************************************************/
46533 +
46534 +
46535 +#if defined(__MWERKS__) && !defined(__GNUC__)
46536 +#pragma pack(push,1)
46537 +#endif /* defined(__MWERKS__) && ... */
46538 +
46539 +/**************************************************************************//**
46540 + @Description Structure for getting a sw parser address according to a label
46541 + Fields commented 'IN' are passed by the port module to be used
46542 + by the FM module.
46543 + Fields commented 'OUT' will be filled by FM before returning to port.
46544 +*//***************************************************************************/
46545 +typedef _Packed struct t_FmPcdIpcSwPrsLable
46546 +{
46547 + uint32_t enumHdr; /**< IN. The existence of this header will invoke
46548 + the sw parser code. */
46549 + uint8_t indexPerHdr; /**< IN. Normally 0, if more than one sw parser
46550 + attachments for the same header, use this
46551 +
46552 + index to distinguish between them. */
46553 +} _PackedType t_FmPcdIpcSwPrsLable;
46554 +
46555 +/**************************************************************************//**
46556 + @Description Structure for port-PCD communication.
46557 + Fields commented 'IN' are passed by the port module to be used
46558 + by the FM module.
46559 + Fields commented 'OUT' will be filled by FM before returning to port.
46560 + Some fields are optional (depending on configuration) and
46561 + will be analized by the port and FM modules accordingly.
46562 +*//***************************************************************************/
46563 +
46564 +typedef struct t_FmPcdIpcKgSchemesParams
46565 +{
46566 + uint8_t guestId;
46567 + uint8_t numOfSchemes;
46568 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46569 +} _PackedType t_FmPcdIpcKgSchemesParams;
46570 +
46571 +typedef struct t_FmPcdIpcKgClsPlanParams
46572 +{
46573 + uint8_t guestId;
46574 + uint16_t numOfClsPlanEntries;
46575 + uint8_t clsPlanBase;
46576 +} _PackedType t_FmPcdIpcKgClsPlanParams;
46577 +
46578 +typedef _Packed struct t_FmPcdIpcPrsIncludePort
46579 +{
46580 + uint8_t hardwarePortId;
46581 + bool include;
46582 +} _PackedType t_FmPcdIpcPrsIncludePort;
46583 +
46584 +
46585 +#define FM_PCD_MAX_REPLY_SIZE 16
46586 +#define FM_PCD_MAX_MSG_SIZE 36
46587 +#define FM_PCD_MAX_REPLY_BODY_SIZE 36
46588 +
46589 +typedef _Packed struct {
46590 + uint32_t msgId;
46591 + uint8_t msgBody[FM_PCD_MAX_MSG_SIZE];
46592 +} _PackedType t_FmPcdIpcMsg;
46593 +
46594 +typedef _Packed struct t_FmPcdIpcReply {
46595 + uint32_t error;
46596 + uint8_t replyBody[FM_PCD_MAX_REPLY_BODY_SIZE];
46597 +} _PackedType t_FmPcdIpcReply;
46598 +
46599 +typedef _Packed struct t_FmIpcResourceAllocParams {
46600 + uint8_t guestId;
46601 + uint16_t base;
46602 + uint16_t num;
46603 +}_PackedType t_FmIpcResourceAllocParams;
46604 +
46605 +#if defined(__MWERKS__) && !defined(__GNUC__)
46606 +#pragma pack(pop)
46607 +#endif /* defined(__MWERKS__) && ... */
46608 +
46609 +
46610 +
46611 +/**************************************************************************//**
46612 + @Function FM_PCD_ALLOC_KG_SCHEMES
46613 +
46614 + @Description Used by FM PCD front-end in order to allocate KG resources
46615 +
46616 + @Param[in/out] t_FmPcdIpcKgAllocParams Pointer
46617 +*//***************************************************************************/
46618 +#define FM_PCD_ALLOC_KG_SCHEMES 3
46619 +
46620 +/**************************************************************************//**
46621 + @Function FM_PCD_FREE_KG_SCHEMES
46622 +
46623 + @Description Used by FM PCD front-end in order to Free KG resources
46624 +
46625 + @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer
46626 +*//***************************************************************************/
46627 +#define FM_PCD_FREE_KG_SCHEMES 4
46628 +
46629 +/**************************************************************************//**
46630 + @Function FM_PCD_ALLOC_PROFILES
46631 +
46632 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46633 +
46634 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46635 +*//***************************************************************************/
46636 +#define FM_PCD_ALLOC_PROFILES 5
46637 +
46638 +/**************************************************************************//**
46639 + @Function FM_PCD_FREE_PROFILES
46640 +
46641 + @Description Used by FM PCD front-end in order to Free Policer profiles
46642 +
46643 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46644 +*//***************************************************************************/
46645 +#define FM_PCD_FREE_PROFILES 6
46646 +
46647 +/**************************************************************************//**
46648 + @Function FM_PCD_SET_PORT_PROFILES
46649 +
46650 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46651 + for specific port
46652 +
46653 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46654 +*//***************************************************************************/
46655 +#define FM_PCD_SET_PORT_PROFILES 7
46656 +
46657 +/**************************************************************************//**
46658 + @Function FM_PCD_CLEAR_PORT_PROFILES
46659 +
46660 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46661 + for specific port
46662 +
46663 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46664 +*//***************************************************************************/
46665 +#define FM_PCD_CLEAR_PORT_PROFILES 8
46666 +
46667 +/**************************************************************************//**
46668 + @Function FM_PCD_GET_PHYS_MURAM_BASE
46669 +
46670 + @Description Used by FM PCD front-end in order to get MURAM base address
46671 +
46672 + @Param[in/out] t_FmPcdIcPhysAddr Pointer
46673 +*//***************************************************************************/
46674 +#define FM_PCD_GET_PHYS_MURAM_BASE 9
46675 +
46676 +/**************************************************************************//**
46677 + @Function FM_PCD_GET_SW_PRS_OFFSET
46678 +
46679 + @Description Used by FM front-end to get the SW parser offset of the start of
46680 + code relevant to a given label.
46681 +
46682 + @Param[in/out] t_FmPcdIpcSwPrsLable Pointer
46683 +*//***************************************************************************/
46684 +#define FM_PCD_GET_SW_PRS_OFFSET 10
46685 +
46686 +/**************************************************************************//**
46687 + @Function FM_PCD_MASTER_IS_ENABLED
46688 +
46689 + @Description Used by FM front-end in order to verify
46690 + PCD enablement.
46691 +
46692 + @Param[in] bool Pointer
46693 +*//***************************************************************************/
46694 +#define FM_PCD_MASTER_IS_ENABLED 15
46695 +
46696 +/**************************************************************************//**
46697 + @Function FM_PCD_GUEST_DISABLE
46698 +
46699 + @Description Used by FM front-end to inform back-end when
46700 + front-end PCD is disabled
46701 +
46702 + @Param[in] None
46703 +*//***************************************************************************/
46704 +#define FM_PCD_GUEST_DISABLE 16
46705 +
46706 +/**************************************************************************//**
46707 + @Function FM_PCD_FREE_KG_CLSPLAN
46708 +
46709 + @Description Used by FM PCD front-end in order to Free KG classification plan entries
46710 +
46711 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46712 +*//***************************************************************************/
46713 +#define FM_PCD_FREE_KG_CLSPLAN 22
46714 +
46715 +/**************************************************************************//**
46716 + @Function FM_PCD_ALLOC_KG_CLSPLAN
46717 +
46718 + @Description Used by FM PCD front-end in order to allocate KG classification plan entries
46719 +
46720 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46721 +*//***************************************************************************/
46722 +#define FM_PCD_ALLOC_KG_CLSPLAN 23
46723 +
46724 +/**************************************************************************//**
46725 + @Function FM_PCD_MASTER_IS_ALIVE
46726 +
46727 + @Description Used by FM front-end to check that back-end exists
46728 +
46729 + @Param[in] None
46730 +*//***************************************************************************/
46731 +#define FM_PCD_MASTER_IS_ALIVE 24
46732 +
46733 +/**************************************************************************//**
46734 + @Function FM_PCD_GET_COUNTER
46735 +
46736 + @Description Used by FM front-end to read PCD counters
46737 +
46738 + @Param[in/out] t_FmPcdIpcGetCounter Pointer
46739 +*//***************************************************************************/
46740 +#define FM_PCD_GET_COUNTER 25
46741 +
46742 +/**************************************************************************//**
46743 + @Function FM_PCD_PRS_INC_PORT_STATS
46744 +
46745 + @Description Used by FM front-end to set/clear statistics for port
46746 +
46747 + @Param[in/out] t_FmPcdIpcPrsIncludePort Pointer
46748 +*//***************************************************************************/
46749 +#define FM_PCD_PRS_INC_PORT_STATS 26
46750 +
46751 +#if (DPAA_VERSION >= 11)
46752 +/* TODO - doc */
46753 +#define FM_PCD_ALLOC_SP 27
46754 +#endif /* (DPAA_VERSION >= 11) */
46755 +
46756 +
46757 +/** @} */ /* end of FM_PCD_IPC_grp group */
46758 +/** @} */ /* end of FM_grp group */
46759 +
46760 +
46761 +#endif /* __FM_PCD_IPC_H */
46762 --- /dev/null
46763 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
46764 @@ -0,0 +1,1847 @@
46765 +/*
46766 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46767 + *
46768 + * Redistribution and use in source and binary forms, with or without
46769 + * modification, are permitted provided that the following conditions are met:
46770 + * * Redistributions of source code must retain the above copyright
46771 + * notice, this list of conditions and the following disclaimer.
46772 + * * Redistributions in binary form must reproduce the above copyright
46773 + * notice, this list of conditions and the following disclaimer in the
46774 + * documentation and/or other materials provided with the distribution.
46775 + * * Neither the name of Freescale Semiconductor nor the
46776 + * names of its contributors may be used to endorse or promote products
46777 + * derived from this software without specific prior written permission.
46778 + *
46779 + *
46780 + * ALTERNATIVELY, this software may be distributed under the terms of the
46781 + * GNU General Public License ("GPL") as published by the Free Software
46782 + * Foundation, either version 2 of that License or (at your option) any
46783 + * later version.
46784 + *
46785 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46786 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46787 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46788 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46789 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46790 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46791 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46792 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46793 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46794 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46795 + */
46796 +
46797 +
46798 +/******************************************************************************
46799 + @File fm_plcr.c
46800 +
46801 + @Description FM PCD POLICER...
46802 +*//***************************************************************************/
46803 +#include <linux/math64.h>
46804 +#include "std_ext.h"
46805 +#include "error_ext.h"
46806 +#include "string_ext.h"
46807 +#include "debug_ext.h"
46808 +#include "net_ext.h"
46809 +#include "fm_ext.h"
46810 +
46811 +#include "fm_common.h"
46812 +#include "fm_pcd.h"
46813 +#include "fm_hc.h"
46814 +#include "fm_pcd_ipc.h"
46815 +#include "fm_plcr.h"
46816 +
46817 +
46818 +/****************************************/
46819 +/* static functions */
46820 +/****************************************/
46821 +
46822 +static uint32_t PlcrProfileLock(t_Handle h_Profile)
46823 +{
46824 + ASSERT_COND(h_Profile);
46825 + return FmPcdLockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46826 +}
46827 +
46828 +static void PlcrProfileUnlock(t_Handle h_Profile, uint32_t intFlags)
46829 +{
46830 + ASSERT_COND(h_Profile);
46831 + FmPcdUnlockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock, intFlags);
46832 +}
46833 +
46834 +static bool PlcrProfileFlagTryLock(t_Handle h_Profile)
46835 +{
46836 + ASSERT_COND(h_Profile);
46837 + return FmPcdLockTryLock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46838 +}
46839 +
46840 +static void PlcrProfileFlagUnlock(t_Handle h_Profile)
46841 +{
46842 + ASSERT_COND(h_Profile);
46843 + FmPcdLockUnlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46844 +}
46845 +
46846 +static uint32_t PlcrHwLock(t_Handle h_FmPcdPlcr)
46847 +{
46848 + ASSERT_COND(h_FmPcdPlcr);
46849 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock);
46850 +}
46851 +
46852 +static void PlcrHwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
46853 +{
46854 + ASSERT_COND(h_FmPcdPlcr);
46855 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock, intFlags);
46856 +}
46857 +
46858 +static uint32_t PlcrSwLock(t_Handle h_FmPcdPlcr)
46859 +{
46860 + ASSERT_COND(h_FmPcdPlcr);
46861 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock);
46862 +}
46863 +
46864 +static void PlcrSwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
46865 +{
46866 + ASSERT_COND(h_FmPcdPlcr);
46867 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock, intFlags);
46868 +}
46869 +
46870 +static bool IsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId)
46871 +{
46872 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46873 + uint16_t i;
46874 +
46875 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE);
46876 +
46877 + for (i=0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++)
46878 + if (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId)
46879 + return TRUE;
46880 + return FALSE;
46881 +}
46882 +
46883 +static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction)
46884 +{
46885 + uint32_t nia;
46886 + uint16_t absoluteProfileId;
46887 + uint8_t relativeSchemeId, physicalSchemeId;
46888 +
46889 + nia = FM_PCD_PLCR_NIA_VALID;
46890 +
46891 + switch (nextEngine)
46892 + {
46893 + case e_FM_PCD_DONE :
46894 + switch (p_NextEngineParams->action)
46895 + {
46896 + case e_FM_PCD_DROP_FRAME :
46897 + nia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
46898 + break;
46899 + case e_FM_PCD_ENQ_FRAME:
46900 + nia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
46901 + break;
46902 + default:
46903 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
46904 + }
46905 + break;
46906 + case e_FM_PCD_KG:
46907 + physicalSchemeId = FmPcdKgGetSchemeId(p_NextEngineParams->h_DirectScheme);
46908 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
46909 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
46910 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
46911 + if (!FmPcdKgIsSchemeValidSw(p_NextEngineParams->h_DirectScheme))
46912 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
46913 + if (!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId))
46914 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct."));
46915 + nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicalSchemeId;
46916 + break;
46917 + case e_FM_PCD_PLCR:
46918 + absoluteProfileId = ((t_FmPcdPlcrProfile *)p_NextEngineParams->h_Profile)->absoluteProfileId;
46919 + if (!IsProfileShared(p_FmPcd, absoluteProfileId))
46920 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile"));
46921 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
46922 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile "));
46923 + nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId;
46924 + break;
46925 + default:
46926 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
46927 + }
46928 +
46929 + *nextAction = nia;
46930 +
46931 + return E_OK;
46932 +}
46933 +
46934 +static uint32_t CalcFPP(uint32_t fpp)
46935 +{
46936 + if (fpp > 15)
46937 + return 15 - (0x1f - fpp);
46938 + else
46939 + return 16 + fpp;
46940 +}
46941 +
46942 +static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode,
46943 + uint32_t rate,
46944 + uint64_t tsuInTenthNano,
46945 + uint32_t fppShift,
46946 + uint64_t *p_Integer,
46947 + uint64_t *p_Fraction)
46948 +{
46949 + uint64_t tmp, div;
46950 +
46951 + if (rateMode == e_FM_PCD_PLCR_BYTE_MODE)
46952 + {
46953 + /* now we calculate the initial integer for the bigger rate */
46954 + /* from Kbps to Bytes/TSU */
46955 + tmp = (uint64_t)rate;
46956 + tmp *= 1000; /* kb --> b */
46957 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
46958 +
46959 + div = 1000000000; /* nano */
46960 + div *= 10; /* 10 nano */
46961 + div *= 8; /* bit to byte */
46962 + }
46963 + else
46964 + {
46965 + /* now we calculate the initial integer for the bigger rate */
46966 + /* from Kbps to Bytes/TSU */
46967 + tmp = (uint64_t)rate;
46968 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
46969 +
46970 + div = 1000000000; /* nano */
46971 + div *= 10; /* 10 nano */
46972 + }
46973 + *p_Integer = div64_u64(tmp<<fppShift, div);
46974 +
46975 + /* for calculating the fraction, we will recalculate cir and deduct the integer.
46976 + * For precision, we will multiply by 2^16. we do not divid back, since we write
46977 + * this value as fraction - see spec.
46978 + */
46979 + *p_Fraction = div64_u64(((tmp<<fppShift)<<16) - ((*p_Integer<<16)*div), div);
46980 +}
46981 +
46982 +/* .......... */
46983 +
46984 +static void CalcRates(uint32_t bitFor1Micro,
46985 + t_FmPcdPlcrNonPassthroughAlgParams *p_NonPassthroughAlgParam,
46986 + uint32_t *cir,
46987 + uint32_t *cbs,
46988 + uint32_t *pir_eir,
46989 + uint32_t *pbs_ebs,
46990 + uint32_t *fpp)
46991 +{
46992 + uint64_t integer, fraction;
46993 + uint32_t temp, tsuInTenthNanos;
46994 + uint8_t fppShift=0;
46995 +
46996 + /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */
46997 + tsuInTenthNanos = (uint32_t)(1000*10/(1 << bitFor1Micro));
46998 +
46999 + /* we choose the faster rate to calibrate fpp */
47000 + /* The meaning of this step:
47001 + * when fppShift is 0 it means all TS bits are treated as integer and TSU is the TS LSB count.
47002 + * In this configuration we calculate the integer and fraction that represent the higher infoRate
47003 + * When this is done, we can tell where we have "spare" unused bits and optimize the division of TS
47004 + * into "integer" and "fraction" where the logic is - as many bits as possible for integer at
47005 + * high rate, as many bits as possible for fraction at low rate.
47006 + */
47007 + if (p_NonPassthroughAlgParam->committedInfoRate > p_NonPassthroughAlgParam->peakOrExcessInfoRate)
47008 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
47009 + else
47010 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
47011 +
47012 + /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and
47013 + * the LSB bits are for the fraction */
47014 + temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF);
47015 + /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll
47016 + * take max FP = 31.
47017 + * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is
47018 + * limited by the 10G physical port.
47019 + */
47020 + if (temp != 0)
47021 + {
47022 + /* In this case, the largest rate integer is non 0, if it does not occupy all (high) 16
47023 + * bits of the PIR_EIR we can use this fact and enlarge it to occupy all 16 bits.
47024 + * The logic is to have as many bits for integer in the higher rates, but if we have "0"s
47025 + * in the integer part of the cir/pir register, than these bits are wasted. So we want
47026 + * to use these bits for the fraction. in this way we will have for fraction - the number
47027 + * of "0" bits and the rest - for integer.
47028 + * In other words: For each bit we shift it in PIR_EIR, we move the FP in the TS
47029 + * one bit to the left - preserving the relationship and achieving more bits
47030 + * for integer in the TS.
47031 + */
47032 +
47033 + /* count zeroes left of the higher used bit (in order to shift the value such that
47034 + * unused bits may be used for fraction).
47035 + */
47036 + while ((temp & 0x80000000) == 0)
47037 + {
47038 + temp = temp << 1;
47039 + fppShift++;
47040 + }
47041 + if (fppShift > 15)
47042 + {
47043 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small"));
47044 + return;
47045 + }
47046 + }
47047 + else
47048 + {
47049 + temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */
47050 + if (!temp)
47051 + /* integer and fraction are 0, we set FP to its max val */
47052 + fppShift = 31;
47053 + else
47054 + {
47055 + /* integer was 0 but fraction is not. FP is 16 for the fraction,
47056 + * + all left zeroes of the fraction. */
47057 + fppShift=16;
47058 + /* count zeroes left of the higher used bit (in order to shift the value such that
47059 + * unused bits may be used for fraction).
47060 + */
47061 + while ((temp & 0x8000) == 0)
47062 + {
47063 + temp = temp << 1;
47064 + fppShift++;
47065 + }
47066 + }
47067 + }
47068 +
47069 + /*
47070 + * This means that the FM TS register will now be used so that 'fppShift' bits are for
47071 + * fraction and the rest for integer */
47072 + /* now we re-calculate cir and pir_eir with the calculated FP */
47073 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
47074 + *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
47075 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
47076 + *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
47077 +
47078 + *cbs = p_NonPassthroughAlgParam->committedBurstSize;
47079 + *pbs_ebs = p_NonPassthroughAlgParam->peakOrExcessBurstSize;
47080 +
47081 + /* convert FP as it should be written to reg.
47082 + * 0-15 --> 16-31
47083 + * 16-31 --> 0-15
47084 + */
47085 + *fpp = CalcFPP(fppShift);
47086 +}
47087 +
47088 +static void WritePar(t_FmPcd *p_FmPcd, uint32_t par)
47089 +{
47090 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47091 +
47092 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47093 + WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par);
47094 +
47095 + while (GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ;
47096 +}
47097 +
47098 +static t_Error BuildProfileRegs(t_FmPcd *p_FmPcd,
47099 + t_FmPcdPlcrProfileParams *p_ProfileParams,
47100 + t_FmPcdPlcrProfileRegs *p_PlcrRegs)
47101 +{
47102 + t_Error err = E_OK;
47103 + uint32_t pemode, gnia, ynia, rnia, bitFor1Micro;
47104 +
47105 + ASSERT_COND(p_FmPcd);
47106 +
47107 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
47108 + if (bitFor1Micro == 0)
47109 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
47110 +
47111 +/* Set G, Y, R Nia */
47112 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnGreen, &(p_ProfileParams->paramsOnGreen), &gnia);
47113 + if (err)
47114 + RETURN_ERROR(MAJOR, err, NO_MSG);
47115 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnYellow, &(p_ProfileParams->paramsOnYellow), &ynia);
47116 + if (err)
47117 + RETURN_ERROR(MAJOR, err, NO_MSG);
47118 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnRed, &(p_ProfileParams->paramsOnRed), &rnia);
47119 + if (err)
47120 + RETURN_ERROR(MAJOR, err, NO_MSG);
47121 +
47122 +/* Mode fmpl_pemode */
47123 + pemode = FM_PCD_PLCR_PEMODE_PI;
47124 +
47125 + switch (p_ProfileParams->algSelection)
47126 + {
47127 + case e_FM_PCD_PLCR_PASS_THROUGH:
47128 + p_PlcrRegs->fmpl_pecir = 0;
47129 + p_PlcrRegs->fmpl_pecbs = 0;
47130 + p_PlcrRegs->fmpl_pepepir_eir = 0;
47131 + p_PlcrRegs->fmpl_pepbs_ebs = 0;
47132 + p_PlcrRegs->fmpl_pelts = 0;
47133 + p_PlcrRegs->fmpl_pects = 0;
47134 + p_PlcrRegs->fmpl_pepts_ets = 0;
47135 + pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK;
47136 + switch (p_ProfileParams->colorMode)
47137 + {
47138 + case e_FM_PCD_PLCR_COLOR_BLIND:
47139 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47140 + switch (p_ProfileParams->color.dfltColor)
47141 + {
47142 + case e_FM_PCD_PLCR_GREEN:
47143 + pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK;
47144 + break;
47145 + case e_FM_PCD_PLCR_YELLOW:
47146 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_Y;
47147 + break;
47148 + case e_FM_PCD_PLCR_RED:
47149 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_R;
47150 + break;
47151 + case e_FM_PCD_PLCR_OVERRIDE:
47152 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE;
47153 + break;
47154 + default:
47155 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47156 + }
47157 +
47158 + break;
47159 + case e_FM_PCD_PLCR_COLOR_AWARE:
47160 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47161 + break;
47162 + default:
47163 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47164 + }
47165 + break;
47166 +
47167 + case e_FM_PCD_PLCR_RFC_2698:
47168 + /* Select algorithm MODE[ALG] = "01" */
47169 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698;
47170 + if (p_ProfileParams->nonPassthroughAlgParams.committedInfoRate > p_ProfileParams->nonPassthroughAlgParams.peakOrExcessInfoRate)
47171 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than committedInfoRate."));
47172 + goto cont_rfc;
47173 + case e_FM_PCD_PLCR_RFC_4115:
47174 + /* Select algorithm MODE[ALG] = "10" */
47175 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115;
47176 +cont_rfc:
47177 + /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */
47178 + switch (p_ProfileParams->colorMode)
47179 + {
47180 + case e_FM_PCD_PLCR_COLOR_BLIND:
47181 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47182 + break;
47183 + case e_FM_PCD_PLCR_COLOR_AWARE:
47184 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47185 + /*In color aware more select override color interpretation (MODE[OVCLR]) */
47186 + switch (p_ProfileParams->color.override)
47187 + {
47188 + case e_FM_PCD_PLCR_GREEN:
47189 + pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK;
47190 + break;
47191 + case e_FM_PCD_PLCR_YELLOW:
47192 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_Y;
47193 + break;
47194 + case e_FM_PCD_PLCR_RED:
47195 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_R;
47196 + break;
47197 + case e_FM_PCD_PLCR_OVERRIDE:
47198 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_G_NC;
47199 + break;
47200 + default:
47201 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47202 + }
47203 + break;
47204 + default:
47205 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47206 + }
47207 + /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */
47208 + switch (p_ProfileParams->nonPassthroughAlgParams.rateMode)
47209 + {
47210 + case e_FM_PCD_PLCR_BYTE_MODE :
47211 + pemode &= ~FM_PCD_PLCR_PEMODE_PKT;
47212 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.frameLengthSelection)
47213 + {
47214 + case e_FM_PCD_PLCR_L2_FRM_LEN:
47215 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L2;
47216 + break;
47217 + case e_FM_PCD_PLCR_L3_FRM_LEN:
47218 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L3;
47219 + break;
47220 + case e_FM_PCD_PLCR_L4_FRM_LEN:
47221 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L4;
47222 + break;
47223 + case e_FM_PCD_PLCR_FULL_FRM_LEN:
47224 + pemode |= FM_PCD_PLCR_PEMODE_FLS_FULL;
47225 + break;
47226 + default:
47227 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47228 + }
47229 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection)
47230 + {
47231 + case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN:
47232 + pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS;
47233 + break;
47234 + case e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN:
47235 + pemode |= FM_PCD_PLCR_PEMODE_RBFLS;
47236 + break;
47237 + default:
47238 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47239 + }
47240 + break;
47241 + case e_FM_PCD_PLCR_PACKET_MODE :
47242 + pemode |= FM_PCD_PLCR_PEMODE_PKT;
47243 + break;
47244 + default:
47245 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47246 + }
47247 + /* Select timeStamp floating point position (MODE[FPP]) to fit the actual traffic rates. For PACKET
47248 + mode with low traffic rates move the fixed point to the left to increase fraction accuracy. For BYTE
47249 + mode with high traffic rates move the fixed point to the right to increase integer accuracy. */
47250 +
47251 + /* Configure Traffic Parameters*/
47252 + {
47253 + uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0;
47254 +
47255 + CalcRates(bitFor1Micro, &p_ProfileParams->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp);
47256 +
47257 + /* Set Committed Information Rate (CIR) */
47258 + p_PlcrRegs->fmpl_pecir = cir;
47259 + /* Set Committed Burst Size (CBS). */
47260 + p_PlcrRegs->fmpl_pecbs = cbs;
47261 + /* Set Peak Information Rate (PIR_EIR used as PIR) */
47262 + p_PlcrRegs->fmpl_pepepir_eir = pir_eir;
47263 + /* Set Peak Burst Size (PBS_EBS used as PBS) */
47264 + p_PlcrRegs->fmpl_pepbs_ebs = pbs_ebs;
47265 +
47266 + /* Initialize the Metering Buckets to be full (write them with 0xFFFFFFFF. */
47267 + /* Peak Rate Token Bucket Size (PTS_ETS used as PTS) */
47268 + p_PlcrRegs->fmpl_pepts_ets = 0xFFFFFFFF;
47269 + /* Committed Rate Token Bucket Size (CTS) */
47270 + p_PlcrRegs->fmpl_pects = 0xFFFFFFFF;
47271 +
47272 + /* Set the FPP based on calculation */
47273 + pemode |= (fpp << FM_PCD_PLCR_PEMODE_FPP_SHIFT);
47274 + }
47275 + break; /* FM_PCD_PLCR_PEMODE_ALG_RFC2698 , FM_PCD_PLCR_PEMODE_ALG_RFC4115 */
47276 + default:
47277 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47278 + }
47279 +
47280 + p_PlcrRegs->fmpl_pemode = pemode;
47281 +
47282 + p_PlcrRegs->fmpl_pegnia = gnia;
47283 + p_PlcrRegs->fmpl_peynia = ynia;
47284 + p_PlcrRegs->fmpl_pernia = rnia;
47285 +
47286 + /* Zero Counters */
47287 + p_PlcrRegs->fmpl_pegpc = 0;
47288 + p_PlcrRegs->fmpl_peypc = 0;
47289 + p_PlcrRegs->fmpl_perpc = 0;
47290 + p_PlcrRegs->fmpl_perypc = 0;
47291 + p_PlcrRegs->fmpl_perrpc = 0;
47292 +
47293 + return E_OK;
47294 +}
47295 +
47296 +static t_Error AllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47297 +{
47298 + uint32_t profilesFound;
47299 + uint16_t i, k=0;
47300 + uint32_t intFlags;
47301 +
47302 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47303 +
47304 + if (!numOfProfiles)
47305 + return E_OK;
47306 +
47307 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
47308 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
47309 +
47310 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47311 + /* Find numOfProfiles free profiles (may be spread) */
47312 + profilesFound = 0;
47313 + for (i=0;i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47314 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
47315 + {
47316 + profilesFound++;
47317 + profilesIds[k] = i;
47318 + k++;
47319 + if (profilesFound == numOfProfiles)
47320 + break;
47321 + }
47322 +
47323 + if (profilesFound != numOfProfiles)
47324 + {
47325 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47326 + RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG);
47327 + }
47328 +
47329 + for (i = 0;i<k;i++)
47330 + {
47331 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE;
47332 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0;
47333 + }
47334 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47335 +
47336 + return E_OK;
47337 +}
47338 +
47339 +static void FreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47340 +{
47341 + uint16_t i;
47342 +
47343 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
47344 +
47345 + ASSERT_COND(numOfProfiles);
47346 +
47347 + for (i=0; i < numOfProfiles; i++)
47348 + {
47349 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated);
47350 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE;
47351 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = p_FmPcd->guestId;
47352 + }
47353 +}
47354 +
47355 +static void UpdateRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool set)
47356 +{
47357 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47358 +
47359 + /* this routine is protected by calling routine */
47360 +
47361 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
47362 +
47363 + if (set)
47364 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = TRUE;
47365 + else
47366 + {
47367 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = 0;
47368 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = FALSE;
47369 + }
47370 +}
47371 +
47372 +/*********************************************/
47373 +/*............Policer Exception..............*/
47374 +/*********************************************/
47375 +static void EventsCB(t_Handle h_FmPcd)
47376 +{
47377 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47378 + uint32_t event, mask, force;
47379 +
47380 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47381 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr);
47382 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
47383 +
47384 + event &= mask;
47385 +
47386 + /* clear the forced events */
47387 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr);
47388 + if (force & event)
47389 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event);
47390 +
47391 +
47392 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event);
47393 +
47394 + if (event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE)
47395 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE);
47396 + if (event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE)
47397 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE);
47398 +}
47399 +
47400 +/* ..... */
47401 +
47402 +static void ErrorExceptionsCB(t_Handle h_FmPcd)
47403 +{
47404 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47405 + uint32_t event, force, captureReg, mask;
47406 +
47407 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47408 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr);
47409 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
47410 +
47411 + event &= mask;
47412 +
47413 + /* clear the forced events */
47414 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr);
47415 + if (force & event)
47416 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event);
47417 +
47418 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event);
47419 +
47420 + if (event & FM_PCD_PLCR_DOUBLE_ECC)
47421 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC);
47422 + if (event & FM_PCD_PLCR_INIT_ENTRY_ERROR)
47423 + {
47424 + captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr);
47425 + /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP);
47426 + p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK);
47427 + p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ;
47428 + p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/
47429 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK));
47430 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP);
47431 + }
47432 +}
47433 +
47434 +
47435 +/*****************************************************************************/
47436 +/* Inter-module API routines */
47437 +/*****************************************************************************/
47438 +
47439 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
47440 +{
47441 + t_FmPcdPlcr *p_FmPcdPlcr;
47442 + uint16_t i=0;
47443 +
47444 + UNUSED(p_FmPcd);
47445 + UNUSED(p_FmPcdParams);
47446 +
47447 + p_FmPcdPlcr = (t_FmPcdPlcr *) XX_Malloc(sizeof(t_FmPcdPlcr));
47448 + if (!p_FmPcdPlcr)
47449 + {
47450 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer structure allocation FAILED"));
47451 + return NULL;
47452 + }
47453 + memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr));
47454 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
47455 + {
47456 + p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm));
47457 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh;
47458 + p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions);
47459 + }
47460 +
47461 + p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles;
47462 +
47463 + p_FmPcdPlcr->partPlcrProfilesBase = p_FmPcdParams->partPlcrProfilesBase;
47464 + p_FmPcdPlcr->partNumOfPlcrProfiles = p_FmPcdParams->partNumOfPlcrProfiles;
47465 + /* for backward compatabilty. if no policer profile, will set automatically to the max */
47466 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) &&
47467 + (p_FmPcdPlcr->partNumOfPlcrProfiles == 0))
47468 + p_FmPcdPlcr->partNumOfPlcrProfiles = FM_PCD_PLCR_NUM_ENTRIES;
47469 +
47470 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47471 + p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47472 +
47473 + return p_FmPcdPlcr;
47474 +}
47475 +
47476 +t_Error PlcrInit(t_FmPcd *p_FmPcd)
47477 +{
47478 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
47479 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
47480 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47481 + t_Error err = E_OK;
47482 + uint32_t tmpReg32 = 0;
47483 + uint16_t base;
47484 +
47485 + if ((p_FmPcdPlcr->partPlcrProfilesBase + p_FmPcdPlcr->partNumOfPlcrProfiles) > FM_PCD_PLCR_NUM_ENTRIES)
47486 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partPlcrProfilesBase+partNumOfPlcrProfiles out of range!!!"));
47487 +
47488 + p_FmPcdPlcr->h_HwSpinlock = XX_InitSpinlock();
47489 + if (!p_FmPcdPlcr->h_HwSpinlock)
47490 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer HW spinlock"));
47491 +
47492 + p_FmPcdPlcr->h_SwSpinlock = XX_InitSpinlock();
47493 + if (!p_FmPcdPlcr->h_SwSpinlock)
47494 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer SW spinlock"));
47495 +
47496 + base = PlcrAllocProfilesForPartition(p_FmPcd,
47497 + p_FmPcdPlcr->partPlcrProfilesBase,
47498 + p_FmPcdPlcr->partNumOfPlcrProfiles,
47499 + p_FmPcd->guestId);
47500 + if (base == (uint16_t)ILLEGAL_BASE)
47501 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
47502 +
47503 + if (p_FmPcdPlcr->numOfSharedProfiles)
47504 + {
47505 + err = AllocSharedProfiles(p_FmPcd,
47506 + p_FmPcdPlcr->numOfSharedProfiles,
47507 + p_FmPcdPlcr->sharedProfilesIds);
47508 + if (err)
47509 + RETURN_ERROR(MAJOR, err,NO_MSG);
47510 + }
47511 +
47512 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47513 + return E_OK;
47514 +
47515 + /**********************FMPL_GCR******************/
47516 + tmpReg32 = 0;
47517 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
47518 + if (p_Param->plcrAutoRefresh)
47519 + tmpReg32 |= FM_PCD_PLCR_GCR_DAR;
47520 + tmpReg32 |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
47521 +
47522 + WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32);
47523 + /**********************FMPL_GCR******************/
47524 +
47525 + /**********************FMPL_EEVR******************/
47526 + WRITE_UINT32(p_Regs->fmpl_eevr, (FM_PCD_PLCR_DOUBLE_ECC | FM_PCD_PLCR_INIT_ENTRY_ERROR));
47527 + /**********************FMPL_EEVR******************/
47528 + /**********************FMPL_EIER******************/
47529 + tmpReg32 = 0;
47530 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)
47531 + {
47532 + FmEnableRamsEcc(p_FmPcd->h_Fm);
47533 + tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC;
47534 + }
47535 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
47536 + tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
47537 + WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32);
47538 + /**********************FMPL_EIER******************/
47539 +
47540 + /**********************FMPL_EVR******************/
47541 + WRITE_UINT32(p_Regs->fmpl_evr, (FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE | FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE));
47542 + /**********************FMPL_EVR******************/
47543 + /**********************FMPL_IER******************/
47544 + tmpReg32 = 0;
47545 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE)
47546 + tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
47547 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE)
47548 + tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
47549 + WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32);
47550 + /**********************FMPL_IER******************/
47551 +
47552 + /* register even if no interrupts enabled, to allow future enablement */
47553 + FmRegisterIntr(p_FmPcd->h_Fm,
47554 + e_FM_MOD_PLCR,
47555 + 0,
47556 + e_FM_INTR_TYPE_ERR,
47557 + ErrorExceptionsCB,
47558 + p_FmPcd);
47559 + FmRegisterIntr(p_FmPcd->h_Fm,
47560 + e_FM_MOD_PLCR,
47561 + 0,
47562 + e_FM_INTR_TYPE_NORMAL,
47563 + EventsCB,
47564 + p_FmPcd);
47565 +
47566 + /* driver initializes one DFLT profile at the last entry*/
47567 + /**********************FMPL_DPMR******************/
47568 + tmpReg32 = 0;
47569 + WRITE_UINT32(p_Regs->fmpl_dpmr, tmpReg32);
47570 + p_FmPcd->p_FmPcdPlcr->profiles[0].profilesMng.allocated = TRUE;
47571 +
47572 + return E_OK;
47573 +}
47574 +
47575 +t_Error PlcrFree(t_FmPcd *p_FmPcd)
47576 +{
47577 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR);
47578 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL);
47579 +
47580 + if (p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles)
47581 + FreeSharedProfiles(p_FmPcd,
47582 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles,
47583 + p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);
47584 +
47585 + if (p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles)
47586 + PlcrFreeProfilesForPartition(p_FmPcd,
47587 + p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase,
47588 + p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles,
47589 + p_FmPcd->guestId);
47590 +
47591 + if (p_FmPcd->p_FmPcdPlcr->h_SwSpinlock)
47592 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_SwSpinlock);
47593 +
47594 + if (p_FmPcd->p_FmPcdPlcr->h_HwSpinlock)
47595 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_HwSpinlock);
47596 +
47597 + return E_OK;
47598 +}
47599 +
47600 +void PlcrEnable(t_FmPcd *p_FmPcd)
47601 +{
47602 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47603 +
47604 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN);
47605 +}
47606 +
47607 +void PlcrDisable(t_FmPcd *p_FmPcd)
47608 +{
47609 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47610 +
47611 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN);
47612 +}
47613 +
47614 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47615 +{
47616 + uint32_t intFlags;
47617 + uint16_t profilesFound = 0;
47618 + int i = 0;
47619 +
47620 + ASSERT_COND(p_FmPcd);
47621 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47622 +
47623 + if (!numOfProfiles)
47624 + return 0;
47625 +
47626 + if ((numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES) ||
47627 + (base + numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES))
47628 + return (uint16_t)ILLEGAL_BASE;
47629 +
47630 + if (p_FmPcd->h_IpcSession)
47631 + {
47632 + t_FmIpcResourceAllocParams ipcAllocParams;
47633 + t_FmPcdIpcMsg msg;
47634 + t_FmPcdIpcReply reply;
47635 + t_Error err;
47636 + uint32_t replyLength;
47637 +
47638 + memset(&msg, 0, sizeof(msg));
47639 + memset(&reply, 0, sizeof(reply));
47640 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47641 + ipcAllocParams.guestId = p_FmPcd->guestId;
47642 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47643 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47644 + msg.msgId = FM_PCD_ALLOC_PROFILES;
47645 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47646 + replyLength = sizeof(uint32_t) + sizeof(uint16_t);
47647 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47648 + (uint8_t*)&msg,
47649 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47650 + (uint8_t*)&reply,
47651 + &replyLength,
47652 + NULL,
47653 + NULL);
47654 + if ((err != E_OK) ||
47655 + (replyLength != (sizeof(uint32_t) + sizeof(uint16_t))))
47656 + {
47657 + REPORT_ERROR(MAJOR, err, NO_MSG);
47658 + return (uint16_t)ILLEGAL_BASE;
47659 + }
47660 + else
47661 + memcpy((uint8_t*)&p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, reply.replyBody, sizeof(uint16_t));
47662 + if (p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase == (uint16_t)ILLEGAL_BASE)
47663 + {
47664 + REPORT_ERROR(MAJOR, err, NO_MSG);
47665 + return (uint16_t)ILLEGAL_BASE;
47666 + }
47667 + }
47668 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47669 + {
47670 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47671 + return (uint16_t)ILLEGAL_BASE;
47672 + }
47673 +
47674 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
47675 + for (i=base; i<(base+numOfProfiles); i++)
47676 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
47677 + profilesFound++;
47678 + else
47679 + break;
47680 +
47681 + if (profilesFound == numOfProfiles)
47682 + for (i=base; i<(base+numOfProfiles); i++)
47683 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = guestId;
47684 + else
47685 + {
47686 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47687 + return (uint16_t)ILLEGAL_BASE;
47688 + }
47689 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47690 +
47691 + return base;
47692 +}
47693 +
47694 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47695 +{
47696 + int i = 0;
47697 +
47698 + ASSERT_COND(p_FmPcd);
47699 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47700 +
47701 + if (p_FmPcd->h_IpcSession)
47702 + {
47703 + t_FmIpcResourceAllocParams ipcAllocParams;
47704 + t_FmPcdIpcMsg msg;
47705 + t_Error err;
47706 +
47707 + memset(&msg, 0, sizeof(msg));
47708 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47709 + ipcAllocParams.guestId = p_FmPcd->guestId;
47710 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47711 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47712 + msg.msgId = FM_PCD_FREE_PROFILES;
47713 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47714 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47715 + (uint8_t*)&msg,
47716 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47717 + NULL,
47718 + NULL,
47719 + NULL,
47720 + NULL);
47721 + if (err != E_OK)
47722 + REPORT_ERROR(MAJOR, err, NO_MSG);
47723 + return;
47724 + }
47725 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47726 + {
47727 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47728 + return;
47729 + }
47730 +
47731 + for (i=base; i<(base+numOfProfiles); i++)
47732 + {
47733 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == guestId)
47734 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47735 + else
47736 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
47737 + }
47738 +}
47739 +
47740 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
47741 + uint8_t hardwarePortId,
47742 + uint16_t numOfProfiles,
47743 + uint16_t base)
47744 +{
47745 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47746 + uint32_t log2Num, tmpReg32;
47747 +
47748 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47749 + !p_Regs &&
47750 + p_FmPcd->h_IpcSession)
47751 + {
47752 + t_FmIpcResourceAllocParams ipcAllocParams;
47753 + t_FmPcdIpcMsg msg;
47754 + t_Error err;
47755 +
47756 + memset(&msg, 0, sizeof(msg));
47757 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47758 + ipcAllocParams.guestId = hardwarePortId;
47759 + ipcAllocParams.num = numOfProfiles;
47760 + ipcAllocParams.base = base;
47761 + msg.msgId = FM_PCD_SET_PORT_PROFILES;
47762 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47763 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47764 + (uint8_t*)&msg,
47765 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47766 + NULL,
47767 + NULL,
47768 + NULL,
47769 + NULL);
47770 + if (err != E_OK)
47771 + RETURN_ERROR(MAJOR, err, NO_MSG);
47772 + return E_OK;
47773 + }
47774 + else if (!p_Regs)
47775 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
47776 + ("Either IPC or 'baseAddress' is required!"));
47777 +
47778 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47779 +
47780 + if (GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V)
47781 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
47782 + ("The requesting port has already an allocated profiles window."));
47783 +
47784 + /**********************FMPL_PMRx******************/
47785 + LOG2((uint64_t)numOfProfiles, log2Num);
47786 + tmpReg32 = base;
47787 + tmpReg32 |= log2Num << 16;
47788 + tmpReg32 |= FM_PCD_PLCR_PMR_V;
47789 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32);
47790 +
47791 + return E_OK;
47792 +}
47793 +
47794 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
47795 +{
47796 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47797 +
47798 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47799 + !p_Regs &&
47800 + p_FmPcd->h_IpcSession)
47801 + {
47802 + t_FmIpcResourceAllocParams ipcAllocParams;
47803 + t_FmPcdIpcMsg msg;
47804 + t_Error err;
47805 +
47806 + memset(&msg, 0, sizeof(msg));
47807 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47808 + ipcAllocParams.guestId = hardwarePortId;
47809 + msg.msgId = FM_PCD_CLEAR_PORT_PROFILES;
47810 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47811 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47812 + (uint8_t*)&msg,
47813 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47814 + NULL,
47815 + NULL,
47816 + NULL,
47817 + NULL);
47818 + if (err != E_OK)
47819 + RETURN_ERROR(MAJOR, err, NO_MSG);
47820 + return E_OK;
47821 + }
47822 + else if (!p_Regs)
47823 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
47824 + ("Either IPC or 'baseAddress' is required!"));
47825 +
47826 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47827 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0);
47828 +
47829 + return E_OK;
47830 +}
47831 +
47832 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles)
47833 +{
47834 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47835 + t_Error err = E_OK;
47836 + uint32_t profilesFound;
47837 + uint32_t intFlags;
47838 + uint16_t i, first, swPortIndex = 0;
47839 +
47840 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47841 +
47842 + if (!numOfProfiles)
47843 + return E_OK;
47844 +
47845 + ASSERT_COND(hardwarePortId);
47846 +
47847 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
47848 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
47849 +
47850 + if (!POWER_OF_2(numOfProfiles))
47851 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
47852 +
47853 + first = 0;
47854 + profilesFound = 0;
47855 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47856 +
47857 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; )
47858 + {
47859 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
47860 + {
47861 + profilesFound++;
47862 + i++;
47863 + if (profilesFound == numOfProfiles)
47864 + break;
47865 + }
47866 + else
47867 + {
47868 + profilesFound = 0;
47869 + /* advance i to the next aligned address */
47870 + i = first = (uint16_t)(first + numOfProfiles);
47871 + }
47872 + }
47873 +
47874 + if (profilesFound == numOfProfiles)
47875 + {
47876 + for (i=first; i<first + numOfProfiles; i++)
47877 + {
47878 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE;
47879 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId;
47880 + }
47881 + }
47882 + else
47883 + {
47884 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47885 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
47886 + }
47887 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47888 +
47889 + err = PlcrSetPortProfiles(p_FmPcd, hardwarePortId, numOfProfiles, first);
47890 + if (err)
47891 + {
47892 + RETURN_ERROR(MAJOR, err, NO_MSG);
47893 + }
47894 +
47895 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
47896 +
47897 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles;
47898 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = first;
47899 +
47900 + return E_OK;
47901 +}
47902 +
47903 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
47904 +{
47905 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47906 + t_Error err = E_OK;
47907 + uint32_t intFlags;
47908 + uint16_t i, swPortIndex = 0;
47909 +
47910 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47911 +
47912 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47913 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
47914 +
47915 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
47916 +
47917 + err = PlcrClearPortProfiles(p_FmPcd, hardwarePortId);
47918 + if (err)
47919 + RETURN_ERROR(MAJOR, err,NO_MSG);
47920 +
47921 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47922 + for (i=p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
47923 + i<(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase +
47924 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles);
47925 + i++)
47926 + {
47927 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId);
47928 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated);
47929 +
47930 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE;
47931 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = p_FmPcd->guestId;
47932 + }
47933 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47934 +
47935 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0;
47936 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0;
47937 +
47938 + return E_OK;
47939 +}
47940 +
47941 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction)
47942 +{
47943 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47944 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
47945 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs;
47946 + uint32_t tmpReg32, intFlags;
47947 + t_Error err;
47948 +
47949 + /* Calling function locked all PCD modules, so no need to lock here */
47950 +
47951 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
47952 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range"));
47953 +
47954 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileIndx))
47955 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid"));
47956 +
47957 + /*intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx]);*/
47958 +
47959 + if (p_FmPcd->h_Hc)
47960 + {
47961 + err = FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction);
47962 +
47963 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
47964 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
47965 +
47966 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
47967 + return err;
47968 + }
47969 +
47970 + /* lock the HW because once we read the registers we don't want them to be changed
47971 + * by another access. (We can copy to a tmp location and release the lock!) */
47972 +
47973 + intFlags = PlcrHwLock(p_FmPcdPlcr);
47974 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
47975 +
47976 + if (!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredActionFlag ||
47977 + !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction))
47978 + {
47979 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
47980 + {
47981 + if ((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) ||
47982 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) ||
47983 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE))
47984 + {
47985 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
47986 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
47987 + RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE"));
47988 + }
47989 +
47990 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME)
47991 + {
47992 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia);
47993 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
47994 + {
47995 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
47996 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
47997 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
47998 + }
47999 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48000 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32);
48001 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48002 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
48003 + WritePar(p_FmPcd, tmpReg32);
48004 + }
48005 +
48006 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME)
48007 + {
48008 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia);
48009 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48010 + {
48011 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48012 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48013 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48014 + }
48015 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48016 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32);
48017 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48018 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
48019 + WritePar(p_FmPcd, tmpReg32);
48020 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48021 + }
48022 +
48023 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME)
48024 + {
48025 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia);
48026 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48027 + {
48028 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48029 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48030 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48031 + }
48032 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48033 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32);
48034 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48035 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
48036 + WritePar(p_FmPcd, tmpReg32);
48037 +
48038 + }
48039 + }
48040 + }
48041 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48042 +
48043 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
48044 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
48045 +
48046 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48047 +
48048 + return E_OK;
48049 +}
48050 +
48051 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48052 +{
48053 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48054 +
48055 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48056 +
48057 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag;
48058 +}
48059 +
48060 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48061 +{
48062 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48063 +
48064 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48065 +
48066 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction;
48067 +}
48068 +
48069 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48070 +{
48071 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48072 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48073 +
48074 + ASSERT_COND(absoluteProfileId < FM_PCD_PLCR_NUM_ENTRIES);
48075 +
48076 + return p_FmPcdPlcr->profiles[absoluteProfileId].valid;
48077 +}
48078 +
48079 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48080 +{
48081 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48082 + uint32_t intFlags;
48083 +
48084 + ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48085 +
48086 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
48087 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE;
48088 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
48089 +}
48090 +
48091 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48092 +{
48093 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48094 + uint32_t intFlags;
48095 +
48096 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48097 +
48098 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
48099 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE;
48100 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
48101 +}
48102 +
48103 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile)
48104 +{
48105 + return ((t_FmPcdPlcrProfile*)h_Profile)->absoluteProfileId;
48106 +}
48107 +
48108 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
48109 + e_FmPcdProfileTypeSelection profileType,
48110 + t_Handle h_FmPort,
48111 + uint16_t relativeProfile,
48112 + uint16_t *p_AbsoluteId)
48113 +{
48114 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48115 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48116 + uint8_t i;
48117 +
48118 + switch (profileType)
48119 + {
48120 + case e_FM_PCD_PLCR_PORT_PRIVATE:
48121 + /* get port PCD id from port handle */
48122 + for (i=0;i<FM_MAX_NUM_OF_PORTS;i++)
48123 + if (p_FmPcd->p_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort)
48124 + break;
48125 + if (i == FM_MAX_NUM_OF_PORTS)
48126 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle."));
48127 +
48128 + if (!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48129 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles"));
48130 + if (relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48131 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48132 + *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile);
48133 + break;
48134 + case e_FM_PCD_PLCR_SHARED:
48135 + if (relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles)
48136 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48137 + *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]);
48138 + break;
48139 + default:
48140 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type"));
48141 + }
48142 +
48143 + return E_OK;
48144 +}
48145 +
48146 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId)
48147 +{
48148 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48149 + uint16_t swPortIndex = 0;
48150 +
48151 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48152 +
48153 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
48154 +}
48155 +
48156 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
48157 +{
48158 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48159 + uint16_t swPortIndex = 0;
48160 +
48161 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48162 +
48163 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles;
48164 +
48165 +}
48166 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId)
48167 +{
48168 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48169 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT));
48170 +}
48171 +
48172 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId)
48173 +{
48174 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48175 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48176 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48177 +}
48178 +
48179 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg)
48180 +{
48181 +
48182 + if (profileModeReg & FM_PCD_PLCR_PEMODE_PI)
48183 + return TRUE;
48184 + else
48185 + return FALSE;
48186 +}
48187 +
48188 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId)
48189 +{
48190 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48191 + FM_PCD_PLCR_PAR_R |
48192 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48193 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48194 +}
48195 +
48196 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter)
48197 +{
48198 + switch (counter)
48199 + {
48200 + case (e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER):
48201 + return FM_PCD_PLCR_PAR_PWSEL_PEGPC;
48202 + case (e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER):
48203 + return FM_PCD_PLCR_PAR_PWSEL_PEYPC;
48204 + case (e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) :
48205 + return FM_PCD_PLCR_PAR_PWSEL_PERPC;
48206 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) :
48207 + return FM_PCD_PLCR_PAR_PWSEL_PERYPC;
48208 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) :
48209 + return FM_PCD_PLCR_PAR_PWSEL_PERRPC;
48210 + default:
48211 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48212 + return 0;
48213 + }
48214 +}
48215 +
48216 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red)
48217 +{
48218 +
48219 + uint32_t tmpReg32 = 0;
48220 +
48221 + if (green)
48222 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
48223 + if (yellow)
48224 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
48225 + if (red)
48226 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
48227 +
48228 + return tmpReg32;
48229 +}
48230 +
48231 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction)
48232 +{
48233 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48234 +
48235 + /* this routine is protected by calling routine */
48236 +
48237 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48238 +
48239 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction |= requiredAction;
48240 +}
48241 +
48242 +/*********************** End of inter-module routines ************************/
48243 +
48244 +
48245 +/**************************************************/
48246 +/*............Policer API.........................*/
48247 +/**************************************************/
48248 +
48249 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable)
48250 +{
48251 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48252 +
48253 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48254 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48255 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48256 +
48257 + if (!FmIsMaster(p_FmPcd->h_Fm))
48258 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!"));
48259 +
48260 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable;
48261 +
48262 + return E_OK;
48263 +}
48264 +
48265 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles)
48266 +{
48267 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48268 +
48269 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48270 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48271 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48272 +
48273 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles;
48274 +
48275 + return E_OK;
48276 +}
48277 +
48278 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable)
48279 +{
48280 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48281 + uint32_t tmpReg32;
48282 +
48283 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48284 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48285 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48286 +
48287 + if (!FmIsMaster(p_FmPcd->h_Fm))
48288 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!"));
48289 +
48290 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr);
48291 + if (enable)
48292 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
48293 + else
48294 + tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN;
48295 +
48296 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32);
48297 + return E_OK;
48298 +}
48299 +
48300 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
48301 + t_FmPcdPlcrProfileParams *p_ProfileParams)
48302 +{
48303 + t_FmPcd *p_FmPcd;
48304 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48305 + t_FmPcdPlcrProfileRegs plcrProfileReg;
48306 + uint32_t intFlags;
48307 + uint16_t absoluteProfileId;
48308 + t_Error err = E_OK;
48309 + uint32_t tmpReg32;
48310 + t_FmPcdPlcrProfile *p_Profile;
48311 +
48312 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
48313 +
48314 + if (p_ProfileParams->modify)
48315 + {
48316 + p_Profile = (t_FmPcdPlcrProfile *)p_ProfileParams->id.h_Profile;
48317 + p_FmPcd = p_Profile->h_FmPcd;
48318 + absoluteProfileId = p_Profile->absoluteProfileId;
48319 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48320 + {
48321 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48322 + return NULL;
48323 + }
48324 +
48325 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48326 +
48327 + /* Try lock profile using flag */
48328 + if (!PlcrProfileFlagTryLock(p_Profile))
48329 + {
48330 + DBG(TRACE, ("Profile Try Lock - BUSY"));
48331 + /* Signal to caller BUSY condition */
48332 + p_ProfileParams->id.h_Profile = NULL;
48333 + return NULL;
48334 + }
48335 + }
48336 + else
48337 + {
48338 + p_FmPcd = (t_FmPcd*)h_FmPcd;
48339 +
48340 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48341 +
48342 + /* SMP: needs to be protected only if another core now changes the windows */
48343 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(h_FmPcd,
48344 + p_ProfileParams->id.newParams.profileType,
48345 + p_ProfileParams->id.newParams.h_FmPort,
48346 + p_ProfileParams->id.newParams.relativeProfileId,
48347 + &absoluteProfileId);
48348 + if (err)
48349 + {
48350 + REPORT_ERROR(MAJOR, err, NO_MSG);
48351 + return NULL;
48352 + }
48353 +
48354 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48355 + {
48356 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48357 + return NULL;
48358 + }
48359 +
48360 + if (FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
48361 + {
48362 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used"));
48363 + return NULL;
48364 + }
48365 +
48366 + /* initialize profile struct */
48367 + p_Profile = &p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId];
48368 +
48369 + p_Profile->h_FmPcd = p_FmPcd;
48370 + p_Profile->absoluteProfileId = absoluteProfileId;
48371 +
48372 + p_Profile->p_Lock = FmPcdAcquireLock(p_FmPcd);
48373 + if (!p_Profile->p_Lock)
48374 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Policer Profile lock obj!"));
48375 + }
48376 +
48377 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
48378 +
48379 + p_Profile->nextEngineOnGreen = p_ProfileParams->nextEngineOnGreen;
48380 + memcpy(&p_Profile->paramsOnGreen, &(p_ProfileParams->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams));
48381 +
48382 + p_Profile->nextEngineOnYellow = p_ProfileParams->nextEngineOnYellow;
48383 + memcpy(&p_Profile->paramsOnYellow, &(p_ProfileParams->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams));
48384 +
48385 + p_Profile->nextEngineOnRed = p_ProfileParams->nextEngineOnRed;
48386 + memcpy(&p_Profile->paramsOnRed, &(p_ProfileParams->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams));
48387 +
48388 + memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrProfileRegs));
48389 +
48390 + /* build the policer profile registers */
48391 + err = BuildProfileRegs(h_FmPcd, p_ProfileParams, &plcrProfileReg);
48392 + if (err)
48393 + {
48394 + REPORT_ERROR(MAJOR, err, NO_MSG);
48395 + if (p_ProfileParams->modify)
48396 + /* unlock */
48397 + PlcrProfileFlagUnlock(p_Profile);
48398 + if (!p_ProfileParams->modify &&
48399 + p_Profile->p_Lock)
48400 + /* release allocated Profile lock */
48401 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48402 + return NULL;
48403 + }
48404 +
48405 + if (p_FmPcd->h_Hc)
48406 + {
48407 + err = FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, (t_Handle)p_Profile, &plcrProfileReg);
48408 + if (p_ProfileParams->modify)
48409 + PlcrProfileFlagUnlock(p_Profile);
48410 + if (err)
48411 + {
48412 + /* release the allocated scheme lock */
48413 + if (!p_ProfileParams->modify &&
48414 + p_Profile->p_Lock)
48415 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48416 +
48417 + return NULL;
48418 + }
48419 + if (!p_ProfileParams->modify)
48420 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48421 + return (t_Handle)p_Profile;
48422 + }
48423 +
48424 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48425 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL);
48426 +
48427 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48428 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode);
48429 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia);
48430 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia);
48431 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia , plcrProfileReg.fmpl_pernia);
48432 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecir , plcrProfileReg.fmpl_pecir);
48433 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecbs , plcrProfileReg.fmpl_pecbs);
48434 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepepir_eir,plcrProfileReg.fmpl_pepepir_eir);
48435 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepbs_ebs,plcrProfileReg.fmpl_pepbs_ebs);
48436 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pelts , plcrProfileReg.fmpl_pelts);
48437 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pects , plcrProfileReg.fmpl_pects);
48438 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepts_ets,plcrProfileReg.fmpl_pepts_ets);
48439 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc , plcrProfileReg.fmpl_pegpc);
48440 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc , plcrProfileReg.fmpl_peypc);
48441 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc , plcrProfileReg.fmpl_perpc);
48442 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc , plcrProfileReg.fmpl_perypc);
48443 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc , plcrProfileReg.fmpl_perrpc);
48444 +
48445 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId);
48446 + WritePar(p_FmPcd, tmpReg32);
48447 +
48448 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48449 +
48450 + if (!p_ProfileParams->modify)
48451 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48452 + else
48453 + PlcrProfileFlagUnlock(p_Profile);
48454 +
48455 + return (t_Handle)p_Profile;
48456 +}
48457 +
48458 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile)
48459 +{
48460 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48461 + t_FmPcd *p_FmPcd;
48462 + uint16_t profileIndx;
48463 + uint32_t tmpReg32, intFlags;
48464 + t_Error err;
48465 +
48466 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48467 + p_FmPcd = p_Profile->h_FmPcd;
48468 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48469 +
48470 + profileIndx = p_Profile->absoluteProfileId;
48471 +
48472 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, FALSE);
48473 +
48474 + FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx);
48475 +
48476 + if (p_FmPcd->h_Hc)
48477 + {
48478 + err = FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile);
48479 + if (p_Profile->p_Lock)
48480 + /* release allocated Profile lock */
48481 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48482 +
48483 + return err;
48484 + }
48485 +
48486 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48487 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI);
48488 +
48489 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
48490 + WritePar(p_FmPcd, tmpReg32);
48491 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48492 +
48493 +
48494 + if (p_Profile->p_Lock)
48495 + /* release allocated Profile lock */
48496 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48497 +
48498 + /* we do not memset profile as all its fields are being re-initialized at "set",
48499 + * plus its allocation information is still valid. */
48500 + return E_OK;
48501 +}
48502 +
48503 +/***************************************************/
48504 +/*............Policer Profile Counter..............*/
48505 +/***************************************************/
48506 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
48507 +{
48508 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48509 + t_FmPcd *p_FmPcd;
48510 + uint16_t profileIndx;
48511 + uint32_t intFlags, counterVal = 0;
48512 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48513 +
48514 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48515 + p_FmPcd = p_Profile->h_FmPcd;
48516 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48517 +
48518 + if (p_FmPcd->h_Hc)
48519 + return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter);
48520 +
48521 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48522 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0);
48523 +
48524 + profileIndx = p_Profile->absoluteProfileId;
48525 +
48526 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
48527 + {
48528 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48529 + return 0;
48530 + }
48531 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48532 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
48533 +
48534 + switch (counter)
48535 + {
48536 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48537 + counterVal = (GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc));
48538 + break;
48539 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48540 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc);
48541 + break;
48542 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48543 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc);
48544 + break;
48545 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48546 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc);
48547 + break;
48548 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48549 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc);
48550 + break;
48551 + default:
48552 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48553 + break;
48554 + }
48555 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48556 +
48557 + return counterVal;
48558 +}
48559 +
48560 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
48561 +{
48562 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48563 + t_FmPcd *p_FmPcd;
48564 + uint16_t profileIndx;
48565 + uint32_t tmpReg32, intFlags;
48566 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48567 +
48568 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48569 +
48570 + p_FmPcd = p_Profile->h_FmPcd;
48571 + profileIndx = p_Profile->absoluteProfileId;
48572 +
48573 + if (p_FmPcd->h_Hc)
48574 + return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value);
48575 +
48576 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48577 + SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE);
48578 +
48579 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48580 + switch (counter)
48581 + {
48582 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48583 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc, value);
48584 + break;
48585 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48586 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc, value);
48587 + break;
48588 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48589 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc, value);
48590 + break;
48591 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48592 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc ,value);
48593 + break;
48594 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48595 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value);
48596 + break;
48597 + default:
48598 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48599 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48600 + }
48601 +
48602 + /* Activate the atomic write action by writing FMPL_PAR with: GO=1, RW=1, PSI=0, PNUM =
48603 + * Profile Number, PWSEL=0xFFFF (select all words).
48604 + */
48605 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48606 + tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter);
48607 + WritePar(p_FmPcd, tmpReg32);
48608 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48609 +
48610 + return E_OK;
48611 +}
48612 --- /dev/null
48613 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
48614 @@ -0,0 +1,165 @@
48615 +/*
48616 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48617 + *
48618 + * Redistribution and use in source and binary forms, with or without
48619 + * modification, are permitted provided that the following conditions are met:
48620 + * * Redistributions of source code must retain the above copyright
48621 + * notice, this list of conditions and the following disclaimer.
48622 + * * Redistributions in binary form must reproduce the above copyright
48623 + * notice, this list of conditions and the following disclaimer in the
48624 + * documentation and/or other materials provided with the distribution.
48625 + * * Neither the name of Freescale Semiconductor nor the
48626 + * names of its contributors may be used to endorse or promote products
48627 + * derived from this software without specific prior written permission.
48628 + *
48629 + *
48630 + * ALTERNATIVELY, this software may be distributed under the terms of the
48631 + * GNU General Public License ("GPL") as published by the Free Software
48632 + * Foundation, either version 2 of that License or (at your option) any
48633 + * later version.
48634 + *
48635 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48636 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48637 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48638 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48639 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48640 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48641 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48642 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48643 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48644 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48645 + */
48646 +
48647 +
48648 +/******************************************************************************
48649 + @File fm_plcr.h
48650 +
48651 + @Description FM Policer private header
48652 +*//***************************************************************************/
48653 +#ifndef __FM_PLCR_H
48654 +#define __FM_PLCR_H
48655 +
48656 +#include "std_ext.h"
48657 +
48658 +
48659 +/***********************************************************************/
48660 +/* Policer defines */
48661 +/***********************************************************************/
48662 +
48663 +#define FM_PCD_PLCR_PAR_GO 0x80000000
48664 +#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF
48665 +#define FM_PCD_PLCR_PAR_R 0x40000000
48666 +
48667 +/* shifts */
48668 +#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16
48669 +
48670 +/* masks */
48671 +#define FM_PCD_PLCR_PEMODE_PI 0x80000000
48672 +#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000
48673 +#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000
48674 +#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000
48675 +#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000
48676 +#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000
48677 +#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000
48678 +#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000
48679 +#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000
48680 +#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000
48681 +#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000
48682 +#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000
48683 +#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000
48684 +#define FM_PCD_PLCR_PEMODE_PKT 0x00800000
48685 +#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000
48686 +#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16
48687 +#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000
48688 +#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000
48689 +#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000
48690 +#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000
48691 +#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000
48692 +#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800
48693 +#define FM_PCD_PLCR_PEMODE_TRA 0x00000004
48694 +#define FM_PCD_PLCR_PEMODE_TRB 0x00000002
48695 +#define FM_PCD_PLCR_PEMODE_TRC 0x00000001
48696 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
48697 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
48698 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
48699 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
48700 +
48701 +#define FM_PCD_PLCR_NIA_VALID 0x80000000
48702 +
48703 +#define FM_PCD_PLCR_GCR_EN 0x80000000
48704 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
48705 +#define FM_PCD_PLCR_GCR_DAR 0x20000000
48706 +#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF
48707 +#define FM_PCD_PLCR_NIA_ABS 0x00000100
48708 +
48709 +#define FM_PCD_PLCR_GSR_BSY 0x80000000
48710 +#define FM_PCD_PLCR_GSR_DQS 0x60000000
48711 +#define FM_PCD_PLCR_GSR_RPB 0x20000000
48712 +#define FM_PCD_PLCR_GSR_FQS 0x0C000000
48713 +#define FM_PCD_PLCR_GSR_LPALG 0x0000C000
48714 +#define FM_PCD_PLCR_GSR_LPCA 0x00003000
48715 +#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF
48716 +
48717 +#define FM_PCD_PLCR_EVR_PSIC 0x80000000
48718 +#define FM_PCD_PLCR_EVR_AAC 0x40000000
48719 +
48720 +#define FM_PCD_PLCR_PAR_PSI 0x20000000
48721 +#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000
48722 +/* PWSEL Selctive select options */
48723 +#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */
48724 +#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */
48725 +#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */
48726 +#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */
48727 +#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */
48728 +#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */
48729 +#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */
48730 +#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */
48731 +#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */
48732 +#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */
48733 +#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */
48734 +#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */
48735 +#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */
48736 +#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */
48737 +#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */
48738 +#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */
48739 +
48740 +#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1]
48741 + 1-> 2^N specific locations. */
48742 +#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}.
48743 + 2-> 2^(N-1) base locations. */
48744 +#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}.
48745 + 4-> 2^(N-2) base locations. */
48746 +#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}.
48747 + 8->2^(N-3) base locations. */
48748 +#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}.
48749 + 16-> 2^(N-4) base locations. */
48750 +#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}.
48751 + 32-> 2^(N-5) base locations. */
48752 +#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}.
48753 + 64-> 2^(N-6) base locations. */
48754 +#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}.
48755 + 128-> 2^(N-7) base locations. */
48756 +#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}.
48757 + When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */
48758 +
48759 +#define FM_PCD_PLCR_PMR_V 0x80000000
48760 +#define PLCR_ERR_ECC_CAP 0x80000000
48761 +#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000
48762 +#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0
48763 +#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F
48764 +
48765 +#define PLCR_ERR_UNINIT_CAP 0x80000000
48766 +#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF
48767 +#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000
48768 +#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000
48769 +
48770 +/* shifts */
48771 +#define PLCR_ERR_ECC_PNUM_SHIFT 4
48772 +#define PLCR_ERR_UNINIT_PID_SHIFT 16
48773 +
48774 +#define FM_PCD_PLCR_PMR_BRN_SHIFT 16
48775 +
48776 +#define PLCR_PORT_WINDOW_SIZE(hardwarePortId)
48777 +
48778 +
48779 +#endif /* __FM_PLCR_H */
48780 --- /dev/null
48781 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
48782 @@ -0,0 +1,423 @@
48783 +/*
48784 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48785 + *
48786 + * Redistribution and use in source and binary forms, with or without
48787 + * modification, are permitted provided that the following conditions are met:
48788 + * * Redistributions of source code must retain the above copyright
48789 + * notice, this list of conditions and the following disclaimer.
48790 + * * Redistributions in binary form must reproduce the above copyright
48791 + * notice, this list of conditions and the following disclaimer in the
48792 + * documentation and/or other materials provided with the distribution.
48793 + * * Neither the name of Freescale Semiconductor nor the
48794 + * names of its contributors may be used to endorse or promote products
48795 + * derived from this software without specific prior written permission.
48796 + *
48797 + *
48798 + * ALTERNATIVELY, this software may be distributed under the terms of the
48799 + * GNU General Public License ("GPL") as published by the Free Software
48800 + * Foundation, either version 2 of that License or (at your option) any
48801 + * later version.
48802 + *
48803 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48804 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48805 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48806 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48807 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48808 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48809 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48810 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48811 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48812 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48813 + */
48814 +
48815 +
48816 +/******************************************************************************
48817 + @File fm_pcd.c
48818 +
48819 + @Description FM PCD ...
48820 +*//***************************************************************************/
48821 +#include <linux/math64.h>
48822 +#include "std_ext.h"
48823 +#include "error_ext.h"
48824 +#include "string_ext.h"
48825 +#include "debug_ext.h"
48826 +#include "net_ext.h"
48827 +
48828 +#include "fm_common.h"
48829 +#include "fm_pcd.h"
48830 +#include "fm_pcd_ipc.h"
48831 +#include "fm_prs.h"
48832 +#include "fsl_fman_prs.h"
48833 +
48834 +
48835 +static void PcdPrsErrorException(t_Handle h_FmPcd)
48836 +{
48837 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48838 + uint32_t event, ev_mask;
48839 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48840 +
48841 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48842 + ev_mask = fman_prs_get_err_ev_mask(PrsRegs);
48843 +
48844 + event = fman_prs_get_err_event(PrsRegs, ev_mask);
48845 +
48846 + fman_prs_ack_err_event(PrsRegs, event);
48847 +
48848 + DBG(TRACE, ("parser error - 0x%08x\n",event));
48849 +
48850 + if(event & FM_PCD_PRS_DOUBLE_ECC)
48851 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
48852 +}
48853 +
48854 +static void PcdPrsException(t_Handle h_FmPcd)
48855 +{
48856 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48857 + uint32_t event, ev_mask;
48858 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48859 +
48860 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48861 + ev_mask = fman_prs_get_expt_ev_mask(PrsRegs);
48862 + event = fman_prs_get_expt_event(PrsRegs, ev_mask);
48863 +
48864 + ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
48865 +
48866 + DBG(TRACE, ("parser event - 0x%08x\n",event));
48867 +
48868 + fman_prs_ack_expt_event(PrsRegs, event);
48869 +
48870 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
48871 +}
48872 +
48873 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
48874 +{
48875 + t_FmPcdPrs *p_FmPcdPrs;
48876 + uintptr_t baseAddr;
48877 +
48878 + UNUSED(p_FmPcd);
48879 + UNUSED(p_FmPcdParams);
48880 +
48881 + p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
48882 + if (!p_FmPcdPrs)
48883 + {
48884 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
48885 + return NULL;
48886 + }
48887 + memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
48888 + fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg);
48889 +
48890 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
48891 + {
48892 + baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
48893 + p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr);
48894 + p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
48895 + }
48896 +
48897 + p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat;
48898 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim;
48899 + p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions;
48900 +
48901 + return p_FmPcdPrs;
48902 +}
48903 +
48904 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
48905 + static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH;
48906 +#else
48907 + static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH;
48908 +#endif /* FM_CAPWAP_SUPPORT */
48909 +
48910 +t_Error PrsInit(t_FmPcd *p_FmPcd)
48911 +{
48912 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
48913 + uint32_t *p_TmpCode;
48914 + uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode,
48915 + FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE);
48916 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48917 + uint32_t i;
48918 +
48919 + ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE));
48920 +
48921 + /* nothing to do in guest-partition */
48922 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
48923 + return E_OK;
48924 +
48925 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t));
48926 + if (!p_TmpCode)
48927 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
48928 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4));
48929 + memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch));
48930 +
48931 + fman_prs_init(PrsRegs, &p_Param->dfltCfg);
48932 +
48933 + /* register even if no interrupts enabled, to allow future enablement */
48934 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
48935 +
48936 + /* register even if no interrupts enabled, to allow future enablement */
48937 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
48938 +
48939 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
48940 + FmEnableRamsEcc(p_FmPcd->h_Fm);
48941 +
48942 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
48943 + FmEnableRamsEcc(p_FmPcd->h_Fm);
48944 +
48945 + /* load sw parser Ip-Frag patch */
48946 + for (i=0; i<DIV_CEIL(sizeof(swPrsPatch), 4); i++)
48947 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
48948 +
48949 + XX_FreeSmart(p_TmpCode);
48950 +
48951 + return E_OK;
48952 +}
48953 +
48954 +void PrsFree(t_FmPcd *p_FmPcd)
48955 +{
48956 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48957 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
48958 + /* register even if no interrupts enabled, to allow future enablement */
48959 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
48960 +}
48961 +
48962 +void PrsEnable(t_FmPcd *p_FmPcd)
48963 +{
48964 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48965 +
48966 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48967 + fman_prs_enable(PrsRegs);
48968 +}
48969 +
48970 +void PrsDisable(t_FmPcd *p_FmPcd)
48971 +{
48972 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48973 +
48974 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48975 + fman_prs_disable(PrsRegs);
48976 +}
48977 +
48978 +int PrsIsEnabled(t_FmPcd *p_FmPcd)
48979 +{
48980 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48981 +
48982 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48983 + return fman_prs_is_enabled(PrsRegs);
48984 +}
48985 +
48986 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
48987 +{
48988 + struct fman_prs_regs *PrsRegs;
48989 + uint32_t bitMask = 0;
48990 + uint8_t prsPortId;
48991 +
48992 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
48993 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48994 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
48995 +
48996 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48997 +
48998 + GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
48999 + GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
49000 +
49001 + if (include)
49002 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
49003 + else
49004 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
49005 +
49006 + fman_prs_set_stst_port_msk(PrsRegs,
49007 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
49008 +
49009 + return E_OK;
49010 +}
49011 +
49012 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
49013 +{
49014 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49015 + t_Error err;
49016 +
49017 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
49018 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49019 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49020 +
49021 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49022 + p_FmPcd->h_IpcSession)
49023 + {
49024 + t_FmPcdIpcPrsIncludePort prsIncludePortParams;
49025 + t_FmPcdIpcMsg msg;
49026 +
49027 + prsIncludePortParams.hardwarePortId = hardwarePortId;
49028 + prsIncludePortParams.include = include;
49029 + memset(&msg, 0, sizeof(msg));
49030 + msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
49031 + memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
49032 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49033 + (uint8_t*)&msg,
49034 + sizeof(msg.msgId) +sizeof(prsIncludePortParams),
49035 + NULL,
49036 + NULL,
49037 + NULL,
49038 + NULL);
49039 + if (err != E_OK)
49040 + RETURN_ERROR(MAJOR, err, NO_MSG);
49041 + return E_OK;
49042 + }
49043 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49044 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49045 + ("running in guest-mode without IPC!"));
49046 +
49047 + return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
49048 +}
49049 +
49050 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
49051 +{
49052 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49053 + t_FmPcdPrsLabelParams *p_Label;
49054 + int i;
49055 +
49056 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
49057 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
49058 +
49059 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49060 + p_FmPcd->h_IpcSession)
49061 + {
49062 + t_Error err = E_OK;
49063 + t_FmPcdIpcSwPrsLable labelParams;
49064 + t_FmPcdIpcMsg msg;
49065 + uint32_t prsOffset = 0;
49066 + t_FmPcdIpcReply reply;
49067 + uint32_t replyLength;
49068 +
49069 + memset(&reply, 0, sizeof(reply));
49070 + memset(&msg, 0, sizeof(msg));
49071 + labelParams.enumHdr = (uint32_t)hdr;
49072 + labelParams.indexPerHdr = indexPerHdr;
49073 + msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
49074 + memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
49075 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
49076 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49077 + (uint8_t*)&msg,
49078 + sizeof(msg.msgId) +sizeof(labelParams),
49079 + (uint8_t*)&reply,
49080 + &replyLength,
49081 + NULL,
49082 + NULL);
49083 + if (err != E_OK)
49084 + RETURN_ERROR(MAJOR, err, NO_MSG);
49085 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
49086 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
49087 +
49088 + memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
49089 + return prsOffset;
49090 + }
49091 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49092 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49093 + ("running in guest-mode without IPC!"));
49094 +
49095 + ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
49096 +
49097 + for (i=0; i<p_FmPcd->p_FmPcdPrs->currLabel; i++)
49098 + {
49099 + p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
49100 +
49101 + if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
49102 + return p_Label->instructionOffset;
49103 + }
49104 +
49105 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
49106 + return (uint32_t)ILLEGAL_BASE;
49107 +}
49108 +
49109 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
49110 +{
49111 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49112 + struct fman_prs_regs *PrsRegs;
49113 +
49114 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
49115 + SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49116 +
49117 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49118 +
49119 +
49120 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
49121 + {
49122 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
49123 + return;
49124 + }
49125 +
49126 + fman_prs_set_stst(PrsRegs, enable);
49127 +}
49128 +
49129 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
49130 +{
49131 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49132 + uint32_t *p_LoadTarget;
49133 + uint32_t *p_TmpCode;
49134 + int i;
49135 +
49136 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49137 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
49138 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
49139 + SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
49140 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
49141 +
49142 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
49143 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!"));
49144 +
49145 + if (!p_SwPrs->override)
49146 + {
49147 + if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
49148 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
49149 + }
49150 + else
49151 + p_FmPcd->p_FmPcdPrs->currLabel = 0;
49152 +
49153 + if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
49154 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
49155 +
49156 + if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
49157 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
49158 +
49159 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t));
49160 + if (!p_TmpCode)
49161 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
49162 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4));
49163 + memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size);
49164 +
49165 + /* save sw parser labels */
49166 + memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel],
49167 + p_SwPrs->labelsTable,
49168 + p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
49169 + p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
49170 +
49171 + /* load sw parser code */
49172 + p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
49173 +
49174 + for(i=0; i<DIV_CEIL(p_SwPrs->size, 4); i++)
49175 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
49176 +
49177 + p_FmPcd->p_FmPcdPrs->p_CurrSwPrs =
49178 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4);
49179 +
49180 + /* copy data parameters */
49181 + for (i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
49182 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
49183 +
49184 + /* Clear last 4 bytes */
49185 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
49186 +
49187 + XX_FreeSmart(p_TmpCode);
49188 +
49189 + return E_OK;
49190 +}
49191 +
49192 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
49193 +{
49194 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49195 +
49196 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49197 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
49198 +
49199 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
49200 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
49201 +
49202 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
49203 +
49204 + return E_OK;
49205 +}
49206 --- /dev/null
49207 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
49208 @@ -0,0 +1,316 @@
49209 +/*
49210 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49211 + *
49212 + * Redistribution and use in source and binary forms, with or without
49213 + * modification, are permitted provided that the following conditions are met:
49214 + * * Redistributions of source code must retain the above copyright
49215 + * notice, this list of conditions and the following disclaimer.
49216 + * * Redistributions in binary form must reproduce the above copyright
49217 + * notice, this list of conditions and the following disclaimer in the
49218 + * documentation and/or other materials provided with the distribution.
49219 + * * Neither the name of Freescale Semiconductor nor the
49220 + * names of its contributors may be used to endorse or promote products
49221 + * derived from this software without specific prior written permission.
49222 + *
49223 + *
49224 + * ALTERNATIVELY, this software may be distributed under the terms of the
49225 + * GNU General Public License ("GPL") as published by the Free Software
49226 + * Foundation, either version 2 of that License or (at your option) any
49227 + * later version.
49228 + *
49229 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49230 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49231 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49232 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49233 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49234 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49235 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49236 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49237 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49238 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49239 + */
49240 +
49241 +
49242 +/******************************************************************************
49243 + @File fm_prs.h
49244 +
49245 + @Description FM Parser private header
49246 + *//***************************************************************************/
49247 +#ifndef __FM_PRS_H
49248 +#define __FM_PRS_H
49249 +
49250 +#include "std_ext.h"
49251 +
49252 +/***********************************************************************/
49253 +/* SW parser IP_FRAG patch */
49254 +/***********************************************************************/
49255 +
49256 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
49257 +#define SW_PRS_UDP_LITE_PATCH \
49258 +{\
49259 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49260 + 0x00,0x00,0x50,0x2C,0x40,0x00,0x31,0x92,0x50,0x2C, \
49261 + 0x00,0x88,0x18,0x2F,0x00,0x01,0x1B,0xFE,0x18,0x71, \
49262 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49263 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x60,0x4F, \
49264 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49265 + 0x00,0x01,0x07,0x01,0x60,0x3B,0x00,0x00,0x30,0xD0, \
49266 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49267 + 0x40,0x4C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49268 + 0x00,0x06,0x18,0x5D,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49269 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49270 + 0x00,0x08,0x28,0x1A,0x60,0x37,0x00,0x00,0x30,0xF2, \
49271 + 0x18,0x5D,0x06,0x00,0x29,0x1E,0x30,0xF2,0x2F,0x0E, \
49272 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x2F,0x0E, \
49273 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49274 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49275 + 0x2F,0x0E,0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80, \
49276 + 0x00,0x02,0x00,0x00,0x97,0x9E,0x40,0x7E,0x00,0x08, \
49277 + 0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE,0x00,0x00, \
49278 + 0x9F,0x9E,0x40,0xB3,0x00,0x00,0x02,0x1F,0x00,0x08, \
49279 + 0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0,0x60,0x9F, \
49280 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49281 + 0x00,0x01,0x07,0x01,0x60,0x8B,0x00,0x00,0x30,0xD0, \
49282 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49283 + 0x40,0x9C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49284 + 0x00,0x06,0x18,0xAD,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49285 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49286 + 0x00,0x08,0x28,0x1A,0x60,0x87,0x00,0x00,0x30,0xF2, \
49287 + 0x18,0xAD,0x06,0x00,0x29,0x1E,0x30,0xF2,0x50,0xB3, \
49288 + 0xFF,0xFF,0x18,0xB8,0x08,0x16,0x00,0x54,0x00,0x01, \
49289 + 0x1B,0xFE,0x18,0xC5,0x32,0xF1,0x28,0x5D,0x32,0xF1, \
49290 + 0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00,0x8F,0x9F, \
49291 + 0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01,0x1B,0xFF, \
49292 + 0x00,0x01,0x1B,0xFF \
49293 +}
49294 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
49295 +
49296 +#if (DPAA_VERSION == 10)
49297 +/* Version: 106.1.9 */
49298 +#define SW_PRS_OFFLOAD_PATCH \
49299 +{ \
49300 + 0x31,0x52,0x00,0xDA,0x0A,0x00,0x00,0x00,0x00,0x00, \
49301 + 0x00,0x00,0x43,0x0A,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49302 + 0x00,0x00,0x99,0x00,0x53,0x13,0x00,0x00,0x00,0x00, \
49303 + 0x9F,0x98,0x53,0x13,0x00,0x00,0x1B,0x23,0x33,0xF1, \
49304 + 0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49305 + 0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x01, \
49306 + 0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80,0x1F,0xFF, \
49307 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x06,0x00, \
49308 + 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x2F,0x00,0x00, \
49309 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x00,0x40, \
49310 + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x00,0x00, \
49311 + 0x00,0x00,0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55, \
49312 + 0x00,0x28,0x28,0x43,0x30,0x7E,0x43,0x45,0x00,0x00, \
49313 + 0x30,0x7E,0x43,0x45,0x00,0x3C,0x1B,0x5D,0x32,0x11, \
49314 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x83,0x8F, \
49315 + 0x2F,0x0F,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49316 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49317 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49318 + 0x28,0x43,0x06,0x00,0x1B,0x3E,0x30,0x7E,0x53,0x79, \
49319 + 0x00,0x2B,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49320 + 0x00,0x00,0x87,0x8F,0x28,0x23,0x06,0x00,0x32,0x11, \
49321 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49322 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49323 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x00,0x01, \
49324 + 0x1B,0xFE,0x00,0x00,0x9B,0x8E,0x53,0x90,0x00,0x00, \
49325 + 0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23,0x06,0x00, \
49326 + 0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28,0x00,0x00, \
49327 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49328 + 0x28,0x43,0x06,0x00,0x00,0x01,0x1B,0xFE,0x32,0xC1, \
49329 + 0x00,0x55,0x00,0x28,0x28,0x43,0x1B,0xCF,0x00,0x00, \
49330 + 0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55,0x00,0x28, \
49331 + 0x28,0x43,0x30,0x7E,0x43,0xBF,0x00,0x2C,0x32,0x11, \
49332 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49333 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49334 + 0x00,0x81,0x00,0x00,0x83,0x8F,0x2F,0x0F,0x06,0x00, \
49335 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01, \
49336 + 0x00,0x81,0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50, \
49337 + 0x00,0x01,0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00, \
49338 + 0x1B,0x9C,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49339 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49340 + 0x00,0x00,0x00,0x01,0x32,0xC1,0x32,0xF0,0x00,0x4A, \
49341 + 0x00,0x80,0x1F,0xFF,0x00,0x01,0x1B,0xFE, \
49342 +}
49343 +
49344 +#else
49345 +#define SW_PRS_OFFLOAD_PATCH \
49346 +{ \
49347 + 0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00,0x00,0x00, \
49348 + 0x00,0x00,0x51,0x16,0x08,0x4B,0x31,0x53,0x00,0xFB, \
49349 + 0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x2B, \
49350 + 0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00,0x00,0x00, \
49351 + 0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA,0x0A,0x00, \
49352 + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x20,0x00,0x00, \
49353 + 0x00,0x01,0x1B,0xFE,0x00,0x00,0x99,0x00,0x51,0x29, \
49354 + 0x00,0x00,0x00,0x00,0x9F,0x98,0x51,0x29,0x00,0x00, \
49355 + 0x19,0x44,0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F, \
49356 + 0x00,0x20,0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00, \
49357 + 0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3, \
49358 + 0x29,0x8F,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49359 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49360 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x00,0x01,0x1B,0xFE, \
49361 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49362 + 0x00,0x00,0x51,0x52,0x40,0x00,0x31,0x92,0x51,0x52, \
49363 + 0x00,0x88,0x19,0x55,0x08,0x05,0x00,0x00,0x19,0x99, \
49364 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49365 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x61,0x75, \
49366 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49367 + 0x00,0x01,0x07,0x01,0x61,0x61,0x00,0x00,0x30,0xD0, \
49368 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49369 + 0x41,0x72,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49370 + 0x00,0x06,0x19,0x83,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49371 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49372 + 0x00,0x08,0x28,0x1A,0x61,0x5D,0x00,0x00,0x30,0xF2, \
49373 + 0x19,0x83,0x06,0x00,0x29,0x1E,0x30,0xF2,0x29,0x0E, \
49374 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x29,0x0E, \
49375 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49376 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49377 + 0x29,0x0E,0x08,0x05,0x00,0x01,0x31,0x52,0x00,0xDA, \
49378 + 0x0E,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0xAF, \
49379 + 0x04,0x4B,0x31,0x53,0x00,0xFB,0xFF,0xF0,0x00,0x00, \
49380 + 0x00,0x00,0x00,0x00,0x29,0x2B,0x33,0xF1,0x00,0xFB, \
49381 + 0x00,0xDF,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7F, \
49382 + 0x31,0x52,0x00,0xDA,0x06,0x00,0x00,0x00,0x00,0x00, \
49383 + 0x00,0x00,0x41,0xB9,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49384 + 0x31,0x52,0x00,0xDA,0x00,0x40,0x00,0x00,0x00,0x00, \
49385 + 0x00,0x00,0x42,0x06,0x00,0x00,0x00,0x00,0x9B,0x8F, \
49386 + 0x28,0x01,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49387 + 0x30,0x00,0x41,0xEB,0x00,0x2C,0x32,0x11,0x32,0xC0, \
49388 + 0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F,0x28,0x23, \
49389 + 0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49390 + 0x00,0x00,0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11, \
49391 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49392 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49393 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x19,0xC8, \
49394 + 0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F,0x00,0x20, \
49395 + 0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00,0x01,0x00, \
49396 + 0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3,0x29,0x8F, \
49397 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49398 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49399 + 0x00,0x01,0x1B,0xFE,0x30,0x50,0x52,0x0B,0x00,0x00, \
49400 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49401 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x42,0x18, \
49402 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49403 + 0x00,0x00,0x9F,0x9E,0x42,0x4D,0x00,0x00,0x02,0x1F, \
49404 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49405 + 0x62,0x39,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49406 + 0x00,0x52,0x00,0x01,0x07,0x01,0x62,0x25,0x00,0x00, \
49407 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49408 + 0x00,0x00,0x42,0x36,0x00,0x00,0x02,0x8F,0x00,0x00, \
49409 + 0x30,0xF2,0x00,0x06,0x1A,0x47,0x00,0x00,0x9F,0xFF, \
49410 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49411 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x62,0x21,0x00,0x00, \
49412 + 0x30,0xF2,0x1A,0x47,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49413 + 0x52,0x4D,0xFF,0xFF,0x1A,0x52,0x08,0x16,0x00,0x54, \
49414 + 0x00,0x01,0x1B,0xFE,0x1A,0x5F,0x32,0xF1,0x28,0x5D, \
49415 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
49416 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
49417 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x31,0x52,0x00,0xDA, \
49418 + 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x6D, \
49419 + 0x40,0x00,0x31,0x92,0x52,0x6D,0x00,0x88,0x1A,0x70, \
49420 + 0x08,0x05,0x00,0x00,0x1A,0xB4,0x02,0x1F,0x00,0x08, \
49421 + 0x00,0x83,0x02,0x1F,0x00,0x20,0x28,0x1B,0x00,0x05, \
49422 + 0x29,0x1F,0x30,0xD0,0x62,0x90,0x00,0x07,0x00,0x05, \
49423 + 0x00,0x00,0xC3,0x8F,0x00,0x52,0x00,0x01,0x07,0x01, \
49424 + 0x62,0x7C,0x00,0x00,0x30,0xD0,0x00,0xDA,0x00,0x01, \
49425 + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x8D,0x00,0x00, \
49426 + 0x02,0x8F,0x00,0x00,0x30,0xF2,0x00,0x06,0x1A,0x9E, \
49427 + 0x00,0x00,0x9F,0xFF,0x30,0xF2,0x00,0x06,0x29,0x1E, \
49428 + 0x07,0x08,0x30,0xD0,0x00,0x52,0x00,0x08,0x28,0x1A, \
49429 + 0x62,0x78,0x00,0x00,0x30,0xF2,0x1A,0x9E,0x06,0x00, \
49430 + 0x29,0x1E,0x30,0xF2,0x29,0x0E,0x30,0x72,0x00,0x00, \
49431 + 0x9B,0x8F,0x00,0x06,0x29,0x0E,0x32,0xF1,0x32,0xB0, \
49432 + 0x00,0x4F,0x00,0x57,0x00,0x28,0x00,0x00,0x97,0x9E, \
49433 + 0x00,0x4E,0x30,0x72,0x00,0x06,0x29,0x0E,0x08,0x05, \
49434 + 0x00,0x01,0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00, \
49435 + 0x00,0x00,0x00,0x00,0x52,0xCA,0x04,0x4B,0x31,0x53, \
49436 + 0x00,0xFB,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, \
49437 + 0x29,0x2B,0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00, \
49438 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA, \
49439 + 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xD4, \
49440 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA, \
49441 + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x37, \
49442 + 0x00,0x00,0x00,0x00,0x9B,0x8F,0x28,0x01,0x32,0xC1, \
49443 + 0x00,0x55,0x00,0x28,0x28,0x43,0x30,0x00,0x42,0xEA, \
49444 + 0x00,0x00,0x30,0x00,0x42,0xEA,0x00,0x3C,0x1B,0x02, \
49445 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00, \
49446 + 0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11,0x32,0xC0, \
49447 + 0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11, \
49448 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49449 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1A,0xE3,0x30,0x00, \
49450 + 0x43,0x20,0x00,0x2B,0x00,0x00,0x9B,0x8E,0x43,0x0E, \
49451 + 0x00,0x00,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49452 + 0x1B,0x1F,0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23, \
49453 + 0x06,0x00,0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28, \
49454 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49455 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1B,0x37,0x32,0x11, \
49456 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49457 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49458 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49459 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49460 + 0x28,0x43,0x06,0x00,0x30,0x50,0x53,0x3C,0x00,0x00, \
49461 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49462 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x43,0x49, \
49463 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49464 + 0x00,0x00,0x9F,0x9E,0x43,0x7E,0x00,0x00,0x02,0x1F, \
49465 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49466 + 0x63,0x6A,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49467 + 0x00,0x52,0x00,0x01,0x07,0x01,0x63,0x56,0x00,0x00, \
49468 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49469 + 0x00,0x00,0x43,0x67,0x00,0x00,0x02,0x8F,0x00,0x00, \
49470 + 0x30,0xF2,0x00,0x06,0x1B,0x78,0x00,0x00,0x9F,0xFF, \
49471 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49472 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x63,0x52,0x00,0x00, \
49473 + 0x30,0xF2,0x1B,0x78,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49474 + 0x53,0x7E,0xFF,0xFF,0x1B,0x83,0x08,0x16,0x00,0x54, \
49475 + 0x00,0x01,0x1B,0xFE,0x1B,0x90,0x32,0xF1,0x28,0x5D, \
49476 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
49477 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
49478 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x08,0x07,0x00,0x02, \
49479 + 0x00,0x00,0x8D,0x80,0x53,0x9C,0x00,0x01,0x30,0x71, \
49480 + 0x00,0x55,0x00,0x01,0x28,0x0F,0x00,0x00,0x8D,0x00, \
49481 + 0x53,0xA4,0x00,0x01,0x30,0x71,0x00,0x55,0x00,0x01, \
49482 + 0x28,0x0F,0x00,0x00,0x83,0x8E,0x53,0xB9,0x00,0x00, \
49483 + 0x00,0x00,0x86,0x08,0x30,0x71,0x00,0x7B,0x03,0xB9, \
49484 + 0x33,0xB4,0x00,0xDA,0xFF,0xFF,0x00,0x0F,0x00,0x00, \
49485 + 0x00,0x00,0x00,0x00,0x86,0x09,0x01,0x03,0x00,0x7D, \
49486 + 0x03,0xB9,0x1B,0xC8,0x33,0xD1,0x00,0xF9,0x00,0x10, \
49487 + 0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7B,0x09,0x5F, \
49488 + 0x00,0x1A,0x00,0x00,0x09,0x4F,0x00,0x1A,0x00,0x00, \
49489 + 0x00,0x01,0x1B,0xFF,0x00,0x00,0x8C,0x00,0x53,0xF0, \
49490 + 0x00,0x01,0x34,0xF5,0x00,0xFB,0xFF,0xFF,0x00,0x7F, \
49491 + 0x00,0x00,0x00,0x00,0x2A,0x9F,0x00,0x00,0x93,0x8F, \
49492 + 0x28,0x49,0x00,0x00,0x97,0x8F,0x28,0x4B,0x34,0x61, \
49493 + 0x28,0x4D,0x34,0x71,0x28,0x4F,0x34,0xB7,0x00,0xF9, \
49494 + 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97, \
49495 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49496 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49497 + 0x00,0x01,0x1B,0xFF,0x00,0x01,0x1B,0xFF, \
49498 +}
49499 +#endif /* (DPAA_VERSION == 10) */
49500 +
49501 +/****************************/
49502 +/* Parser defines */
49503 +/****************************/
49504 +#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at
49505 + the end of the SW parser area */
49506 +
49507 +/* masks */
49508 +#define PRS_ERR_CAP 0x80000000
49509 +#define PRS_ERR_TYPE_DOUBLE 0x40000000
49510 +#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000
49511 +#define PRS_ERR_ADDR_MASK 0x000001FF
49512 +
49513 +/* others */
49514 +#define PRS_MAX_CYCLE_LIMIT 8191
49515 +#define PRS_SW_DATA 0x00000800
49516 +#define PRS_REGS_OFFSET 0x00000840
49517 +
49518 +#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \
49519 + prsPortId = (uint8_t)(hardwarePortId & 0x0f)
49520 +
49521 +#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \
49522 + bitMask = 0x80000000>>prsPortId
49523 +
49524 +#endif /* __FM_PRS_H */
49525 --- /dev/null
49526 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
49527 @@ -0,0 +1,984 @@
49528 +/*
49529 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49530 + *
49531 + * Redistribution and use in source and binary forms, with or without
49532 + * modification, are permitted provided that the following conditions are met:
49533 + * * Redistributions of source code must retain the above copyright
49534 + * notice, this list of conditions and the following disclaimer.
49535 + * * Redistributions in binary form must reproduce the above copyright
49536 + * notice, this list of conditions and the following disclaimer in the
49537 + * documentation and/or other materials provided with the distribution.
49538 + * * Neither the name of Freescale Semiconductor nor the
49539 + * names of its contributors may be used to endorse or promote products
49540 + * derived from this software without specific prior written permission.
49541 + *
49542 + *
49543 + * ALTERNATIVELY, this software may be distributed under the terms of the
49544 + * GNU General Public License ("GPL") as published by the Free Software
49545 + * Foundation, either version 2 of that License or (at your option) any
49546 + * later version.
49547 + *
49548 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49549 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49550 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49551 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49552 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49553 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49554 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49555 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49556 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49557 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49558 + */
49559 +
49560 +
49561 +/******************************************************************************
49562 + @File fm_replic.c
49563 +
49564 + @Description FM frame replicator
49565 +*//***************************************************************************/
49566 +#include "std_ext.h"
49567 +#include "error_ext.h"
49568 +#include "string_ext.h"
49569 +#include "debug_ext.h"
49570 +#include "fm_pcd_ext.h"
49571 +#include "fm_muram_ext.h"
49572 +#include "fm_common.h"
49573 +#include "fm_hc.h"
49574 +#include "fm_replic.h"
49575 +#include "fm_cc.h"
49576 +#include "list_ext.h"
49577 +
49578 +
49579 +/****************************************/
49580 +/* static functions */
49581 +/****************************************/
49582 +static uint8_t GetMemberPosition(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49583 + uint32_t memberIndex,
49584 + bool isAddOperation)
49585 +{
49586 + uint8_t memberPosition;
49587 + uint32_t lastMemberIndex;
49588 +
49589 + ASSERT_COND(p_ReplicGroup);
49590 +
49591 + /* the last member index is different between add and remove operation -
49592 + in case of remove - this is exactly the last member index
49593 + in case of add - this is the last member index + 1 - e.g.
49594 + if we have 4 members, the index of the actual last member is 3(because the
49595 + index starts from 0) therefore in order to add a new member as the last
49596 + member we shall use memberIndex = 4 and not 3
49597 + */
49598 + if (isAddOperation)
49599 + lastMemberIndex = p_ReplicGroup->numOfEntries;
49600 + else
49601 + lastMemberIndex = p_ReplicGroup->numOfEntries-1;
49602 +
49603 + /* last */
49604 + if (memberIndex == lastMemberIndex)
49605 + memberPosition = FRM_REPLIC_LAST_MEMBER_INDEX;
49606 + else
49607 + {
49608 + /* first */
49609 + if (memberIndex == 0)
49610 + memberPosition = FRM_REPLIC_FIRST_MEMBER_INDEX;
49611 + else
49612 + {
49613 + /* middle */
49614 + ASSERT_COND(memberIndex < lastMemberIndex);
49615 + memberPosition = FRM_REPLIC_MIDDLE_MEMBER_INDEX;
49616 + }
49617 + }
49618 + return memberPosition;
49619 +}
49620 +
49621 +static t_Error MemberCheckParams(t_Handle h_FmPcd,
49622 + t_FmPcdCcNextEngineParams *p_MemberParams)
49623 +{
49624 + t_Error err;
49625 +
49626 +
49627 + if ((p_MemberParams->nextEngine != e_FM_PCD_DONE) &&
49628 + (p_MemberParams->nextEngine != e_FM_PCD_KG) &&
49629 + (p_MemberParams->nextEngine != e_FM_PCD_PLCR))
49630 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine of a member should be MatchTable(cc) or Done or Policer"));
49631 +
49632 + /* check the regular parameters of the next engine */
49633 + err = ValidateNextEngineParams(h_FmPcd, p_MemberParams, e_FM_PCD_CC_STATS_MODE_NONE);
49634 + if (err)
49635 + RETURN_ERROR(MAJOR, err, ("member next engine parameters"));
49636 +
49637 + return E_OK;
49638 +}
49639 +
49640 +static t_Error CheckParams(t_Handle h_FmPcd,
49641 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
49642 +{
49643 + int i;
49644 + t_Error err;
49645 +
49646 + /* check that max num of entries is at least 2 */
49647 + if (!IN_RANGE(2, p_ReplicGroupParam->maxNumOfEntries, FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES))
49648 + 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));
49649 +
49650 + /* check that number of entries is greater than zero */
49651 + if (!p_ReplicGroupParam->numOfEntries)
49652 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOFEntries in the frame replicator group should be greater than zero"));
49653 +
49654 + /* check that max num of entries is equal or greater than number of entries */
49655 + if (p_ReplicGroupParam->maxNumOfEntries < p_ReplicGroupParam->numOfEntries)
49656 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfEntries should be equal or greater than numOfEntries"));
49657 +
49658 + for (i=0; i<p_ReplicGroupParam->numOfEntries; i++)
49659 + {
49660 + err = MemberCheckParams(h_FmPcd, &p_ReplicGroupParam->nextEngineParams[i]);
49661 + if (err)
49662 + RETURN_ERROR(MAJOR, err, ("member check parameters"));
49663 + }
49664 + return E_OK;
49665 +}
49666 +
49667 +static t_FmPcdFrmReplicMember *GetAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
49668 +{
49669 + t_FmPcdFrmReplicMember *p_ReplicMember = NULL;
49670 + t_List *p_Next;
49671 +
49672 + if (!LIST_IsEmpty(&p_ReplicGroup->availableMembersList))
49673 + {
49674 + p_Next = LIST_FIRST(&p_ReplicGroup->availableMembersList);
49675 + p_ReplicMember = LIST_OBJECT(p_Next, t_FmPcdFrmReplicMember, node);
49676 + ASSERT_COND(p_ReplicMember);
49677 + LIST_DelAndInit(p_Next);
49678 + }
49679 + return p_ReplicMember;
49680 +}
49681 +
49682 +static void PutAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49683 + t_FmPcdFrmReplicMember *p_ReplicMember)
49684 +{
49685 + LIST_AddToTail(&p_ReplicMember->node, &p_ReplicGroup->availableMembersList);
49686 +}
49687 +
49688 +static void AddMemberToList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49689 + t_FmPcdFrmReplicMember *p_CurrentMember,
49690 + t_List *p_ListHead)
49691 +{
49692 + LIST_Add(&p_CurrentMember->node, p_ListHead);
49693 +
49694 + p_ReplicGroup->numOfEntries++;
49695 +}
49696 +
49697 +static void RemoveMemberFromList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49698 + t_FmPcdFrmReplicMember *p_CurrentMember)
49699 +{
49700 + ASSERT_COND(p_ReplicGroup->numOfEntries);
49701 + LIST_DelAndInit(&p_CurrentMember->node);
49702 + p_ReplicGroup->numOfEntries--;
49703 +}
49704 +
49705 +static void LinkSourceToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49706 + t_AdOfTypeContLookup *p_SourceTd,
49707 + t_FmPcdFrmReplicMember *p_ReplicMember)
49708 +{
49709 + t_FmPcd *p_FmPcd;
49710 +
49711 + ASSERT_COND(p_SourceTd);
49712 + ASSERT_COND(p_ReplicMember);
49713 + ASSERT_COND(p_ReplicGroup);
49714 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49715 +
49716 + /* Link the first member in the group to the source TD */
49717 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49718 +
49719 + WRITE_UINT32(p_SourceTd->matchTblPtr,
49720 + (uint32_t)(XX_VirtToPhys(p_ReplicMember->p_MemberAd) -
49721 + p_FmPcd->physicalMuramBase));
49722 +}
49723 +
49724 +static void LinkMemberToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49725 + t_FmPcdFrmReplicMember *p_CurrentMember,
49726 + t_FmPcdFrmReplicMember *p_NextMember)
49727 +{
49728 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_CurrentMember->p_MemberAd;
49729 + t_AdOfTypeResult *p_NextReplicAd = NULL;
49730 + t_FmPcd *p_FmPcd;
49731 + uint32_t offset = 0;
49732 +
49733 + /* Check if the next member exists or it's NULL (- means that this is the last member) */
49734 + if (p_NextMember)
49735 + {
49736 + p_NextReplicAd = (t_AdOfTypeResult*)p_NextMember->p_MemberAd;
49737 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49738 + offset = (XX_VirtToPhys(p_NextReplicAd) - (p_FmPcd->physicalMuramBase));
49739 + offset = ((offset>>NEXT_FRM_REPLIC_ADDR_SHIFT)<< NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT);
49740 + }
49741 +
49742 + /* link the current AD to point to the AD of the next member */
49743 + WRITE_UINT32(p_CurrReplicAd->res, offset);
49744 +}
49745 +
49746 +static t_Error ModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49747 + void *p_OldDescriptor,
49748 + void *p_NewDescriptor)
49749 +{
49750 + t_Handle h_Hc;
49751 + t_Error err;
49752 + t_FmPcd *p_FmPcd;
49753 +
49754 + ASSERT_COND(p_ReplicGroup);
49755 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49756 + ASSERT_COND(p_OldDescriptor);
49757 + ASSERT_COND(p_NewDescriptor);
49758 +
49759 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49760 + h_Hc = FmPcdGetHcHandle(p_FmPcd);
49761 + if (!h_Hc)
49762 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Host command"));
49763 +
49764 + err = FmHcPcdCcDoDynamicChange(h_Hc,
49765 + (uint32_t)(XX_VirtToPhys(p_OldDescriptor) - p_FmPcd->physicalMuramBase),
49766 + (uint32_t)(XX_VirtToPhys(p_NewDescriptor) - p_FmPcd->physicalMuramBase));
49767 + if (err)
49768 + RETURN_ERROR(MAJOR, err, ("Dynamic change host command"));
49769 +
49770 + return E_OK;
49771 +}
49772 +
49773 +static void FillReplicAdOfTypeResult(void *p_ReplicAd, bool last)
49774 +{
49775 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_ReplicAd;
49776 + uint32_t tmp;
49777 +
49778 + tmp = GET_UINT32(p_CurrReplicAd->plcrProfile);
49779 + if (last)
49780 + /* clear the NL bit in case it's the last member in the group*/
49781 + WRITE_UINT32(p_CurrReplicAd->plcrProfile,(tmp & ~FRM_REPLIC_NL_BIT));
49782 + else
49783 + /* set the NL bit in case it's not the last member in the group */
49784 + WRITE_UINT32(p_CurrReplicAd->plcrProfile, (tmp |FRM_REPLIC_NL_BIT));
49785 +
49786 + /* set FR bit in the action descriptor */
49787 + tmp = GET_UINT32(p_CurrReplicAd->nia);
49788 + WRITE_UINT32(p_CurrReplicAd->nia,
49789 + (tmp | FRM_REPLIC_FR_BIT | FM_PCD_AD_RESULT_EXTENDED_MODE ));
49790 +}
49791 +
49792 +static void BuildSourceTd(void *p_Ad)
49793 +{
49794 + t_AdOfTypeContLookup *p_SourceTd;
49795 +
49796 + ASSERT_COND(p_Ad);
49797 +
49798 + p_SourceTd = (t_AdOfTypeContLookup *)p_Ad;
49799 +
49800 + IOMemSet32((uint8_t*)p_SourceTd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49801 +
49802 + /* initialize the source table descriptor */
49803 + WRITE_UINT32(p_SourceTd->ccAdBase, FM_PCD_AD_CONT_LOOKUP_TYPE);
49804 + WRITE_UINT32(p_SourceTd->pcAndOffsets, FRM_REPLIC_SOURCE_TD_OPCODE);
49805 +}
49806 +
49807 +static t_Error BuildShadowAndModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49808 + t_FmPcdFrmReplicMember *p_NextMember,
49809 + t_FmPcdFrmReplicMember *p_CurrentMember,
49810 + bool sourceDescriptor,
49811 + bool last)
49812 +{
49813 + t_FmPcd *p_FmPcd;
49814 + t_FmPcdFrmReplicMember shadowMember;
49815 + t_Error err;
49816 +
49817 + ASSERT_COND(p_ReplicGroup);
49818 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49819 +
49820 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49821 + ASSERT_COND(p_FmPcd->p_CcShadow);
49822 +
49823 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
49824 + return ERROR_CODE(E_BUSY);
49825 +
49826 + if (sourceDescriptor)
49827 + {
49828 + BuildSourceTd(p_FmPcd->p_CcShadow);
49829 + LinkSourceToMember(p_ReplicGroup, p_FmPcd->p_CcShadow, p_NextMember);
49830 +
49831 + /* Modify the source table descriptor according to the prepared shadow descriptor */
49832 + err = ModifyDescriptor(p_ReplicGroup,
49833 + p_ReplicGroup->p_SourceTd,
49834 + p_FmPcd->p_CcShadow/* new prepared source td */);
49835 +
49836 + RELEASE_LOCK(p_FmPcd->shadowLock);
49837 + if (err)
49838 + RETURN_ERROR(MAJOR, err, ("Modify source Descriptor in BuildShadowAndModifyDescriptor"));
49839 +
49840 + }
49841 + else
49842 + {
49843 + IO2IOCpy32(p_FmPcd->p_CcShadow,
49844 + p_CurrentMember->p_MemberAd,
49845 + FM_PCD_CC_AD_ENTRY_SIZE);
49846 +
49847 + /* update the last bit in the shadow ad */
49848 + FillReplicAdOfTypeResult(p_FmPcd->p_CcShadow, last);
49849 +
49850 + shadowMember.p_MemberAd = p_FmPcd->p_CcShadow;
49851 +
49852 + /* update the next FR member index */
49853 + LinkMemberToMember(p_ReplicGroup, &shadowMember, p_NextMember);
49854 +
49855 + /* Modify the next member according to the prepared shadow descriptor */
49856 + err = ModifyDescriptor(p_ReplicGroup,
49857 + p_CurrentMember->p_MemberAd,
49858 + p_FmPcd->p_CcShadow);
49859 +
49860 + RELEASE_LOCK(p_FmPcd->shadowLock);
49861 + if (err)
49862 + RETURN_ERROR(MAJOR, err, ("Modify Descriptor in BuildShadowAndModifyDescriptor"));
49863 + }
49864 +
49865 +
49866 + return E_OK;
49867 +}
49868 +
49869 +static t_FmPcdFrmReplicMember* GetMemberByIndex(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49870 + uint16_t memberIndex)
49871 +{
49872 + int i=0;
49873 + t_List *p_Pos;
49874 + t_FmPcdFrmReplicMember *p_Member = NULL;
49875 +
49876 + LIST_FOR_EACH(p_Pos, &p_ReplicGroup->membersList)
49877 + {
49878 + if (i == memberIndex)
49879 + {
49880 + p_Member = LIST_OBJECT(p_Pos, t_FmPcdFrmReplicMember, node);
49881 + return p_Member;
49882 + }
49883 + i++;
49884 + }
49885 + return p_Member;
49886 +}
49887 +
49888 +static t_Error AllocMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
49889 +{
49890 + t_FmPcdFrmReplicMember *p_CurrentMember;
49891 + t_Handle h_Muram;
49892 +
49893 + ASSERT_COND(p_ReplicGroup);
49894 +
49895 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
49896 + ASSERT_COND(h_Muram);
49897 +
49898 + /* Initialize an internal structure of a member to add to the available members list */
49899 + p_CurrentMember = (t_FmPcdFrmReplicMember *)XX_Malloc(sizeof(t_FmPcdFrmReplicMember));
49900 + if (!p_CurrentMember)
49901 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Frame replicator member"));
49902 +
49903 + memset(p_CurrentMember, 0 ,sizeof(t_FmPcdFrmReplicMember));
49904 +
49905 + /* Allocate the member AD */
49906 + p_CurrentMember->p_MemberAd =
49907 + (t_AdOfTypeResult*)FM_MURAM_AllocMem(h_Muram,
49908 + FM_PCD_CC_AD_ENTRY_SIZE,
49909 + FM_PCD_CC_AD_TABLE_ALIGN);
49910 + if (!p_CurrentMember->p_MemberAd)
49911 + {
49912 + XX_Free(p_CurrentMember);
49913 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("member AD table"));
49914 + }
49915 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49916 +
49917 + /* Add the new member to the available members list */
49918 + LIST_AddToTail(&p_CurrentMember->node, &(p_ReplicGroup->availableMembersList));
49919 +
49920 + return E_OK;
49921 +}
49922 +
49923 +static t_FmPcdFrmReplicMember* InitMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49924 + t_FmPcdCcNextEngineParams *p_MemberParams,
49925 + bool last)
49926 +{
49927 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL;
49928 +
49929 + ASSERT_COND(p_ReplicGroup);
49930 +
49931 + /* Get an available member from the internal members list */
49932 + p_CurrentMember = GetAvailableMember(p_ReplicGroup);
49933 + if (!p_CurrentMember)
49934 + {
49935 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Available member"));
49936 + return NULL;
49937 + }
49938 + p_CurrentMember->h_Manip = NULL;
49939 +
49940 + /* clear the Ad of the new member */
49941 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49942 +
49943 + INIT_LIST(&p_CurrentMember->node);
49944 +
49945 + /* Initialize the Ad of the member */
49946 + NextStepAd(p_CurrentMember->p_MemberAd,
49947 + NULL,
49948 + p_MemberParams,
49949 + p_ReplicGroup->h_FmPcd);
49950 +
49951 + /* save Manip handle (for free needs) */
49952 + if (p_MemberParams->h_Manip)
49953 + p_CurrentMember->h_Manip = p_MemberParams->h_Manip;
49954 +
49955 + /* Initialize the relevant frame replicator fields in the AD */
49956 + FillReplicAdOfTypeResult(p_CurrentMember->p_MemberAd, last);
49957 +
49958 + return p_CurrentMember;
49959 +}
49960 +
49961 +static void FreeMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49962 + t_FmPcdFrmReplicMember *p_Member)
49963 +{
49964 + /* Note: Can't free the member AD just returns the member to the available
49965 + member list - therefore only memset the AD */
49966 +
49967 + /* zero the AD */
49968 + IOMemSet32(p_Member->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49969 +
49970 +
49971 + /* return the member to the available members list */
49972 + PutAvailableMember(p_ReplicGroup, p_Member);
49973 +}
49974 +
49975 +static t_Error RemoveMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49976 + uint16_t memberIndex)
49977 +{
49978 + t_FmPcd *p_FmPcd = NULL;
49979 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL, *p_PreviousMember = NULL, *p_NextMember = NULL;
49980 + t_Error err;
49981 + uint8_t memberPosition;
49982 +
49983 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49984 + ASSERT_COND(p_FmPcd);
49985 + UNUSED(p_FmPcd);
49986 +
49987 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
49988 + ASSERT_COND(p_CurrentMember);
49989 +
49990 + /* determine the member position in the group */
49991 + memberPosition = GetMemberPosition(p_ReplicGroup,
49992 + memberIndex,
49993 + FALSE/*remove operation*/);
49994 +
49995 + switch (memberPosition)
49996 + {
49997 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
49998 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
49999 + ASSERT_COND(p_NextMember);
50000 +
50001 + /* update the source td itself by using a host command */
50002 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50003 + p_NextMember,
50004 + NULL,
50005 + TRUE/*sourceDescriptor*/,
50006 + FALSE/*last*/);
50007 + break;
50008 +
50009 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
50010 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50011 + ASSERT_COND(p_PreviousMember);
50012 +
50013 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
50014 + ASSERT_COND(p_NextMember);
50015 +
50016 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50017 + p_NextMember,
50018 + p_PreviousMember,
50019 + FALSE/*sourceDescriptor*/,
50020 + FALSE/*last*/);
50021 +
50022 + break;
50023 +
50024 + case FRM_REPLIC_LAST_MEMBER_INDEX:
50025 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50026 + ASSERT_COND(p_PreviousMember);
50027 +
50028 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50029 + NULL,
50030 + p_PreviousMember,
50031 + FALSE/*sourceDescriptor*/,
50032 + TRUE/*last*/);
50033 + break;
50034 +
50035 + default:
50036 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in remove member"));
50037 + }
50038 +
50039 + if (err)
50040 + RETURN_ERROR(MAJOR, err, NO_MSG);
50041 +
50042 + if (p_CurrentMember->h_Manip)
50043 + {
50044 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
50045 + p_CurrentMember->h_Manip = NULL;
50046 + }
50047 +
50048 + /* remove the member from the driver internal members list */
50049 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
50050 +
50051 + /* return the member to the available members list */
50052 + FreeMember(p_ReplicGroup, p_CurrentMember);
50053 +
50054 + return E_OK;
50055 +}
50056 +
50057 +static void DeleteGroup(t_FmPcdFrmReplicGroup *p_ReplicGroup)
50058 +{
50059 + int i, j;
50060 + t_Handle h_Muram;
50061 + t_FmPcdFrmReplicMember *p_Member, *p_CurrentMember;
50062 +
50063 + if (p_ReplicGroup)
50064 + {
50065 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
50066 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50067 + ASSERT_COND(h_Muram);
50068 +
50069 + /* free the source table descriptor */
50070 + if (p_ReplicGroup->p_SourceTd)
50071 + {
50072 + FM_MURAM_FreeMem(h_Muram, p_ReplicGroup->p_SourceTd);
50073 + p_ReplicGroup->p_SourceTd = NULL;
50074 + }
50075 +
50076 + /* Remove all members from the members linked list (hw and sw) and
50077 + return the members to the available members list */
50078 + if (p_ReplicGroup->numOfEntries)
50079 + {
50080 + j = p_ReplicGroup->numOfEntries-1;
50081 +
50082 + /* manually removal of the member because there are no owners of
50083 + this group */
50084 + for (i=j; i>=0; i--)
50085 + {
50086 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)i/*memberIndex*/);
50087 + ASSERT_COND(p_CurrentMember);
50088 +
50089 + if (p_CurrentMember->h_Manip)
50090 + {
50091 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
50092 + p_CurrentMember->h_Manip = NULL;
50093 + }
50094 +
50095 + /* remove the member from the internal driver members list */
50096 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
50097 +
50098 + /* return the member to the available members list */
50099 + FreeMember(p_ReplicGroup, p_CurrentMember);
50100 + }
50101 + }
50102 +
50103 + /* Free members AD */
50104 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
50105 + {
50106 + p_Member = GetAvailableMember(p_ReplicGroup);
50107 + ASSERT_COND(p_Member);
50108 + if (p_Member->p_MemberAd)
50109 + {
50110 + FM_MURAM_FreeMem(h_Muram, p_Member->p_MemberAd);
50111 + p_Member->p_MemberAd = NULL;
50112 + }
50113 + XX_Free(p_Member);
50114 + }
50115 +
50116 + /* release the group lock */
50117 + if (p_ReplicGroup->p_Lock)
50118 + FmPcdReleaseLock(p_ReplicGroup->h_FmPcd, p_ReplicGroup->p_Lock);
50119 +
50120 + /* free the replicator group */
50121 + XX_Free(p_ReplicGroup);
50122 + }
50123 +}
50124 +
50125 +
50126 +/*****************************************************************************/
50127 +/* Inter-module API routines */
50128 +/*****************************************************************************/
50129 +
50130 +/* NOTE: the inter-module routines are locked by cc in case of using them */
50131 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup)
50132 +{
50133 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50134 + ASSERT_COND(p_ReplicGroup);
50135 +
50136 + return (p_ReplicGroup->p_SourceTd);
50137 +}
50138 +
50139 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup,
50140 + void *p_Ad,
50141 + t_Handle *h_AdNew)
50142 +{
50143 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50144 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad;
50145 + t_FmPcd *p_FmPcd;
50146 +
50147 + ASSERT_COND(p_ReplicGroup);
50148 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50149 +
50150 + /* build a bypass ad */
50151 + WRITE_UINT32(p_AdResult->fqid, FM_PCD_AD_BYPASS_TYPE |
50152 + (uint32_t)((XX_VirtToPhys(p_ReplicGroup->p_SourceTd)) - p_FmPcd->physicalMuramBase));
50153 +
50154 + *h_AdNew = NULL;
50155 +}
50156 +
50157 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup,
50158 + bool add)
50159 +{
50160 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50161 + ASSERT_COND(p_ReplicGroup);
50162 +
50163 + /* update the group owner counter */
50164 + if (add)
50165 + p_ReplicGroup->owners++;
50166 + else
50167 + {
50168 + ASSERT_COND(p_ReplicGroup->owners);
50169 + p_ReplicGroup->owners--;
50170 + }
50171 +}
50172 +
50173 +t_Error FrmReplicGroupTryLock(t_Handle h_ReplicGroup)
50174 +{
50175 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50176 +
50177 + ASSERT_COND(h_ReplicGroup);
50178 +
50179 + if (FmPcdLockTryLock(p_ReplicGroup->p_Lock))
50180 + return E_OK;
50181 +
50182 + return ERROR_CODE(E_BUSY);
50183 +}
50184 +
50185 +void FrmReplicGroupUnlock(t_Handle h_ReplicGroup)
50186 +{
50187 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50188 +
50189 + ASSERT_COND(h_ReplicGroup);
50190 +
50191 + FmPcdLockUnlock(p_ReplicGroup->p_Lock);
50192 +}
50193 +/*********************** End of inter-module routines ************************/
50194 +
50195 +
50196 +/****************************************/
50197 +/* API Init unit functions */
50198 +/****************************************/
50199 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd,
50200 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
50201 +{
50202 + t_FmPcdFrmReplicGroup *p_ReplicGroup;
50203 + t_FmPcdFrmReplicMember *p_CurrentMember, *p_NextMember = NULL;
50204 + int i;
50205 + t_Error err;
50206 + bool last = FALSE;
50207 + t_Handle h_Muram;
50208 +
50209 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
50210 + SANITY_CHECK_RETURN_VALUE(p_ReplicGroupParam, E_INVALID_HANDLE, NULL);
50211 +
50212 + if (!FmPcdIsAdvancedOffloadSupported(h_FmPcd))
50213 + {
50214 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
50215 + return NULL;
50216 + }
50217 +
50218 + err = CheckParams(h_FmPcd, p_ReplicGroupParam);
50219 + if (err)
50220 + {
50221 + REPORT_ERROR(MAJOR, err, (NO_MSG));
50222 + return NULL;
50223 + }
50224 +
50225 + p_ReplicGroup = (t_FmPcdFrmReplicGroup*)XX_Malloc(sizeof(t_FmPcdFrmReplicGroup));
50226 + if (!p_ReplicGroup)
50227 + {
50228 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
50229 + return NULL;
50230 + }
50231 + memset(p_ReplicGroup, 0, sizeof(t_FmPcdFrmReplicGroup));
50232 +
50233 + /* initialize lists for internal driver use */
50234 + INIT_LIST(&p_ReplicGroup->availableMembersList);
50235 + INIT_LIST(&p_ReplicGroup->membersList);
50236 +
50237 + p_ReplicGroup->h_FmPcd = h_FmPcd;
50238 +
50239 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50240 + ASSERT_COND(h_Muram);
50241 +
50242 + /* initialize the group lock */
50243 + p_ReplicGroup->p_Lock = FmPcdAcquireLock(p_ReplicGroup->h_FmPcd);
50244 + if (!p_ReplicGroup->p_Lock)
50245 + {
50246 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Replic group lock"));
50247 + DeleteGroup(p_ReplicGroup);
50248 + return NULL;
50249 + }
50250 +
50251 + /* Allocate the frame replicator source table descriptor */
50252 + p_ReplicGroup->p_SourceTd =
50253 + (t_Handle)FM_MURAM_AllocMem(h_Muram,
50254 + FM_PCD_CC_AD_ENTRY_SIZE,
50255 + FM_PCD_CC_AD_TABLE_ALIGN);
50256 + if (!p_ReplicGroup->p_SourceTd)
50257 + {
50258 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("frame replicator source table descriptor"));
50259 + DeleteGroup(p_ReplicGroup);
50260 + return NULL;
50261 + }
50262 +
50263 + /* update the shadow size - required for the host commands */
50264 + err = FmPcdUpdateCcShadow(p_ReplicGroup->h_FmPcd,
50265 + FM_PCD_CC_AD_ENTRY_SIZE,
50266 + FM_PCD_CC_AD_TABLE_ALIGN);
50267 + if (err)
50268 + {
50269 + REPORT_ERROR(MAJOR, err, ("Update CC shadow"));
50270 + DeleteGroup(p_ReplicGroup);
50271 + return NULL;
50272 + }
50273 +
50274 + p_ReplicGroup->maxNumOfEntries = p_ReplicGroupParam->maxNumOfEntries;
50275 +
50276 + /* Allocate the maximal number of members ADs and Statistics AD for the group
50277 + It prevents allocation of Muram in run-time */
50278 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
50279 + {
50280 + err = AllocMember(p_ReplicGroup);
50281 + if (err)
50282 + {
50283 + REPORT_ERROR(MAJOR, err, ("allocate a new member"));
50284 + DeleteGroup(p_ReplicGroup);
50285 + return NULL;
50286 + }
50287 + }
50288 +
50289 + /* Initialize the members linked lists:
50290 + (hw - the one that is used by the FMan controller and
50291 + sw - the one that is managed by the driver internally) */
50292 + for (i=(p_ReplicGroupParam->numOfEntries-1); i>=0; i--)
50293 + {
50294 + /* check if this is the last member in the group */
50295 + if (i == (p_ReplicGroupParam->numOfEntries-1))
50296 + last = TRUE;
50297 + else
50298 + last = FALSE;
50299 +
50300 + /* Initialize a new member */
50301 + p_CurrentMember = InitMember(p_ReplicGroup,
50302 + &(p_ReplicGroupParam->nextEngineParams[i]),
50303 + last);
50304 + if (!p_CurrentMember)
50305 + {
50306 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50307 + DeleteGroup(p_ReplicGroup);
50308 + return NULL;
50309 + }
50310 +
50311 + /* Build the members group - link two consecutive members in the hw linked list */
50312 + LinkMemberToMember(p_ReplicGroup, p_CurrentMember, p_NextMember);
50313 +
50314 + /* update the driver internal members list to be compatible to the hw members linked list */
50315 + AddMemberToList(p_ReplicGroup, p_CurrentMember, &p_ReplicGroup->membersList);
50316 +
50317 + p_NextMember = p_CurrentMember;
50318 + }
50319 +
50320 + /* initialize the source table descriptor */
50321 + BuildSourceTd(p_ReplicGroup->p_SourceTd);
50322 +
50323 + /* link the source table descriptor to point to the first member in the group */
50324 + LinkSourceToMember(p_ReplicGroup, p_ReplicGroup->p_SourceTd, p_NextMember);
50325 +
50326 + return p_ReplicGroup;
50327 +}
50328 +
50329 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_ReplicGroup)
50330 +{
50331 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50332 +
50333 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50334 +
50335 + if (p_ReplicGroup->owners)
50336 + RETURN_ERROR(MAJOR,
50337 + E_INVALID_STATE,
50338 + ("the group has owners and can't be deleted"));
50339 +
50340 + DeleteGroup(p_ReplicGroup);
50341 +
50342 + return E_OK;
50343 +}
50344 +
50345 +
50346 +/*****************************************************************************/
50347 +/* API Run-time Frame replicator Control unit functions */
50348 +/*****************************************************************************/
50349 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_ReplicGroup,
50350 + uint16_t memberIndex,
50351 + t_FmPcdCcNextEngineParams *p_MemberParams)
50352 +{
50353 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50354 + t_FmPcdFrmReplicMember *p_NewMember, *p_CurrentMember = NULL, *p_PreviousMember = NULL;
50355 + t_Error err;
50356 + uint8_t memberPosition;
50357 +
50358 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50359 + SANITY_CHECK_RETURN_ERROR(p_MemberParams, E_INVALID_HANDLE);
50360 +
50361 + /* group lock */
50362 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50363 + if (GET_ERROR_TYPE(err) == E_BUSY)
50364 + return ERROR_CODE(E_BUSY);
50365 +
50366 + if (memberIndex > p_ReplicGroup->numOfEntries)
50367 + {
50368 + /* unlock */
50369 + FrmReplicGroupUnlock(p_ReplicGroup);
50370 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
50371 + ("memberIndex is greater than the members in the list"));
50372 + }
50373 +
50374 + if (memberIndex >= p_ReplicGroup->maxNumOfEntries)
50375 + {
50376 + /* unlock */
50377 + FrmReplicGroupUnlock(p_ReplicGroup);
50378 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("memberIndex is greater than the allowed number of members in the group"));
50379 + }
50380 +
50381 + if ((p_ReplicGroup->numOfEntries + 1) > FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
50382 + {
50383 + /* unlock */
50384 + FrmReplicGroupUnlock(p_ReplicGroup);
50385 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
50386 + ("numOfEntries with new entry can not be larger than %d\n",
50387 + FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES));
50388 + }
50389 +
50390 + err = MemberCheckParams(p_ReplicGroup->h_FmPcd, p_MemberParams);
50391 + if (err)
50392 + {
50393 + /* unlock */
50394 + FrmReplicGroupUnlock(p_ReplicGroup);
50395 + RETURN_ERROR(MAJOR, err, ("member check parameters in add operation"));
50396 + }
50397 + /* determine the member position in the group */
50398 + memberPosition = GetMemberPosition(p_ReplicGroup,
50399 + memberIndex,
50400 + TRUE/* add operation */);
50401 +
50402 + /* Initialize a new member */
50403 + p_NewMember = InitMember(p_ReplicGroup,
50404 + p_MemberParams,
50405 + (memberPosition == FRM_REPLIC_LAST_MEMBER_INDEX ? TRUE : FALSE));
50406 + if (!p_NewMember)
50407 + {
50408 + /* unlock */
50409 + FrmReplicGroupUnlock(p_ReplicGroup);
50410 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50411 + }
50412 +
50413 + switch (memberPosition)
50414 + {
50415 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
50416 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50417 + ASSERT_COND(p_CurrentMember);
50418 +
50419 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50420 +
50421 + /* update the internal group source TD */
50422 + LinkSourceToMember(p_ReplicGroup,
50423 + p_ReplicGroup->p_SourceTd,
50424 + p_NewMember);
50425 +
50426 + /* add member to the internal sw member list */
50427 + AddMemberToList(p_ReplicGroup,
50428 + p_NewMember,
50429 + &p_ReplicGroup->membersList);
50430 + break;
50431 +
50432 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
50433 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50434 + ASSERT_COND(p_CurrentMember);
50435 +
50436 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50437 + ASSERT_COND(p_PreviousMember);
50438 +
50439 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50440 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50441 +
50442 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50443 + break;
50444 +
50445 + case FRM_REPLIC_LAST_MEMBER_INDEX:
50446 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50447 + ASSERT_COND(p_PreviousMember);
50448 +
50449 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50450 + FillReplicAdOfTypeResult(p_PreviousMember->p_MemberAd, FALSE/*last*/);
50451 +
50452 + /* add the new member to the internal sw member list */
50453 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50454 + break;
50455 +
50456 + default:
50457 + /* unlock */
50458 + FrmReplicGroupUnlock(p_ReplicGroup);
50459 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in add member"));
50460 +
50461 + }
50462 +
50463 + /* unlock */
50464 + FrmReplicGroupUnlock(p_ReplicGroup);
50465 +
50466 + return E_OK;
50467 +}
50468 +
50469 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_ReplicGroup,
50470 + uint16_t memberIndex)
50471 +{
50472 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50473 + t_Error err;
50474 +
50475 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50476 +
50477 + /* lock */
50478 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50479 + if (GET_ERROR_TYPE(err) == E_BUSY)
50480 + return ERROR_CODE(E_BUSY);
50481 +
50482 + if (memberIndex >= p_ReplicGroup->numOfEntries)
50483 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member index to remove"));
50484 +
50485 + /* Design decision: group must contain at least one member
50486 + No possibility to remove the last member from the group */
50487 + if (p_ReplicGroup->numOfEntries == 1)
50488 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Can't remove the last member. At least one member should be related to a group."));
50489 +
50490 + err = RemoveMember(p_ReplicGroup, memberIndex);
50491 +
50492 + /* unlock */
50493 + FrmReplicGroupUnlock(p_ReplicGroup);
50494 +
50495 + switch (GET_ERROR_TYPE(err))
50496 + {
50497 + case E_OK:
50498 + return E_OK;
50499 +
50500 + case E_BUSY:
50501 + DBG(TRACE, ("E_BUSY error"));
50502 + return ERROR_CODE(E_BUSY);
50503 +
50504 + default:
50505 + RETURN_ERROR(MAJOR, err, NO_MSG);
50506 + }
50507 +}
50508 +
50509 +/*********************** End of API routines ************************/
50510 +
50511 +
50512 --- /dev/null
50513 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
50514 @@ -0,0 +1,101 @@
50515 +/*
50516 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50517 + *
50518 + * Redistribution and use in source and binary forms, with or without
50519 + * modification, are permitted provided that the following conditions are met:
50520 + * * Redistributions of source code must retain the above copyright
50521 + * notice, this list of conditions and the following disclaimer.
50522 + * * Redistributions in binary form must reproduce the above copyright
50523 + * notice, this list of conditions and the following disclaimer in the
50524 + * documentation and/or other materials provided with the distribution.
50525 + * * Neither the name of Freescale Semiconductor nor the
50526 + * names of its contributors may be used to endorse or promote products
50527 + * derived from this software without specific prior written permission.
50528 + *
50529 + *
50530 + * ALTERNATIVELY, this software may be distributed under the terms of the
50531 + * GNU General Public License ("GPL") as published by the Free Software
50532 + * Foundation, either version 2 of that License or (at your option) any
50533 + * later version.
50534 + *
50535 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50536 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50537 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50538 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50539 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50540 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50541 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50542 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50543 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50544 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50545 + */
50546 +
50547 +
50548 +/******************************************************************************
50549 + @File fm_replic.h
50550 +
50551 + @Description FM frame replicator
50552 +*//***************************************************************************/
50553 +#ifndef __FM_REPLIC_H
50554 +#define __FM_REPLIC_H
50555 +
50556 +#include "std_ext.h"
50557 +#include "error_ext.h"
50558 +
50559 +
50560 +#define FRM_REPLIC_SOURCE_TD_OPCODE 0x75
50561 +#define NEXT_FRM_REPLIC_ADDR_SHIFT 4
50562 +#define NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT 16
50563 +#define FRM_REPLIC_FR_BIT 0x08000000
50564 +#define FRM_REPLIC_NL_BIT 0x10000000
50565 +#define FRM_REPLIC_INVALID_MEMBER_INDEX 0xffff
50566 +#define FRM_REPLIC_FIRST_MEMBER_INDEX 0
50567 +
50568 +#define FRM_REPLIC_MIDDLE_MEMBER_INDEX 1
50569 +#define FRM_REPLIC_LAST_MEMBER_INDEX 2
50570 +
50571 +#define SOURCE_TD_ITSELF_OPTION 0x01
50572 +#define SOURCE_TD_COPY_OPTION 0x02
50573 +#define SOURCE_TD_ITSELF_AND_COPY_OPTION SOURCE_TD_ITSELF_OPTION | SOURCE_TD_COPY_OPTION
50574 +#define SOURCE_TD_NONE 0x04
50575 +
50576 +/*typedef enum e_SourceTdOption
50577 +{
50578 + e_SOURCE_TD_NONE = 0,
50579 + e_SOURCE_TD_ITSELF_OPTION = 1,
50580 + e_SOURCE_TD_COPY_OPTION = 2,
50581 + e_SOURCE_TD_ITSELF_AND_COPY_OPTION = e_SOURCE_TD_ITSELF_OPTION | e_SOURCE_TD_COPY_OPTION
50582 +} e_SourceTdOption;
50583 +*/
50584 +
50585 +typedef struct
50586 +{
50587 + volatile uint32_t type;
50588 + volatile uint32_t frGroupPointer;
50589 + volatile uint32_t operationCode;
50590 + volatile uint32_t reserved;
50591 +} t_FrmReplicGroupSourceAd;
50592 +
50593 +typedef struct t_FmPcdFrmReplicMember
50594 +{
50595 + void *p_MemberAd; /**< pointer to the member AD */
50596 + void *p_StatisticsAd;/**< pointer to the statistics AD of the member */
50597 + t_Handle h_Manip; /**< manip handle - need for free routines */
50598 + t_List node;
50599 +} t_FmPcdFrmReplicMember;
50600 +
50601 +typedef struct t_FmPcdFrmReplicGroup
50602 +{
50603 + t_Handle h_FmPcd;
50604 +
50605 + uint8_t maxNumOfEntries;/**< maximal number of members in the group */
50606 + uint8_t numOfEntries; /**< actual number of members in the group */
50607 + uint16_t owners; /**< how many keys share this frame replicator group */
50608 + void *p_SourceTd; /**< pointer to the frame replicator source table descriptor */
50609 + t_List membersList; /**< the members list - should reflect the order of the members as in the hw linked list*/
50610 + t_List availableMembersList;/**< list of all the available members in the group */
50611 + t_FmPcdLock *p_Lock;
50612 +} t_FmPcdFrmReplicGroup;
50613 +
50614 +
50615 +#endif /* __FM_REPLIC_H */
50616 --- /dev/null
50617 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
50618 @@ -0,0 +1,888 @@
50619 +/*
50620 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50621 + *
50622 + * Redistribution and use in source and binary forms, with or without
50623 + * modification, are permitted provided that the following conditions are met:
50624 + * * Redistributions of source code must retain the above copyright
50625 + * notice, this list of conditions and the following disclaimer.
50626 + * * Redistributions in binary form must reproduce the above copyright
50627 + * notice, this list of conditions and the following disclaimer in the
50628 + * documentation and/or other materials provided with the distribution.
50629 + * * Neither the name of Freescale Semiconductor nor the
50630 + * names of its contributors may be used to endorse or promote products
50631 + * derived from this software without specific prior written permission.
50632 + *
50633 + *
50634 + * ALTERNATIVELY, this software may be distributed under the terms of the
50635 + * GNU General Public License ("GPL") as published by the Free Software
50636 + * Foundation, either version 2 of that License or (at your option) any
50637 + * later version.
50638 + *
50639 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50640 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50641 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50642 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50643 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50644 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50645 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50646 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50647 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50648 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50649 + */
50650 +
50651 +#include "fsl_fman_kg.h"
50652 +
50653 +/****************************************/
50654 +/* static functions */
50655 +/****************************************/
50656 +
50657 +
50658 +static uint32_t build_ar_bind_scheme(uint8_t hwport_id, bool write)
50659 +{
50660 + uint32_t rw;
50661 +
50662 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50663 +
50664 + return (uint32_t)(FM_KG_KGAR_GO |
50665 + rw |
50666 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50667 + hwport_id |
50668 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
50669 +}
50670 +
50671 +static void clear_pe_all_scheme(struct fman_kg_regs *regs, uint8_t hwport_id)
50672 +{
50673 + uint32_t ar;
50674 +
50675 + fman_kg_write_sp(regs, 0xffffffff, 0);
50676 +
50677 + ar = build_ar_bind_scheme(hwport_id, TRUE);
50678 + fman_kg_write_ar_wait(regs, ar);
50679 +}
50680 +
50681 +static uint32_t build_ar_bind_cls_plan(uint8_t hwport_id, bool write)
50682 +{
50683 + uint32_t rw;
50684 +
50685 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50686 +
50687 + return (uint32_t)(FM_KG_KGAR_GO |
50688 + rw |
50689 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50690 + hwport_id |
50691 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
50692 +}
50693 +
50694 +static void clear_pe_all_cls_plan(struct fman_kg_regs *regs, uint8_t hwport_id)
50695 +{
50696 + uint32_t ar;
50697 +
50698 + fman_kg_write_cpp(regs, 0);
50699 +
50700 + ar = build_ar_bind_cls_plan(hwport_id, TRUE);
50701 + fman_kg_write_ar_wait(regs, ar);
50702 +}
50703 +
50704 +static uint8_t get_gen_ht_code(enum fman_kg_gen_extract_src src,
50705 + bool no_validation,
50706 + uint8_t *offset)
50707 +{
50708 + int code;
50709 +
50710 + switch (src) {
50711 + case E_FMAN_KG_GEN_EXTRACT_ETH:
50712 + code = no_validation ? 0x73 : 0x3;
50713 + break;
50714 +
50715 + case E_FMAN_KG_GEN_EXTRACT_ETYPE:
50716 + code = no_validation ? 0x77 : 0x7;
50717 + break;
50718 +
50719 + case E_FMAN_KG_GEN_EXTRACT_SNAP:
50720 + code = no_validation ? 0x74 : 0x4;
50721 + break;
50722 +
50723 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1:
50724 + code = no_validation ? 0x75 : 0x5;
50725 + break;
50726 +
50727 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N:
50728 + code = no_validation ? 0x76 : 0x6;
50729 + break;
50730 +
50731 + case E_FMAN_KG_GEN_EXTRACT_PPPoE:
50732 + code = no_validation ? 0x78 : 0x8;
50733 + break;
50734 +
50735 + case E_FMAN_KG_GEN_EXTRACT_MPLS_1:
50736 + code = no_validation ? 0x79 : 0x9;
50737 + break;
50738 +
50739 + case E_FMAN_KG_GEN_EXTRACT_MPLS_2:
50740 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x19;
50741 + break;
50742 +
50743 + case E_FMAN_KG_GEN_EXTRACT_MPLS_3:
50744 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x29;
50745 + break;
50746 +
50747 + case E_FMAN_KG_GEN_EXTRACT_MPLS_N:
50748 + code = no_validation ? 0x7a : 0xa;
50749 + break;
50750 +
50751 + case E_FMAN_KG_GEN_EXTRACT_IPv4_1:
50752 + code = no_validation ? 0x7b : 0xb;
50753 + break;
50754 +
50755 + case E_FMAN_KG_GEN_EXTRACT_IPv6_1:
50756 + code = no_validation ? 0x7b : 0x1b;
50757 + break;
50758 +
50759 + case E_FMAN_KG_GEN_EXTRACT_IPv4_2:
50760 + code = no_validation ? 0x7c : 0xc;
50761 + break;
50762 +
50763 + case E_FMAN_KG_GEN_EXTRACT_IPv6_2:
50764 + code = no_validation ? 0x7c : 0x1c;
50765 + break;
50766 +
50767 + case E_FMAN_KG_GEN_EXTRACT_MINENCAP:
50768 + code = no_validation ? 0x7c : 0x2c;
50769 + break;
50770 +
50771 + case E_FMAN_KG_GEN_EXTRACT_IP_PID:
50772 + code = no_validation ? 0x72 : 0x2;
50773 + break;
50774 +
50775 + case E_FMAN_KG_GEN_EXTRACT_GRE:
50776 + code = no_validation ? 0x7d : 0xd;
50777 + break;
50778 +
50779 + case E_FMAN_KG_GEN_EXTRACT_TCP:
50780 + code = no_validation ? 0x7e : 0xe;
50781 + break;
50782 +
50783 + case E_FMAN_KG_GEN_EXTRACT_UDP:
50784 + code = no_validation ? 0x7e : 0x1e;
50785 + break;
50786 +
50787 + case E_FMAN_KG_GEN_EXTRACT_SCTP:
50788 + code = no_validation ? 0x7e : 0x3e;
50789 + break;
50790 +
50791 + case E_FMAN_KG_GEN_EXTRACT_DCCP:
50792 + code = no_validation ? 0x7e : 0x4e;
50793 + break;
50794 +
50795 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_AH:
50796 + code = no_validation ? 0x7e : 0x2e;
50797 + break;
50798 +
50799 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP:
50800 + code = no_validation ? 0x7e : 0x6e;
50801 + break;
50802 +
50803 + case E_FMAN_KG_GEN_EXTRACT_SHIM_1:
50804 + code = 0x70;
50805 + break;
50806 +
50807 + case E_FMAN_KG_GEN_EXTRACT_SHIM_2:
50808 + code = 0x71;
50809 + break;
50810 +
50811 + case E_FMAN_KG_GEN_EXTRACT_FROM_DFLT:
50812 + code = 0x10;
50813 + break;
50814 +
50815 + case E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START:
50816 + code = 0x40;
50817 + break;
50818 +
50819 + case E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT:
50820 + code = 0x20;
50821 + break;
50822 +
50823 + case E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE:
50824 + code = 0x7f;
50825 + break;
50826 +
50827 + case E_FMAN_KG_GEN_EXTRACT_FROM_FQID:
50828 + code = 0x20;
50829 + *offset += 0x20;
50830 + break;
50831 +
50832 + default:
50833 + code = FM_KG_SCH_GEN_HT_INVALID;
50834 + }
50835 +
50836 + return (uint8_t)code;
50837 +}
50838 +
50839 +static uint32_t build_ar_scheme(uint8_t scheme,
50840 + uint8_t hwport_id,
50841 + bool update_counter,
50842 + bool write)
50843 +{
50844 + uint32_t rw;
50845 +
50846 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
50847 +
50848 + return (uint32_t)(FM_KG_KGAR_GO |
50849 + rw |
50850 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
50851 + hwport_id |
50852 + ((uint32_t)scheme << FM_KG_KGAR_NUM_SHIFT) |
50853 + (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
50854 +}
50855 +
50856 +static uint32_t build_ar_cls_plan(uint8_t grp,
50857 + uint8_t entries_mask,
50858 + uint8_t hwport_id,
50859 + bool write)
50860 +{
50861 + uint32_t rw;
50862 +
50863 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
50864 +
50865 + return (uint32_t)(FM_KG_KGAR_GO |
50866 + rw |
50867 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
50868 + hwport_id |
50869 + ((uint32_t)grp << FM_KG_KGAR_NUM_SHIFT) |
50870 + ((uint32_t)entries_mask << FM_KG_KGAR_WSEL_SHIFT));
50871 +}
50872 +
50873 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar)
50874 +{
50875 + iowrite32be(fmkg_ar, &regs->fmkg_ar);
50876 + /* Wait for GO to be idle and read error */
50877 + while ((fmkg_ar = ioread32be(&regs->fmkg_ar)) & FM_KG_KGAR_GO) ;
50878 + if (fmkg_ar & FM_PCD_KG_KGAR_ERR)
50879 + return -EINVAL;
50880 + return 0;
50881 +}
50882 +
50883 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add)
50884 +{
50885 +
50886 + struct fman_kg_pe_regs *kgpe_regs;
50887 + uint32_t tmp;
50888 +
50889 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
50890 + tmp = ioread32be(&kgpe_regs->fmkg_pe_sp);
50891 +
50892 + if (add)
50893 + tmp |= sp;
50894 + else /* clear */
50895 + tmp &= ~sp;
50896 +
50897 + iowrite32be(tmp, &kgpe_regs->fmkg_pe_sp);
50898 +
50899 +}
50900 +
50901 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp)
50902 +{
50903 + struct fman_kg_pe_regs *kgpe_regs;
50904 +
50905 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
50906 +
50907 + iowrite32be(cpp, &kgpe_regs->fmkg_pe_cpp);
50908 +}
50909 +
50910 +void fman_kg_get_event(struct fman_kg_regs *regs,
50911 + uint32_t *event,
50912 + uint32_t *scheme_idx)
50913 +{
50914 + uint32_t mask, force;
50915 +
50916 + *event = ioread32be(&regs->fmkg_eer);
50917 + mask = ioread32be(&regs->fmkg_eeer);
50918 + *scheme_idx = ioread32be(&regs->fmkg_seer);
50919 + *scheme_idx &= ioread32be(&regs->fmkg_seeer);
50920 +
50921 + *event &= mask;
50922 +
50923 + /* clear the forced events */
50924 + force = ioread32be(&regs->fmkg_feer);
50925 + if (force & *event)
50926 + iowrite32be(force & ~*event ,&regs->fmkg_feer);
50927 +
50928 + iowrite32be(*event, &regs->fmkg_eer);
50929 + iowrite32be(*scheme_idx, &regs->fmkg_seer);
50930 +}
50931 +
50932 +
50933 +void fman_kg_init(struct fman_kg_regs *regs,
50934 + uint32_t exceptions,
50935 + uint32_t dflt_nia)
50936 +{
50937 + uint32_t tmp;
50938 + int i;
50939 +
50940 + iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
50941 + &regs->fmkg_eer);
50942 +
50943 + tmp = 0;
50944 + if (exceptions & FM_EX_KG_DOUBLE_ECC)
50945 + tmp |= FM_EX_KG_DOUBLE_ECC;
50946 +
50947 + if (exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)
50948 + tmp |= FM_EX_KG_KEYSIZE_OVERFLOW;
50949 +
50950 + iowrite32be(tmp, &regs->fmkg_eeer);
50951 + iowrite32be(0, &regs->fmkg_fdor);
50952 + iowrite32be(0, &regs->fmkg_gdv0r);
50953 + iowrite32be(0, &regs->fmkg_gdv1r);
50954 + iowrite32be(dflt_nia, &regs->fmkg_gcr);
50955 +
50956 + /* Clear binding between ports to schemes and classification plans
50957 + * so that all ports are not bound to any scheme/classification plan */
50958 + for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
50959 + clear_pe_all_scheme(regs, (uint8_t)i);
50960 + clear_pe_all_cls_plan(regs, (uint8_t)i);
50961 + }
50962 +}
50963 +
50964 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs)
50965 +{
50966 + /* enable and enable all scheme interrupts */
50967 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seer);
50968 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seeer);
50969 +}
50970 +
50971 +void fman_kg_enable(struct fman_kg_regs *regs)
50972 +{
50973 + iowrite32be(ioread32be(&regs->fmkg_gcr) | FM_KG_KGGCR_EN,
50974 + &regs->fmkg_gcr);
50975 +}
50976 +
50977 +void fman_kg_disable(struct fman_kg_regs *regs)
50978 +{
50979 + iowrite32be(ioread32be(&regs->fmkg_gcr) & ~FM_KG_KGGCR_EN,
50980 + &regs->fmkg_gcr);
50981 +}
50982 +
50983 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset)
50984 +{
50985 + iowrite32be(offset, &regs->fmkg_fdor);
50986 +}
50987 +
50988 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
50989 + uint8_t def_id,
50990 + uint32_t val)
50991 +{
50992 + if(def_id == 0)
50993 + iowrite32be(val, &regs->fmkg_gdv0r);
50994 + else
50995 + iowrite32be(val, &regs->fmkg_gdv1r);
50996 +}
50997 +
50998 +
50999 +void fman_kg_set_exception(struct fman_kg_regs *regs,
51000 + uint32_t exception,
51001 + bool enable)
51002 +{
51003 + uint32_t tmp;
51004 +
51005 + tmp = ioread32be(&regs->fmkg_eeer);
51006 +
51007 + if (enable) {
51008 + tmp |= exception;
51009 + } else {
51010 + tmp &= ~exception;
51011 + }
51012 +
51013 + iowrite32be(tmp, &regs->fmkg_eeer);
51014 +}
51015 +
51016 +void fman_kg_get_exception(struct fman_kg_regs *regs,
51017 + uint32_t *events,
51018 + uint32_t *scheme_ids,
51019 + bool clear)
51020 +{
51021 + uint32_t mask;
51022 +
51023 + *events = ioread32be(&regs->fmkg_eer);
51024 + mask = ioread32be(&regs->fmkg_eeer);
51025 + *events &= mask;
51026 +
51027 + *scheme_ids = 0;
51028 +
51029 + if (*events & FM_EX_KG_KEYSIZE_OVERFLOW) {
51030 + *scheme_ids = ioread32be(&regs->fmkg_seer);
51031 + mask = ioread32be(&regs->fmkg_seeer);
51032 + *scheme_ids &= mask;
51033 + }
51034 +
51035 + if (clear) {
51036 + iowrite32be(*scheme_ids, &regs->fmkg_seer);
51037 + iowrite32be(*events, &regs->fmkg_eer);
51038 + }
51039 +}
51040 +
51041 +void fman_kg_get_capture(struct fman_kg_regs *regs,
51042 + struct fman_kg_ex_ecc_attr *ecc_attr,
51043 + bool clear)
51044 +{
51045 + uint32_t tmp;
51046 +
51047 + tmp = ioread32be(&regs->fmkg_serc);
51048 +
51049 + if (tmp & KG_FMKG_SERC_CAP) {
51050 + /* Captured data is valid */
51051 + ecc_attr->valid = TRUE;
51052 + ecc_attr->double_ecc =
51053 + (bool)((tmp & KG_FMKG_SERC_CET) ? TRUE : FALSE);
51054 + ecc_attr->single_ecc_count =
51055 + (uint8_t)((tmp & KG_FMKG_SERC_CNT_MSK) >>
51056 + KG_FMKG_SERC_CNT_SHIFT);
51057 + ecc_attr->addr = (uint16_t)(tmp & KG_FMKG_SERC_ADDR_MSK);
51058 +
51059 + if (clear)
51060 + iowrite32be(KG_FMKG_SERC_CAP, &regs->fmkg_serc);
51061 + } else {
51062 + /* No ECC error is captured */
51063 + ecc_attr->valid = FALSE;
51064 + }
51065 +}
51066 +
51067 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
51068 + struct fman_kg_scheme_regs *scheme_regs)
51069 +{
51070 + struct fman_kg_extract_params *extract_params;
51071 + struct fman_kg_gen_extract_params *gen_params;
51072 + uint32_t tmp_reg, i, select, mask, fqb;
51073 + uint8_t offset, shift, ht;
51074 +
51075 + /* Zero out all registers so no need to care about unused ones */
51076 + memset(scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
51077 +
51078 + /* Mode register */
51079 + tmp_reg = fm_kg_build_nia(params->next_engine,
51080 + params->next_engine_action);
51081 + if (tmp_reg == KG_NIA_INVALID) {
51082 + return -EINVAL;
51083 + }
51084 +
51085 + if (params->next_engine == E_FMAN_PCD_PLCR) {
51086 + tmp_reg |= FMAN_KG_SCH_MODE_NIA_PLCR;
51087 + }
51088 + else if (params->next_engine == E_FMAN_PCD_CC) {
51089 + tmp_reg |= (uint32_t)params->cc_params.base_offset <<
51090 + FMAN_KG_SCH_MODE_CCOBASE_SHIFT;
51091 + }
51092 +
51093 + tmp_reg |= FMAN_KG_SCH_MODE_EN;
51094 + scheme_regs->kgse_mode = tmp_reg;
51095 +
51096 + /* Match vector */
51097 + scheme_regs->kgse_mv = params->match_vector;
51098 +
51099 + extract_params = &params->extract_params;
51100 +
51101 + /* Scheme default values registers */
51102 + scheme_regs->kgse_dv0 = extract_params->def_scheme_0;
51103 + scheme_regs->kgse_dv1 = extract_params->def_scheme_1;
51104 +
51105 + /* Extract Known Fields Command register */
51106 + scheme_regs->kgse_ekfc = extract_params->known_fields;
51107 +
51108 + /* Entry Extract Known Default Value register */
51109 + tmp_reg = 0;
51110 + tmp_reg |= extract_params->known_fields_def.mac_addr <<
51111 + FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT;
51112 + tmp_reg |= extract_params->known_fields_def.vlan_tci <<
51113 + FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT;
51114 + tmp_reg |= extract_params->known_fields_def.etype <<
51115 + FMAN_KG_SCH_DEF_ETYPE_SHIFT;
51116 + tmp_reg |= extract_params->known_fields_def.ppp_sid <<
51117 + FMAN_KG_SCH_DEF_PPP_SID_SHIFT;
51118 + tmp_reg |= extract_params->known_fields_def.ppp_pid <<
51119 + FMAN_KG_SCH_DEF_PPP_PID_SHIFT;
51120 + tmp_reg |= extract_params->known_fields_def.mpls <<
51121 + FMAN_KG_SCH_DEF_MPLS_SHIFT;
51122 + tmp_reg |= extract_params->known_fields_def.ip_addr <<
51123 + FMAN_KG_SCH_DEF_IP_ADDR_SHIFT;
51124 + tmp_reg |= extract_params->known_fields_def.ptype <<
51125 + FMAN_KG_SCH_DEF_PTYPE_SHIFT;
51126 + tmp_reg |= extract_params->known_fields_def.ip_tos_tc <<
51127 + FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT;
51128 + tmp_reg |= extract_params->known_fields_def.ipv6_fl <<
51129 + FMAN_KG_SCH_DEF_IPv6_FL_SHIFT;
51130 + tmp_reg |= extract_params->known_fields_def.ipsec_spi <<
51131 + FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT;
51132 + tmp_reg |= extract_params->known_fields_def.l4_port <<
51133 + FMAN_KG_SCH_DEF_L4_PORT_SHIFT;
51134 + tmp_reg |= extract_params->known_fields_def.tcp_flg <<
51135 + FMAN_KG_SCH_DEF_TCP_FLG_SHIFT;
51136 +
51137 + scheme_regs->kgse_ekdv = tmp_reg;
51138 +
51139 + /* Generic extract registers */
51140 + if (extract_params->gen_extract_num > FM_KG_NUM_OF_GENERIC_REGS) {
51141 + return -EINVAL;
51142 + }
51143 +
51144 + for (i = 0; i < extract_params->gen_extract_num; i++) {
51145 + gen_params = extract_params->gen_extract + i;
51146 +
51147 + tmp_reg = FMAN_KG_SCH_GEN_VALID;
51148 + tmp_reg |= (uint32_t)gen_params->def_val <<
51149 + FMAN_KG_SCH_GEN_DEF_SHIFT;
51150 +
51151 + if (gen_params->type == E_FMAN_KG_HASH_EXTRACT) {
51152 + if ((gen_params->extract > FMAN_KG_SCH_GEN_SIZE_MAX) ||
51153 + (gen_params->extract == 0)) {
51154 + return -EINVAL;
51155 + }
51156 + } else {
51157 + tmp_reg |= FMAN_KG_SCH_GEN_OR;
51158 + }
51159 +
51160 + tmp_reg |= (uint32_t)gen_params->extract <<
51161 + FMAN_KG_SCH_GEN_SIZE_SHIFT;
51162 + tmp_reg |= (uint32_t)gen_params->mask <<
51163 + FMAN_KG_SCH_GEN_MASK_SHIFT;
51164 +
51165 + offset = gen_params->offset;
51166 + ht = get_gen_ht_code(gen_params->src,
51167 + gen_params->no_validation,
51168 + &offset);
51169 + tmp_reg |= (uint32_t)ht << FMAN_KG_SCH_GEN_HT_SHIFT;
51170 + tmp_reg |= offset;
51171 +
51172 + scheme_regs->kgse_gec[i] = tmp_reg;
51173 + }
51174 +
51175 + /* Masks registers */
51176 + if (extract_params->masks_num > FM_KG_EXTRACT_MASKS_NUM) {
51177 + return -EINVAL;
51178 + }
51179 +
51180 + select = 0;
51181 + mask = 0;
51182 + fqb = 0;
51183 + for (i = 0; i < extract_params->masks_num; i++) {
51184 + /* MCSx fields */
51185 + KG_GET_MASK_SEL_SHIFT(shift, i);
51186 + if (extract_params->masks[i].is_known) {
51187 + /* Mask known field */
51188 + select |= extract_params->masks[i].field_or_gen_idx <<
51189 + shift;
51190 + } else {
51191 + /* Mask generic extract */
51192 + select |= (extract_params->masks[i].field_or_gen_idx +
51193 + FM_KG_MASK_SEL_GEN_BASE) << shift;
51194 + }
51195 +
51196 + /* MOx fields - spread between se_bmch and se_fqb registers */
51197 + KG_GET_MASK_OFFSET_SHIFT(shift, i);
51198 + if (i < 2) {
51199 + select |= (uint32_t)extract_params->masks[i].offset <<
51200 + shift;
51201 + } else {
51202 + fqb |= (uint32_t)extract_params->masks[i].offset <<
51203 + shift;
51204 + }
51205 +
51206 + /* BMx fields */
51207 + KG_GET_MASK_SHIFT(shift, i);
51208 + mask |= (uint32_t)extract_params->masks[i].mask << shift;
51209 + }
51210 +
51211 + /* Finish with rest of BMx fileds -
51212 + * don't mask bits for unused masks by setting
51213 + * corresponding BMx field = 0xFF */
51214 + for (i = extract_params->masks_num; i < FM_KG_EXTRACT_MASKS_NUM; i++) {
51215 + KG_GET_MASK_SHIFT(shift, i);
51216 + mask |= 0xFF << shift;
51217 + }
51218 +
51219 + scheme_regs->kgse_bmch = select;
51220 + scheme_regs->kgse_bmcl = mask;
51221 +
51222 + /* Finish with FQB register initialization.
51223 + * Check fqid is 24-bit value. */
51224 + if (params->base_fqid & ~0x00FFFFFF) {
51225 + return -EINVAL;
51226 + }
51227 +
51228 + fqb |= params->base_fqid;
51229 + scheme_regs->kgse_fqb = fqb;
51230 +
51231 + /* Hash Configuration register */
51232 + tmp_reg = 0;
51233 + if (params->hash_params.use_hash) {
51234 + /* Check hash mask is 24-bit value */
51235 + if (params->hash_params.mask & ~0x00FFFFFF) {
51236 + return -EINVAL;
51237 + }
51238 +
51239 + /* Hash function produces 64-bit value, 24 bits of that
51240 + * are used to generate fq_id and policer profile.
51241 + * Thus, maximal shift is 40 bits to allow 24 bits out of 64.
51242 + */
51243 + if (params->hash_params.shift_r > FMAN_KG_SCH_HASH_HSHIFT_MAX) {
51244 + return -EINVAL;
51245 + }
51246 +
51247 + tmp_reg |= params->hash_params.mask;
51248 + tmp_reg |= (uint32_t)params->hash_params.shift_r <<
51249 + FMAN_KG_SCH_HASH_HSHIFT_SHIFT;
51250 +
51251 + if (params->hash_params.sym) {
51252 + tmp_reg |= FMAN_KG_SCH_HASH_SYM;
51253 + }
51254 +
51255 + }
51256 +
51257 + if (params->bypass_fqid_gen) {
51258 + tmp_reg |= FMAN_KG_SCH_HASH_NO_FQID_GEN;
51259 + }
51260 +
51261 + scheme_regs->kgse_hc = tmp_reg;
51262 +
51263 + /* Policer Profile register */
51264 + if (params->policer_params.bypass_pp_gen) {
51265 + tmp_reg = 0;
51266 + } else {
51267 + /* Lower 8 bits of 24-bits extracted from hash result
51268 + * are used for policer profile generation.
51269 + * That leaves maximum shift value = 23. */
51270 + if (params->policer_params.shift > FMAN_KG_SCH_PP_SHIFT_MAX) {
51271 + return -EINVAL;
51272 + }
51273 +
51274 + tmp_reg = params->policer_params.base;
51275 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51276 + FMAN_KG_SCH_PP_SH_SHIFT) &
51277 + FMAN_KG_SCH_PP_SH_MASK;
51278 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51279 + FMAN_KG_SCH_PP_SL_SHIFT) &
51280 + FMAN_KG_SCH_PP_SL_MASK;
51281 + tmp_reg |= (uint32_t)params->policer_params.mask <<
51282 + FMAN_KG_SCH_PP_MASK_SHIFT;
51283 + }
51284 +
51285 + scheme_regs->kgse_ppc = tmp_reg;
51286 +
51287 + /* Coarse Classification Bit Select register */
51288 + if (params->next_engine == E_FMAN_PCD_CC) {
51289 + scheme_regs->kgse_ccbs = params->cc_params.qlcv_bits_sel;
51290 + }
51291 +
51292 + /* Packets Counter register */
51293 + if (params->update_counter) {
51294 + scheme_regs->kgse_spc = params->counter_value;
51295 + }
51296 +
51297 + return 0;
51298 +}
51299 +
51300 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
51301 + uint8_t scheme_id,
51302 + uint8_t hwport_id,
51303 + struct fman_kg_scheme_regs *scheme_regs,
51304 + bool update_counter)
51305 +{
51306 + struct fman_kg_scheme_regs *kgse_regs;
51307 + uint32_t tmp_reg;
51308 + int err, i;
51309 +
51310 + /* Write indirect scheme registers */
51311 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51312 +
51313 + iowrite32be(scheme_regs->kgse_mode, &kgse_regs->kgse_mode);
51314 + iowrite32be(scheme_regs->kgse_ekfc, &kgse_regs->kgse_ekfc);
51315 + iowrite32be(scheme_regs->kgse_ekdv, &kgse_regs->kgse_ekdv);
51316 + iowrite32be(scheme_regs->kgse_bmch, &kgse_regs->kgse_bmch);
51317 + iowrite32be(scheme_regs->kgse_bmcl, &kgse_regs->kgse_bmcl);
51318 + iowrite32be(scheme_regs->kgse_fqb, &kgse_regs->kgse_fqb);
51319 + iowrite32be(scheme_regs->kgse_hc, &kgse_regs->kgse_hc);
51320 + iowrite32be(scheme_regs->kgse_ppc, &kgse_regs->kgse_ppc);
51321 + iowrite32be(scheme_regs->kgse_spc, &kgse_regs->kgse_spc);
51322 + iowrite32be(scheme_regs->kgse_dv0, &kgse_regs->kgse_dv0);
51323 + iowrite32be(scheme_regs->kgse_dv1, &kgse_regs->kgse_dv1);
51324 + iowrite32be(scheme_regs->kgse_ccbs, &kgse_regs->kgse_ccbs);
51325 + iowrite32be(scheme_regs->kgse_mv, &kgse_regs->kgse_mv);
51326 +
51327 + for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
51328 + iowrite32be(scheme_regs->kgse_gec[i], &kgse_regs->kgse_gec[i]);
51329 +
51330 + /* Write AR (Action register) */
51331 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, update_counter, TRUE);
51332 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51333 + return err;
51334 +}
51335 +
51336 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
51337 + uint8_t scheme_id,
51338 + uint8_t hwport_id)
51339 +{
51340 + struct fman_kg_scheme_regs *kgse_regs;
51341 + uint32_t tmp_reg;
51342 + int err, i;
51343 +
51344 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51345 +
51346 + /* Clear all registers including enable bit in mode register */
51347 + for (i = 0; i < (sizeof(struct fman_kg_scheme_regs)) / 4; ++i) {
51348 + iowrite32be(0, ((uint32_t *)kgse_regs + i));
51349 + }
51350 +
51351 + /* Write AR (Action register) */
51352 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, FALSE, TRUE);
51353 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51354 + return err;
51355 +}
51356 +
51357 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
51358 + uint8_t scheme_id,
51359 + uint8_t hwport_id,
51360 + uint32_t *counter)
51361 +{
51362 + struct fman_kg_scheme_regs *kgse_regs;
51363 + uint32_t tmp_reg;
51364 + int err;
51365 +
51366 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51367 +
51368 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51369 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51370 +
51371 + if (err != 0)
51372 + return err;
51373 +
51374 + *counter = ioread32be(&kgse_regs->kgse_spc);
51375 +
51376 + return 0;
51377 +}
51378 +
51379 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
51380 + uint8_t scheme_id,
51381 + uint8_t hwport_id,
51382 + uint32_t counter)
51383 +{
51384 + struct fman_kg_scheme_regs *kgse_regs;
51385 + uint32_t tmp_reg;
51386 + int err;
51387 +
51388 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51389 +
51390 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51391 +
51392 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51393 + if (err != 0)
51394 + return err;
51395 +
51396 + /* Keygen indirect access memory contains all scheme_id registers
51397 + * by now. Change only counter value. */
51398 + iowrite32be(counter, &kgse_regs->kgse_spc);
51399 +
51400 + /* Write back scheme registers */
51401 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, TRUE);
51402 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51403 +
51404 + return err;
51405 +}
51406 +
51407 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs)
51408 +{
51409 + return ioread32be(&regs->fmkg_tpc);
51410 +}
51411 +
51412 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
51413 + struct fman_kg_cp_regs *cls_plan_regs)
51414 +{
51415 + uint8_t entries_set, entry_bit;
51416 + int i;
51417 +
51418 + /* Zero out all group's register */
51419 + memset(cls_plan_regs, 0, sizeof(struct fman_kg_cp_regs));
51420 +
51421 + /* Go over all classification entries in params->entries_mask and
51422 + * configure the corresponding cpe register */
51423 + entries_set = params->entries_mask;
51424 + for (i = 0; entries_set; i++) {
51425 + entry_bit = (uint8_t)(0x80 >> i);
51426 + if ((entry_bit & entries_set) == 0)
51427 + continue;
51428 + entries_set ^= entry_bit;
51429 + cls_plan_regs->kgcpe[i] = params->mask_vector[i];
51430 + }
51431 +
51432 + return 0;
51433 +}
51434 +
51435 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
51436 + uint8_t grp_id,
51437 + uint8_t entries_mask,
51438 + uint8_t hwport_id,
51439 + struct fman_kg_cp_regs *cls_plan_regs)
51440 +{
51441 + struct fman_kg_cp_regs *kgcpe_regs;
51442 + uint32_t tmp_reg;
51443 + int i, err;
51444 +
51445 + /* Check group index is valid and the group isn't empty */
51446 + if (grp_id >= FM_KG_CLS_PLAN_GRPS_NUM)
51447 + return -EINVAL;
51448 +
51449 + /* Write indirect classification plan registers */
51450 + kgcpe_regs = (struct fman_kg_cp_regs *)&(regs->fmkg_indirect[0]);
51451 +
51452 + for (i = 0; i < FM_KG_NUM_CLS_PLAN_ENTR; i++) {
51453 + iowrite32be(cls_plan_regs->kgcpe[i], &kgcpe_regs->kgcpe[i]);
51454 + }
51455 +
51456 + tmp_reg = build_ar_cls_plan(grp_id, entries_mask, hwport_id, TRUE);
51457 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51458 + return err;
51459 +}
51460 +
51461 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
51462 + uint8_t hwport_id,
51463 + uint32_t schemes)
51464 +{
51465 + struct fman_kg_pe_regs *kg_pe_regs;
51466 + uint32_t tmp_reg;
51467 + int err;
51468 +
51469 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51470 +
51471 + iowrite32be(schemes, &kg_pe_regs->fmkg_pe_sp);
51472 +
51473 + tmp_reg = build_ar_bind_scheme(hwport_id, TRUE);
51474 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51475 + return err;
51476 +}
51477 +
51478 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
51479 + uint8_t grp_mask,
51480 + uint32_t *bind_cls_plans)
51481 +{
51482 + /* Check grp_base and grp_mask are 5-bits values */
51483 + if ((grp_base & ~0x0000001F) || (grp_mask & ~0x0000001F))
51484 + return -EINVAL;
51485 +
51486 + *bind_cls_plans = (uint32_t) ((grp_mask << FMAN_KG_PE_CPP_MASK_SHIFT) | grp_base);
51487 + return 0;
51488 +}
51489 +
51490 +
51491 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
51492 + uint8_t hwport_id,
51493 + uint32_t bind_cls_plans)
51494 +{
51495 + struct fman_kg_pe_regs *kg_pe_regs;
51496 + uint32_t tmp_reg;
51497 + int err;
51498 +
51499 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51500 +
51501 + iowrite32be(bind_cls_plans, &kg_pe_regs->fmkg_pe_cpp);
51502 +
51503 + tmp_reg = build_ar_bind_cls_plan(hwport_id, TRUE);
51504 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51505 + return err;
51506 +}
51507 --- /dev/null
51508 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
51509 @@ -0,0 +1,129 @@
51510 +/*
51511 + * Copyright 2012 Freescale Semiconductor Inc.
51512 + *
51513 + * Redistribution and use in source and binary forms, with or without
51514 + * modification, are permitted provided that the following conditions are met:
51515 + * * Redistributions of source code must retain the above copyright
51516 + * notice, this list of conditions and the following disclaimer.
51517 + * * Redistributions in binary form must reproduce the above copyright
51518 + * notice, this list of conditions and the following disclaimer in the
51519 + * documentation and/or other materials provided with the distribution.
51520 + * * Neither the name of Freescale Semiconductor nor the
51521 + * names of its contributors may be used to endorse or promote products
51522 + * derived from this software without specific prior written permission.
51523 + *
51524 + *
51525 + * ALTERNATIVELY, this software may be distributed under the terms of the
51526 + * GNU General Public License ("GPL") as published by the Free Software
51527 + * Foundation, either version 2 of that License or (at your option) any
51528 + * later version.
51529 + *
51530 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51531 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51532 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51533 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51534 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51535 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51536 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51537 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51538 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51539 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51540 + */
51541 +
51542 +#include "fsl_fman_prs.h"
51543 +
51544 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51545 +{
51546 + return ioread32be(&regs->fmpr_perr) & ev_mask;
51547 +}
51548 +
51549 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs)
51550 +{
51551 + return ioread32be(&regs->fmpr_perer);
51552 +}
51553 +
51554 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event)
51555 +{
51556 + iowrite32be(event, &regs->fmpr_perr);
51557 +}
51558 +
51559 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51560 +{
51561 + return ioread32be(&regs->fmpr_pevr) & ev_mask;
51562 +}
51563 +
51564 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs)
51565 +{
51566 + return ioread32be(&regs->fmpr_pever);
51567 +}
51568 +
51569 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event)
51570 +{
51571 + iowrite32be(event, &regs->fmpr_pevr);
51572 +}
51573 +
51574 +void fman_prs_defconfig(struct fman_prs_cfg *cfg)
51575 +{
51576 + cfg->port_id_stat = 0;
51577 + cfg->max_prs_cyc_lim = DEFAULT_MAX_PRS_CYC_LIM;
51578 + cfg->prs_exceptions = 0x03000000;
51579 +}
51580 +
51581 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg)
51582 +{
51583 + uint32_t tmp;
51584 +
51585 + iowrite32be(cfg->max_prs_cyc_lim, &regs->fmpr_rpclim);
51586 + iowrite32be((FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS),
51587 + &regs->fmpr_pevr);
51588 +
51589 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
51590 + iowrite32be(FM_PCD_PRS_SINGLE_ECC, &regs->fmpr_pever);
51591 + else
51592 + iowrite32be(0, &regs->fmpr_pever);
51593 +
51594 + iowrite32be(FM_PCD_PRS_DOUBLE_ECC, &regs->fmpr_perr);
51595 +
51596 + tmp = 0;
51597 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
51598 + tmp |= FM_PCD_PRS_DOUBLE_ECC;
51599 + iowrite32be(tmp, &regs->fmpr_perer);
51600 +
51601 + iowrite32be(cfg->port_id_stat, &regs->fmpr_ppsc);
51602 +
51603 + return 0;
51604 +}
51605 +
51606 +void fman_prs_enable(struct fman_prs_regs *regs)
51607 +{
51608 + uint32_t tmp;
51609 +
51610 + tmp = ioread32be(&regs->fmpr_rpimac) | FM_PCD_PRS_RPIMAC_EN;
51611 + iowrite32be(tmp, &regs->fmpr_rpimac);
51612 +}
51613 +
51614 +void fman_prs_disable(struct fman_prs_regs *regs)
51615 +{
51616 + uint32_t tmp;
51617 +
51618 + tmp = ioread32be(&regs->fmpr_rpimac) & ~FM_PCD_PRS_RPIMAC_EN;
51619 + iowrite32be(tmp, &regs->fmpr_rpimac);
51620 +}
51621 +
51622 +int fman_prs_is_enabled(struct fman_prs_regs *regs)
51623 +{
51624 + return ioread32be(&regs->fmpr_rpimac) & FM_PCD_PRS_RPIMAC_EN;
51625 +}
51626 +
51627 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk)
51628 +{
51629 + iowrite32be(pid_msk, &regs->fmpr_ppsc);
51630 +}
51631 +
51632 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable)
51633 +{
51634 + if (enable)
51635 + iowrite32be(FM_PCD_PRS_PPSC_ALL_PORTS, &regs->fmpr_ppsc);
51636 + else
51637 + iowrite32be(0, &regs->fmpr_ppsc);
51638 +}
51639 --- /dev/null
51640 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
51641 @@ -0,0 +1,15 @@
51642 +#
51643 +# Makefile for the Freescale Ethernet controllers
51644 +#
51645 +ccflags-y += -DVERSION=\"\"
51646 +#
51647 +#Include netcomm SW specific definitions
51648 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
51649 +
51650 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
51651 +
51652 +ccflags-y += -I$(NCSW_FM_INC)
51653 +
51654 +obj-y += fsl-ncsw-Pcd.o
51655 +
51656 +fsl-ncsw-Pcd-objs := fm_port.o fm_port_im.o fman_port.o
51657 --- /dev/null
51658 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
51659 @@ -0,0 +1,6436 @@
51660 +/*
51661 + * Copyright 2008-2012 Freescale Semiconductor Inc.
51662 + *
51663 + * Redistribution and use in source and binary forms, with or without
51664 + * modification, are permitted provided that the following conditions are met:
51665 + * * Redistributions of source code must retain the above copyright
51666 + * notice, this list of conditions and the following disclaimer.
51667 + * * Redistributions in binary form must reproduce the above copyright
51668 + * notice, this list of conditions and the following disclaimer in the
51669 + * documentation and/or other materials provided with the distribution.
51670 + * * Neither the name of Freescale Semiconductor nor the
51671 + * names of its contributors may be used to endorse or promote products
51672 + * derived from this software without specific prior written permission.
51673 + *
51674 + *
51675 + * ALTERNATIVELY, this software may be distributed under the terms of the
51676 + * GNU General Public License ("GPL") as published by the Free Software
51677 + * Foundation, either version 2 of that License or (at your option) any
51678 + * later version.
51679 + *
51680 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51681 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51682 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51683 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51684 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51685 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51686 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51687 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51688 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51689 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51690 + */
51691 +
51692 +
51693 +/******************************************************************************
51694 + @File fm_port.c
51695 +
51696 + @Description FM driver routines implementation.
51697 + *//***************************************************************************/
51698 +#include "error_ext.h"
51699 +#include "std_ext.h"
51700 +#include "string_ext.h"
51701 +#include "sprint_ext.h"
51702 +#include "debug_ext.h"
51703 +#include "fm_muram_ext.h"
51704 +
51705 +#include "fman_common.h"
51706 +#include "fm_port.h"
51707 +#include "fm_port_dsar.h"
51708 +#include "common/general.h"
51709 +
51710 +/****************************************/
51711 +/* static functions */
51712 +/****************************************/
51713 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
51714 +
51715 +static t_Error CheckInitParameters(t_FmPort *p_FmPort)
51716 +{
51717 + t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
51718 + struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
51719 + t_Error ans = E_OK;
51720 + uint32_t unusedMask;
51721 +
51722 + if (p_FmPort->imEn)
51723 + {
51724 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51725 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51726 + > 2)
51727 + RETURN_ERROR(
51728 + MAJOR,
51729 + E_INVALID_VALUE,
51730 + ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
51731 +
51732 + if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
51733 + return ERROR_CODE(ans);
51734 + }
51735 + else
51736 + {
51737 + /****************************************/
51738 + /* Rx only */
51739 + /****************************************/
51740 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51741 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51742 + {
51743 + /* external buffer pools */
51744 + if (!p_Params->extBufPools.numOfPoolsUsed)
51745 + RETURN_ERROR(
51746 + MAJOR,
51747 + E_INVALID_VALUE,
51748 + ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
51749 +
51750 + if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
51751 + p_Params->p_BackupBmPools,
51752 + &p_Params->bufPoolDepletion) != E_OK)
51753 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
51754 +
51755 + /* Check that part of IC that needs copying is small enough to enter start margin */
51756 + if (p_Params->intContext.size
51757 + && (p_Params->intContext.size
51758 + + p_Params->intContext.extBufOffset
51759 + > p_Params->bufMargins.startMargins))
51760 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51761 + ("intContext.size is larger than start margins"));
51762 +
51763 + if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
51764 + && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
51765 + RETURN_ERROR(
51766 + MAJOR,
51767 + E_INVALID_VALUE,
51768 + ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
51769 +
51770 +#ifdef FM_NO_BACKUP_POOLS
51771 + if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
51772 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
51773 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
51774 +#endif /* FM_NO_BACKUP_POOLS */
51775 + }
51776 +
51777 + /****************************************/
51778 + /* Non Rx ports */
51779 + /****************************************/
51780 + else
51781 + {
51782 + if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
51783 + RETURN_ERROR(
51784 + MAJOR,
51785 + E_INVALID_VALUE,
51786 + (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
51787 +
51788 + /* to protect HW internal-context from overwrite */
51789 + if ((p_Params->intContext.size)
51790 + && (p_Params->intContext.intContextOffset
51791 + < MIN_TX_INT_OFFSET))
51792 + RETURN_ERROR(
51793 + MAJOR,
51794 + E_INVALID_VALUE,
51795 + ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
51796 +
51797 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
51798 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
51799 + /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
51800 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51801 + != DEFAULT_notSupported))
51802 + {
51803 + /* Check that not larger than 8 */
51804 + if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
51805 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51806 + > MAX_FIFO_PIPELINE_DEPTH))
51807 + RETURN_ERROR(
51808 + MAJOR,
51809 + E_INVALID_VALUE,
51810 + ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
51811 + }
51812 + }
51813 +
51814 + /****************************************/
51815 + /* Rx Or Offline Parsing */
51816 + /****************************************/
51817 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51818 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51819 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
51820 + {
51821 + if (!p_Params->dfltFqid)
51822 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51823 + ("dfltFqid must be between 1 and 2^24-1"));
51824 +#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
51825 + if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
51826 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
51827 +#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
51828 + }
51829 +
51830 + /****************************************/
51831 + /* All ports */
51832 + /****************************************/
51833 + /* common BMI registers values */
51834 + /* Check that Queue Id is not larger than 2^24, and is not 0 */
51835 + if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
51836 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51837 + ("errFqid must be between 1 and 2^24-1"));
51838 + if (p_Params->dfltFqid & ~0x00FFFFFF)
51839 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51840 + ("dfltFqid must be between 1 and 2^24-1"));
51841 + }
51842 +
51843 + /****************************************/
51844 + /* Rx only */
51845 + /****************************************/
51846 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51847 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51848 + {
51849 + if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
51850 + RETURN_ERROR(
51851 + MAJOR,
51852 + E_INVALID_VALUE,
51853 + ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
51854 + if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
51855 + || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
51856 + RETURN_ERROR(
51857 + MAJOR,
51858 + E_INVALID_VALUE,
51859 + ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51860 + if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
51861 + RETURN_ERROR(
51862 + MAJOR,
51863 + E_INVALID_VALUE,
51864 + ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
51865 + if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
51866 + || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
51867 + RETURN_ERROR(
51868 + MAJOR,
51869 + E_INVALID_VALUE,
51870 + ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51871 +
51872 + /* Check that not larger than 16 */
51873 + if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
51874 + RETURN_ERROR(
51875 + MAJOR,
51876 + E_INVALID_VALUE,
51877 + ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
51878 +
51879 + if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
51880 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
51881 +
51882 + /* extra FIFO size (allowed only to Rx ports) */
51883 + if (p_Params->setSizeOfFifo
51884 + && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
51885 + RETURN_ERROR(
51886 + MAJOR,
51887 + E_INVALID_VALUE,
51888 + ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
51889 +
51890 + if (p_Params->bufPoolDepletion.poolsGrpModeEnable
51891 + && !p_Params->bufPoolDepletion.numOfPools)
51892 + RETURN_ERROR(
51893 + MAJOR,
51894 + E_INVALID_VALUE,
51895 + ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
51896 +#ifdef FM_CSI_CFED_LIMIT
51897 + if (p_FmPort->fmRevInfo.majorRev == 4)
51898 + {
51899 + /* Check that not larger than 16 */
51900 + if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
51901 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
51902 + }
51903 +#endif /* FM_CSI_CFED_LIMIT */
51904 + }
51905 +
51906 + /****************************************/
51907 + /* Non Rx ports */
51908 + /****************************************/
51909 + /* extra FIFO size (allowed only to Rx ports) */
51910 + else
51911 + if (p_FmPort->fifoBufs.extra)
51912 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51913 + (" No fifoBufs.extra for non Rx ports"));
51914 +
51915 + /****************************************/
51916 + /* Tx only */
51917 + /****************************************/
51918 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
51919 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
51920 + {
51921 + if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
51922 + RETURN_ERROR(
51923 + MAJOR,
51924 + E_INVALID_VALUE,
51925 + ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
51926 + if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
51927 + RETURN_ERROR(
51928 + MAJOR,
51929 + E_INVALID_VALUE,
51930 + ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
51931 + if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
51932 + RETURN_ERROR(
51933 + MAJOR,
51934 + E_INVALID_VALUE,
51935 + ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
51936 + if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
51937 + || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
51938 + RETURN_ERROR(
51939 + MAJOR,
51940 + E_INVALID_VALUE,
51941 + ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51942 +
51943 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
51944 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51945 + > 2)
51946 + RETURN_ERROR(
51947 + MAJOR, E_INVALID_VALUE,
51948 + ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
51949 + }
51950 +
51951 + /****************************************/
51952 + /* Non Tx Ports */
51953 + /****************************************/
51954 + /* If discard override was selected , no frames may be discarded. */
51955 + else
51956 + if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
51957 + RETURN_ERROR(
51958 + MAJOR,
51959 + E_CONFLICT,
51960 + ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
51961 +
51962 + /****************************************/
51963 + /* Rx and Offline parsing */
51964 + /****************************************/
51965 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51966 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51967 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
51968 + {
51969 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
51970 + unusedMask = BMI_STATUS_OP_MASK_UNUSED;
51971 + else
51972 + unusedMask = BMI_STATUS_RX_MASK_UNUSED;
51973 +
51974 + /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
51975 + if (p_Params->errorsToDiscard & unusedMask)
51976 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
51977 + ("errorsToDiscard contains undefined bits"));
51978 + }
51979 +
51980 + /****************************************/
51981 + /* Offline Ports */
51982 + /****************************************/
51983 +#ifdef FM_OP_OPEN_DMA_MIN_LIMIT
51984 + if ((p_FmPort->fmRevInfo.majorRev >= 6)
51985 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
51986 + && p_Params->setNumOfOpenDmas
51987 + && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
51988 + RETURN_ERROR(
51989 + MAJOR,
51990 + E_INVALID_VALUE,
51991 + ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
51992 +#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
51993 +
51994 + /****************************************/
51995 + /* Offline & HC Ports */
51996 + /****************************************/
51997 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
51998 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
51999 + {
52000 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
52001 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
52002 + (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
52003 + /* this is an indication that user called config for this mode which is not supported in this integration */
52004 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
52005 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
52006 +
52007 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
52008 + if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
52009 + (p_FmPort->fmRevInfo.majorRev >= 6))) &&
52010 + (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
52011 + /* this is an indication that user called config for this mode which is not supported in this integration */
52012 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
52013 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
52014 + }
52015 +
52016 + /****************************************/
52017 + /* All ports */
52018 + /****************************************/
52019 + /* Check that not larger than 16 */
52020 + if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
52021 + && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
52022 + RETURN_ERROR(
52023 + MAJOR,
52024 + E_INVALID_VALUE,
52025 + ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
52026 +
52027 + if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
52028 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52029 +
52030 + /* common BMI registers values */
52031 + if (p_Params->setNumOfTasks
52032 + && ((!p_FmPort->tasks.num)
52033 + || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
52034 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52035 + ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
52036 + if (p_Params->setNumOfTasks
52037 + && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
52038 + RETURN_ERROR(
52039 + MAJOR,
52040 + E_INVALID_VALUE,
52041 + ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
52042 + if (p_Params->setNumOfOpenDmas
52043 + && ((!p_FmPort->openDmas.num)
52044 + || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
52045 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52046 + ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
52047 + if (p_Params->setNumOfOpenDmas
52048 + && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
52049 + RETURN_ERROR(
52050 + MAJOR,
52051 + E_INVALID_VALUE,
52052 + ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
52053 + if (p_Params->setSizeOfFifo
52054 + && (!p_FmPort->fifoBufs.num
52055 + || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
52056 + RETURN_ERROR(
52057 + MAJOR,
52058 + E_INVALID_VALUE,
52059 + ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52060 + if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
52061 + RETURN_ERROR(
52062 + MAJOR, E_INVALID_VALUE,
52063 + ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
52064 +
52065 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
52066 + if (p_FmPort->fmRevInfo.majorRev == 4)
52067 + if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
52068 + /* this is an indication that user called config for this mode which is not supported in this integration */
52069 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
52070 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
52071 +
52072 + return E_OK;
52073 +}
52074 +
52075 +static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
52076 +{
52077 + uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
52078 +
52079 + /*************************/
52080 + /* TX PORTS */
52081 + /*************************/
52082 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
52083 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
52084 + {
52085 + minFifoSizeRequired =
52086 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52087 + + (3 * BMI_FIFO_UNITS));
52088 + if (!p_FmPort->imEn)
52089 + minFifoSizeRequired +=
52090 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52091 + * BMI_FIFO_UNITS;
52092 +
52093 + optFifoSizeForB2B = minFifoSizeRequired;
52094 +
52095 + /* Add some margin for back-to-back capability to improve performance,
52096 + allows the hardware to pipeline new frame dma while the previous
52097 + frame not yet transmitted. */
52098 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52099 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
52100 + else
52101 + optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
52102 + }
52103 +
52104 + /*************************/
52105 + /* RX IM PORTS */
52106 + /*************************/
52107 + else
52108 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52109 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52110 + && p_FmPort->imEn)
52111 + {
52112 + optFifoSizeForB2B =
52113 + minFifoSizeRequired =
52114 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52115 + + (4 * BMI_FIFO_UNITS));
52116 + }
52117 +
52118 + /*************************/
52119 + /* RX non-IM PORTS */
52120 + /*************************/
52121 + else
52122 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52123 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52124 + && !p_FmPort->imEn)
52125 + {
52126 + if (p_FmPort->fmRevInfo.majorRev == 4)
52127 + {
52128 + if (p_FmPort->rxPoolsParams.numOfPools == 1)
52129 + minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
52130 + else
52131 + minFifoSizeRequired =
52132 + (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
52133 + + (7 * BMI_FIFO_UNITS));
52134 + }
52135 + else
52136 + {
52137 +#if (DPAA_VERSION >= 11)
52138 + minFifoSizeRequired =
52139 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52140 + + (5 * BMI_FIFO_UNITS));
52141 + /* 4 according to spec + 1 for FOF>0 */
52142 +#else
52143 + minFifoSizeRequired = (uint32_t)
52144 + (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
52145 + + (7*BMI_FIFO_UNITS));
52146 +#endif /* (DPAA_VERSION >= 11) */
52147 + }
52148 +
52149 + optFifoSizeForB2B = minFifoSizeRequired;
52150 +
52151 + /* Add some margin for back-to-back capability to improve performance,
52152 + allows the hardware to pipeline new frame dma while the previous
52153 + frame not yet transmitted. */
52154 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52155 + optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
52156 + else
52157 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
52158 + }
52159 +
52160 + /* For O/H ports, check fifo size and update if necessary */
52161 + else
52162 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52163 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
52164 + {
52165 +#if (DPAA_VERSION >= 11)
52166 + optFifoSizeForB2B =
52167 + minFifoSizeRequired =
52168 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52169 + + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52170 + + 5) * BMI_FIFO_UNITS));
52171 + /* 4 according to spec + 1 for FOF>0 */
52172 +#else
52173 + optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
52174 +#endif /* (DPAA_VERSION >= 11) */
52175 + }
52176 +
52177 + ASSERT_COND(minFifoSizeRequired > 0);
52178 + ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
52179 +
52180 + /* Verify the size */
52181 + if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
52182 + DBG(INFO,
52183 + ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
52184 + else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
52185 + DBG(INFO,
52186 + ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
52187 +
52188 + return E_OK;
52189 +}
52190 +
52191 +static void FmPortDriverParamFree(t_FmPort *p_FmPort)
52192 +{
52193 + if (p_FmPort->p_FmPortDriverParam)
52194 + {
52195 + XX_Free(p_FmPort->p_FmPortDriverParam);
52196 + p_FmPort->p_FmPortDriverParam = NULL;
52197 + }
52198 +}
52199 +
52200 +static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
52201 +{
52202 + t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
52203 + t_FmBufPoolDepletion *p_BufPoolDepletion =
52204 + &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
52205 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
52206 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
52207 + int i = 0, j = 0, err;
52208 + struct fman_port_bpools bpools;
52209 +
52210 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
52211 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
52212 + memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
52213 +
52214 + FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
52215 + sizesArray);
52216 +
52217 + /* Prepare flibs bpools structure */
52218 + memset(&bpools, 0, sizeof(struct fman_port_bpools));
52219 + bpools.count = p_ExtBufPools->numOfPoolsUsed;
52220 + bpools.counters_enable = TRUE;
52221 + for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
52222 + {
52223 + bpools.bpool[i].bpid = orderedArray[i];
52224 + bpools.bpool[i].size = sizesArray[orderedArray[i]];
52225 + /* functionality available only for some derivatives (limited by config) */
52226 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52227 + for (j = 0;
52228 + j
52229 + < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
52230 + j++)
52231 + if (orderedArray[i]
52232 + == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
52233 + {
52234 + bpools.bpool[i].is_backup = TRUE;
52235 + break;
52236 + }
52237 + }
52238 +
52239 + /* save pools parameters for later use */
52240 + p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
52241 + p_FmPort->rxPoolsParams.largestBufSize =
52242 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
52243 + p_FmPort->rxPoolsParams.secondLargestBufSize =
52244 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
52245 +
52246 + /* FMBM_RMPD reg. - pool depletion */
52247 + if (p_BufPoolDepletion->poolsGrpModeEnable)
52248 + {
52249 + bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
52250 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52251 + {
52252 + if (p_BufPoolDepletion->poolsToConsider[i])
52253 + {
52254 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52255 + {
52256 + if (i == orderedArray[j])
52257 + {
52258 + bpools.bpool[j].grp_bp_depleted = TRUE;
52259 + break;
52260 + }
52261 + }
52262 + }
52263 + }
52264 + }
52265 +
52266 + if (p_BufPoolDepletion->singlePoolModeEnable)
52267 + {
52268 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52269 + {
52270 + if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
52271 + {
52272 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52273 + {
52274 + if (i == orderedArray[j])
52275 + {
52276 + bpools.bpool[j].single_bp_depleted = TRUE;
52277 + break;
52278 + }
52279 + }
52280 + }
52281 + }
52282 + }
52283 +
52284 +#if (DPAA_VERSION >= 11)
52285 + /* fill QbbPEV */
52286 + if (p_BufPoolDepletion->poolsGrpModeEnable
52287 + || p_BufPoolDepletion->singlePoolModeEnable)
52288 + {
52289 + for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
52290 + {
52291 + if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
52292 + {
52293 + bpools.bpool[i].pfc_priorities_en = TRUE;
52294 + }
52295 + }
52296 + }
52297 +#endif /* (DPAA_VERSION >= 11) */
52298 +
52299 + /* Issue flibs function */
52300 + err = fman_port_set_bpools(&p_FmPort->port, &bpools);
52301 + if (err != 0)
52302 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
52303 +
52304 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52305 + XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
52306 +
52307 + return E_OK;
52308 +}
52309 +
52310 +static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
52311 +{
52312 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52313 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
52314 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
52315 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
52316 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
52317 + return E_OK;
52318 +}
52319 +
52320 +static t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
52321 +{
52322 + t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
52323 + struct fman_port_params portParams;
52324 + uint32_t tmpVal;
52325 + t_Error err;
52326 +
52327 + /* Set up flibs parameters and issue init function */
52328 +
52329 + memset(&portParams, 0, sizeof(struct fman_port_params));
52330 + portParams.discard_mask = p_DriverParams->errorsToDiscard;
52331 + portParams.dflt_fqid = p_DriverParams->dfltFqid;
52332 + portParams.err_fqid = p_DriverParams->errFqid;
52333 + portParams.deq_sp = p_DriverParams->deqSubPortal;
52334 + portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
52335 + switch (p_FmPort->portType)
52336 + {
52337 + case (e_FM_PORT_TYPE_RX_10G):
52338 + case (e_FM_PORT_TYPE_RX):
52339 + portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
52340 + if (!p_FmPort->imEn)
52341 + {
52342 + if (p_DriverParams->forwardReuseIntContext)
52343 + p_DriverParams->dfltCfg.rx_fd_bits =
52344 + (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
52345 + }
52346 + break;
52347 +
52348 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52349 + portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
52350 + break;
52351 + break;
52352 +
52353 + default:
52354 + break;
52355 + }
52356 +
52357 + tmpVal =
52358 + (uint32_t)(
52359 + (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
52360 + / OFFSET_UNITS + 1) :
52361 + (p_FmPort->internalBufferOffset / OFFSET_UNITS));
52362 + p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
52363 + p_DriverParams->dfltCfg.int_buf_start_margin =
52364 + p_FmPort->internalBufferOffset;
52365 +
52366 + p_DriverParams->dfltCfg.ext_buf_start_margin =
52367 + p_DriverParams->bufMargins.startMargins;
52368 + p_DriverParams->dfltCfg.ext_buf_end_margin =
52369 + p_DriverParams->bufMargins.endMargins;
52370 +
52371 + p_DriverParams->dfltCfg.ic_ext_offset =
52372 + p_DriverParams->intContext.extBufOffset;
52373 + p_DriverParams->dfltCfg.ic_int_offset =
52374 + p_DriverParams->intContext.intContextOffset;
52375 + p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
52376 +
52377 + p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
52378 + p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
52379 + p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
52380 +
52381 + p_DriverParams->dfltCfg.perf_cnt_params.task_val =
52382 + (uint8_t)p_FmPort->tasks.num;
52383 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
52384 + p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
52385 + else
52386 + p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
52387 + p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
52388 + (uint8_t)p_FmPort->openDmas.num;
52389 + p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
52390 +
52391 + if (0
52392 + != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
52393 + &portParams))
52394 + RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
52395 +
52396 + if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
52397 + RETURN_ERROR(MAJOR, err, NO_MSG);
52398 + else
52399 + {
52400 + // from QMIInit
52401 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52402 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52403 + {
52404 + if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
52405 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52406 + FALSE);
52407 + else
52408 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52409 + TRUE);
52410 + }
52411 + }
52412 + /* The code bellow is a trick so the FM will not release the buffer
52413 + to BM nor will try to enqueue the frame to QM */
52414 + if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52415 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
52416 + {
52417 + if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
52418 + {
52419 + /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
52420 + * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
52421 + * buffers to BM regardless of fmbm_tfene
52422 + */
52423 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
52424 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
52425 + NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
52426 + }
52427 + }
52428 +
52429 + return E_OK;
52430 +}
52431 +
52432 +static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52433 +{
52434 + UNUSED(p_FmPort);
52435 +
52436 + switch (counter)
52437 + {
52438 + case (e_FM_PORT_COUNTERS_CYCLE):
52439 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52440 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52441 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52442 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52443 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52444 + case (e_FM_PORT_COUNTERS_FRAME):
52445 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52446 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52447 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52448 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52449 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52450 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52451 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52452 + case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
52453 + return TRUE;
52454 + default:
52455 + return FALSE;
52456 + }
52457 +}
52458 +
52459 +static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52460 +{
52461 + UNUSED(p_FmPort);
52462 +
52463 + switch (counter)
52464 + {
52465 + case (e_FM_PORT_COUNTERS_CYCLE):
52466 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52467 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52468 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52469 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52470 + case (e_FM_PORT_COUNTERS_FRAME):
52471 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52472 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52473 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52474 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52475 + return TRUE;
52476 + default:
52477 + return FALSE;
52478 + }
52479 +}
52480 +
52481 +static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52482 +{
52483 + switch (counter)
52484 + {
52485 + case (e_FM_PORT_COUNTERS_CYCLE):
52486 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52487 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52488 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52489 + case (e_FM_PORT_COUNTERS_FRAME):
52490 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52491 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52492 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52493 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52494 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52495 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52496 + return TRUE;
52497 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52498 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
52499 + return FALSE;
52500 + else
52501 + return TRUE;
52502 + default:
52503 + return FALSE;
52504 + }
52505 +}
52506 +
52507 +static t_Error BmiPortCheckAndGetCounterType(
52508 + t_FmPort *p_FmPort, e_FmPortCounters counter,
52509 + enum fman_port_stats_counters *p_StatsType,
52510 + enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
52511 +{
52512 + volatile uint32_t *p_Reg;
52513 + bool isValid;
52514 +
52515 + switch (p_FmPort->portType)
52516 + {
52517 + case (e_FM_PORT_TYPE_RX_10G):
52518 + case (e_FM_PORT_TYPE_RX):
52519 + p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
52520 + isValid = CheckRxBmiCounter(p_FmPort, counter);
52521 + break;
52522 + case (e_FM_PORT_TYPE_TX_10G):
52523 + case (e_FM_PORT_TYPE_TX):
52524 + p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
52525 + isValid = CheckTxBmiCounter(p_FmPort, counter);
52526 + break;
52527 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52528 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
52529 + p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
52530 + isValid = CheckOhBmiCounter(p_FmPort, counter);
52531 + break;
52532 + default:
52533 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
52534 + }
52535 +
52536 + if (!isValid)
52537 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52538 + ("Requested counter is not available for this port type"));
52539 +
52540 + /* check that counters are enabled */
52541 + switch (counter)
52542 + {
52543 + case (e_FM_PORT_COUNTERS_CYCLE):
52544 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52545 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52546 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52547 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52548 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52549 + /* performance counters - may be read when disabled */
52550 + *p_IsStats = FALSE;
52551 + break;
52552 + case (e_FM_PORT_COUNTERS_FRAME):
52553 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52554 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52555 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52556 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52557 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52558 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52559 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52560 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52561 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52562 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52563 + *p_IsStats = TRUE;
52564 + if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
52565 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52566 + ("Requested counter was not enabled"));
52567 + break;
52568 + default:
52569 + break;
52570 + }
52571 +
52572 + /* Set counter */
52573 + switch (counter)
52574 + {
52575 + case (e_FM_PORT_COUNTERS_CYCLE):
52576 + *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
52577 + break;
52578 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52579 + *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
52580 + break;
52581 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52582 + *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
52583 + break;
52584 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52585 + *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
52586 + break;
52587 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52588 + *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
52589 + break;
52590 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52591 + *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
52592 + break;
52593 + case (e_FM_PORT_COUNTERS_FRAME):
52594 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
52595 + break;
52596 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52597 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
52598 + break;
52599 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52600 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
52601 + break;
52602 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52603 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
52604 + break;
52605 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52606 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
52607 + break;
52608 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52609 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
52610 + break;
52611 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52612 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
52613 + break;
52614 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52615 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
52616 + break;
52617 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52618 + *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
52619 + break;
52620 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52621 + *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
52622 + break;
52623 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52624 + *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
52625 + break;
52626 + default:
52627 + break;
52628 + }
52629 +
52630 + return E_OK;
52631 +}
52632 +
52633 +static t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
52634 + t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
52635 + uint32_t *p_SoftSeqAttachReg)
52636 +{
52637 + uint8_t hdrNum, Ipv4HdrNum;
52638 + u_FmPcdHdrPrsOpts *p_prsOpts;
52639 + uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
52640 +
52641 + if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
52642 + || IS_SPECIAL_HEADER(p_HdrParams->hdr))
52643 + RETURN_ERROR(
52644 + MAJOR, E_NOT_SUPPORTED,
52645 + ("No additional parameters for private or special headers."));
52646 +
52647 + if (p_HdrParams->errDisable)
52648 + tmpReg |= PRS_HDR_ERROR_DIS;
52649 +
52650 + /* Set parser options */
52651 + if (p_HdrParams->usePrsOpts)
52652 + {
52653 + p_prsOpts = &p_HdrParams->prsOpts;
52654 + switch (p_HdrParams->hdr)
52655 + {
52656 + case (HEADER_TYPE_MPLS):
52657 + if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
52658 + tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
52659 + hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
52660 + if (hdrNum == ILLEGAL_HDR_NUM)
52661 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52662 + Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
52663 + if (hdrNum < Ipv4HdrNum)
52664 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52665 + ("Header must be equal or higher than IPv4"));
52666 + tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
52667 + << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
52668 + break;
52669 + case (HEADER_TYPE_PPPoE):
52670 + if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
52671 + tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
52672 + break;
52673 + case (HEADER_TYPE_IPv6):
52674 + if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
52675 + tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
52676 + break;
52677 + case (HEADER_TYPE_TCP):
52678 + if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
52679 + tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
52680 + else
52681 + tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
52682 + break;
52683 + case (HEADER_TYPE_UDP):
52684 + if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
52685 + tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
52686 + else
52687 + tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
52688 + break;
52689 + default:
52690 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
52691 + }
52692 + }
52693 +
52694 + /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
52695 + if (p_HdrParams->swPrsEnable)
52696 + {
52697 + tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
52698 + p_HdrParams->indexPerHdr);
52699 + if (tmpPrsOffset == ILLEGAL_BASE)
52700 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52701 + tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
52702 + }
52703 + *p_SoftSeqAttachReg = tmpReg;
52704 +
52705 + return E_OK;
52706 +}
52707 +
52708 +static uint32_t GetPortSchemeBindParams(
52709 + t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
52710 +{
52711 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52712 + uint32_t walking1Mask = 0x80000000, tmp;
52713 + uint8_t idx = 0;
52714 +
52715 + p_SchemeBind->netEnvId = p_FmPort->netEnvId;
52716 + p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
52717 + p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
52718 + p_SchemeBind->numOfSchemes = 0;
52719 + tmp = p_FmPort->schemesPerPortVector;
52720 + if (tmp)
52721 + {
52722 + while (tmp)
52723 + {
52724 + if (tmp & walking1Mask)
52725 + {
52726 + p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
52727 + p_SchemeBind->numOfSchemes++;
52728 + tmp &= ~walking1Mask;
52729 + }
52730 + walking1Mask >>= 1;
52731 + idx++;
52732 + }
52733 + }
52734 +
52735 + return tmp;
52736 +}
52737 +
52738 +static void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
52739 +{
52740 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52741 + volatile uint32_t *p_BmiCfgReg = NULL;
52742 + uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
52743 + uint32_t lcv, walking1Mask = 0x80000000;
52744 + uint8_t cnt = 0;
52745 +
52746 + ASSERT_COND(p_FmPort);
52747 + ASSERT_COND(p_FmPort->h_FmPcd);
52748 + ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
52749 +
52750 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52751 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52752 + return;
52753 +
52754 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
52755 + /* get LCV for MACSEC */
52756 + if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
52757 + != 0)
52758 + {
52759 + while (!(lcv & walking1Mask))
52760 + {
52761 + cnt++;
52762 + walking1Mask >>= 1;
52763 + }
52764 +
52765 + macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
52766 + WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
52767 + }
52768 +}
52769 +
52770 +static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
52771 +{
52772 + t_Error err = E_OK;
52773 + uint32_t tmpReg;
52774 + volatile uint32_t *p_BmiNia = NULL;
52775 + volatile uint32_t *p_BmiPrsNia = NULL;
52776 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
52777 + volatile uint32_t *p_BmiInitPrsResult = NULL;
52778 + volatile uint32_t *p_BmiCcBase = NULL;
52779 + uint16_t hdrNum, L3HdrNum, greHdrNum;
52780 + int i;
52781 + bool isEmptyClsPlanGrp;
52782 + uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
52783 + uint16_t absoluteProfileId;
52784 + uint8_t physicalSchemeId;
52785 + uint32_t ccTreePhysOffset;
52786 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
52787 + uint32_t initialSwPrs = 0;
52788 +
52789 + ASSERT_COND(p_FmPort);
52790 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
52791 +
52792 + if (p_FmPort->imEn)
52793 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
52794 + ("available for non-independant mode ports only"));
52795 +
52796 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52797 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
52798 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
52799 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
52800 + ("available for Rx and offline parsing ports only"));
52801 +
52802 + p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
52803 +
52804 + p_FmPort->pcdEngines = 0;
52805 +
52806 + /* initialize p_FmPort->pcdEngines field in port's structure */
52807 + switch (p_PcdParams->pcdSupport)
52808 + {
52809 + case (e_FM_PORT_PCD_SUPPORT_NONE):
52810 + RETURN_ERROR(
52811 + MAJOR,
52812 + E_INVALID_STATE,
52813 + ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
52814 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
52815 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52816 + break;
52817 + case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
52818 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52819 + break;
52820 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
52821 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52822 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52823 + break;
52824 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
52825 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52826 + p_FmPort->pcdEngines |= FM_PCD_KG;
52827 + break;
52828 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
52829 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52830 + p_FmPort->pcdEngines |= FM_PCD_CC;
52831 + p_FmPort->pcdEngines |= FM_PCD_KG;
52832 + break;
52833 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
52834 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52835 + p_FmPort->pcdEngines |= FM_PCD_KG;
52836 + p_FmPort->pcdEngines |= FM_PCD_CC;
52837 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52838 + break;
52839 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
52840 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52841 + p_FmPort->pcdEngines |= FM_PCD_CC;
52842 + break;
52843 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
52844 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52845 + p_FmPort->pcdEngines |= FM_PCD_CC;
52846 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52847 + break;
52848 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
52849 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52850 + p_FmPort->pcdEngines |= FM_PCD_KG;
52851 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52852 + break;
52853 + case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
52854 + p_FmPort->pcdEngines |= FM_PCD_CC;
52855 + break;
52856 +#ifdef FM_CAPWAP_SUPPORT
52857 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
52858 + p_FmPort->pcdEngines |= FM_PCD_CC;
52859 + p_FmPort->pcdEngines |= FM_PCD_KG;
52860 + break;
52861 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
52862 + p_FmPort->pcdEngines |= FM_PCD_CC;
52863 + p_FmPort->pcdEngines |= FM_PCD_KG;
52864 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52865 + break;
52866 +#endif /* FM_CAPWAP_SUPPORT */
52867 +
52868 + default:
52869 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
52870 + }
52871 +
52872 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
52873 + && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
52874 + > FM_PCD_PRS_NUM_OF_HDRS))
52875 + RETURN_ERROR(
52876 + MAJOR,
52877 + E_INVALID_VALUE,
52878 + ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
52879 +
52880 + /* check that parameters exist for each and only each defined engine */
52881 + if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
52882 + || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
52883 + != !!p_PcdParams->p_KgParams)
52884 + || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
52885 + != !!p_PcdParams->p_CcParams))
52886 + RETURN_ERROR(
52887 + MAJOR,
52888 + E_INVALID_STATE,
52889 + ("PCD initialization structure is not consistent with pcdSupport"));
52890 +
52891 + /* get PCD registers pointers */
52892 + switch (p_FmPort->portType)
52893 + {
52894 + case (e_FM_PORT_TYPE_RX_10G):
52895 + case (e_FM_PORT_TYPE_RX):
52896 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
52897 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
52898 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
52899 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
52900 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
52901 + break;
52902 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52903 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
52904 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
52905 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
52906 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
52907 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
52908 + break;
52909 + default:
52910 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
52911 + }
52912 +
52913 + /* set PCD port parameter */
52914 + if (p_FmPort->pcdEngines & FM_PCD_CC)
52915 + {
52916 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
52917 + p_PcdParams->p_CcParams->h_CcTree,
52918 + &ccTreePhysOffset, p_FmPort);
52919 + if (err)
52920 + RETURN_ERROR(MAJOR, err, NO_MSG);
52921 +
52922 + WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
52923 + p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
52924 + }
52925 +
52926 + if (p_FmPort->pcdEngines & FM_PCD_KG)
52927 + {
52928 + if (p_PcdParams->p_KgParams->numOfSchemes == 0)
52929 + RETURN_ERROR(
52930 + MAJOR,
52931 + E_INVALID_VALUE,
52932 + ("For ports using Keygen, at least one scheme must be bound. "));
52933 +
52934 + err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
52935 + p_FmPort->hardwarePortId,
52936 + p_FmPort->netEnvId,
52937 + p_FmPort->optArray,
52938 + &p_FmPort->clsPlanGrpId,
52939 + &isEmptyClsPlanGrp);
52940 + if (err)
52941 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52942 + ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
52943 +
52944 + p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
52945 +
52946 + schemeBind.netEnvId = p_FmPort->netEnvId;
52947 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
52948 + schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
52949 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
52950 +
52951 + /* for each scheme */
52952 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
52953 + {
52954 + ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
52955 + physicalSchemeId = FmPcdKgGetSchemeId(
52956 + p_PcdParams->p_KgParams->h_Schemes[i]);
52957 + schemeBind.schemesIds[i] = physicalSchemeId;
52958 + /* build vector */
52959 + p_FmPort->schemesPerPortVector |= 1
52960 + << (31 - (uint32_t)physicalSchemeId);
52961 +#if (DPAA_VERSION >= 11)
52962 + /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
52963 + if !VSPE - in port, for relevant scheme VSPE can not be set*/
52964 + if (!p_FmPort->vspe
52965 + && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
52966 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
52967 + ("VSPE is not at port level"));
52968 +#endif /* (DPAA_VERSION >= 11) */
52969 + }
52970 +
52971 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
52972 + if (err)
52973 + RETURN_ERROR(MAJOR, err, NO_MSG);
52974 + }
52975 +
52976 + /***************************/
52977 + /* configure NIA after BMI */
52978 + /***************************/
52979 + /* rfne may contain FDCS bits, so first we read them. */
52980 + p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
52981 +
52982 + /* If policer is used directly after BMI or PRS */
52983 + if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
52984 + && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
52985 + || (p_PcdParams->pcdSupport
52986 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
52987 + {
52988 + if (!p_PcdParams->p_PlcrParams->h_Profile)
52989 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
52990 + ("Profile should be initialized"));
52991 +
52992 + absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
52993 + p_PcdParams->p_PlcrParams->h_Profile);
52994 +
52995 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
52996 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
52997 + ("Private port profile not valid."));
52998 +
52999 + tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
53000 +
53001 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
53002 + /* update BMI HPNIA */
53003 + WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
53004 + else
53005 + /* e_FM_PCD_SUPPORT_PLCR_ONLY */
53006 + /* update BMI NIA */
53007 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
53008 + }
53009 +
53010 + /* if CC is used directly after BMI */
53011 + if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
53012 +#ifdef FM_CAPWAP_SUPPORT
53013 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
53014 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
53015 +#endif /* FM_CAPWAP_SUPPORT */
53016 + )
53017 + {
53018 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53019 + RETURN_ERROR(
53020 + MAJOR,
53021 + E_INVALID_OPERATION,
53022 + ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
53023 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
53024 + /* check that prs start offset == RIM[FOF] */
53025 + }
53026 +
53027 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
53028 + {
53029 + ASSERT_COND(p_PcdParams->p_PrsParams);
53030 +#if (DPAA_VERSION >= 11)
53031 + if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
53032 + hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
53033 + else
53034 + {
53035 +#endif /* (DPAA_VERSION >= 11) */
53036 + /* if PRS is used it is always first */
53037 + hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
53038 + if (hdrNum == ILLEGAL_HDR_NUM)
53039 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
53040 +#if (DPAA_VERSION >= 11)
53041 + }
53042 +#endif /* (DPAA_VERSION >= 11) */
53043 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
53044 + /* set after parser NIA */
53045 + tmpReg = 0;
53046 + switch (p_PcdParams->pcdSupport)
53047 + {
53048 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
53049 + WRITE_UINT32(*p_BmiPrsNia,
53050 + GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
53051 + break;
53052 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
53053 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
53054 + tmpReg = NIA_KG_CC_EN;
53055 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
53056 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
53057 + if (p_PcdParams->p_KgParams->directScheme)
53058 + {
53059 + physicalSchemeId = FmPcdKgGetSchemeId(
53060 + p_PcdParams->p_KgParams->h_DirectScheme);
53061 + /* check that this scheme was bound to this port */
53062 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
53063 + if (p_PcdParams->p_KgParams->h_DirectScheme
53064 + == p_PcdParams->p_KgParams->h_Schemes[i])
53065 + break;
53066 + if (i == p_PcdParams->p_KgParams->numOfSchemes)
53067 + RETURN_ERROR(
53068 + MAJOR,
53069 + E_INVALID_VALUE,
53070 + ("Direct scheme is not one of the port selected schemes."));
53071 + tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
53072 + }
53073 + WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
53074 + break;
53075 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
53076 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
53077 + WRITE_UINT32(*p_BmiPrsNia,
53078 + (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
53079 + break;
53080 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
53081 + break;
53082 + default:
53083 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
53084 + }
53085 +
53086 + /* set start parsing offset */
53087 + WRITE_UINT32(*p_BmiPrsStartOffset,
53088 + p_PcdParams->p_PrsParams->parsingOffset);
53089 +
53090 + /************************************/
53091 + /* Parser port parameters */
53092 + /************************************/
53093 + /* stop before configuring */
53094 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
53095 + /* wait for parser to be in idle state */
53096 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
53097 + ;
53098 +
53099 + /* set soft seq attachment register */
53100 + memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
53101 +
53102 + /* set protocol options */
53103 + for (i = 0; p_FmPort->optArray[i]; i++)
53104 + switch (p_FmPort->optArray[i])
53105 + {
53106 + case (ETH_BROADCAST):
53107 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
53108 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
53109 + break;
53110 + case (ETH_MULTICAST):
53111 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
53112 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
53113 + break;
53114 + case (VLAN_STACKED):
53115 + hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
53116 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
53117 + break;
53118 + case (MPLS_STACKED):
53119 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
53120 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
53121 + break;
53122 + case (IPV4_BROADCAST_1):
53123 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53124 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
53125 + break;
53126 + case (IPV4_MULTICAST_1):
53127 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53128 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
53129 + break;
53130 + case (IPV4_UNICAST_2):
53131 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53132 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
53133 + break;
53134 + case (IPV4_MULTICAST_BROADCAST_2):
53135 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53136 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
53137 + break;
53138 + case (IPV6_MULTICAST_1):
53139 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53140 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
53141 + break;
53142 + case (IPV6_UNICAST_2):
53143 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53144 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
53145 + break;
53146 + case (IPV6_MULTICAST_2):
53147 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53148 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
53149 + break;
53150 + }
53151 +
53152 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53153 + HEADER_TYPE_UDP_ENCAP_ESP))
53154 + {
53155 + if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
53156 + RETURN_ERROR(
53157 + MINOR, E_INVALID_VALUE,
53158 + ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
53159 +
53160 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
53161 + HEADER_TYPE_UDP;
53162 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
53163 + TRUE;
53164 + p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
53165 + }
53166 +
53167 + /* set MPLS default next header - HW reset workaround */
53168 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
53169 + tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
53170 + L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
53171 + tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
53172 +
53173 + /* for GRE, disable errors */
53174 + greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
53175 + tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
53176 +
53177 + /* For UDP remove PAD from L4 checksum calculation */
53178 + hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
53179 + tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
53180 + /* For TCP remove PAD from L4 checksum calculation */
53181 + hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
53182 + tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
53183 +
53184 + /* config additional params for specific headers */
53185 + for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
53186 + i++)
53187 + {
53188 + /* case for using sw parser as the initial NIA address, before
53189 + * HW parsing
53190 + */
53191 + if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
53192 + p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
53193 + {
53194 + initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
53195 + p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
53196 + if (initialSwPrs == ILLEGAL_BASE)
53197 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53198 +
53199 + /* clear parser first HXS */
53200 + p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
53201 + /* rewrite with soft parser start */
53202 + p_FmPort->savedBmiNia |= initialSwPrs;
53203 + continue;
53204 + }
53205 +
53206 + hdrNum =
53207 + GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
53208 + if (hdrNum == ILLEGAL_HDR_NUM)
53209 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53210 + if (hdrNum == NO_HDR_NUM)
53211 + RETURN_ERROR(
53212 + MAJOR, E_INVALID_VALUE,
53213 + ("Private headers may not use additional parameters"));
53214 +
53215 + err = AdditionalPrsParams(
53216 + p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
53217 + &tmpHxs[hdrNum]);
53218 + if (err)
53219 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53220 + }
53221 +
53222 + /* Check if ip-reassembly port - need to link sw-parser code */
53223 + if (p_FmPort->h_IpReassemblyManip)
53224 + {
53225 + /* link to sw parser code for IP Frag - only if no other code is applied. */
53226 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53227 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53228 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
53229 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53230 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53231 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL);
53232 + } else {
53233 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
53234 + {
53235 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53236 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53237 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53238 + } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53239 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
53240 + {
53241 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53242 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53243 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53244 + }
53245 + }
53246 +
53247 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
53248 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53249 + HEADER_TYPE_UDP_LITE))
53250 + {
53251 + /* link to sw parser code for udp lite - only if no other code is applied. */
53252 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53253 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53254 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
53255 + }
53256 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
53257 + for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
53258 + {
53259 + /* For all header set LCV as taken from netEnv*/
53260 + WRITE_UINT32(
53261 + p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
53262 + FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
53263 + /* set HXS register according to default+Additional params+protocol options */
53264 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
53265 + tmpHxs[i]);
53266 + }
53267 +
53268 + /* set tpid. */
53269 + tmpReg = PRS_TPID_DFLT;
53270 + if (p_PcdParams->p_PrsParams->setVlanTpid1)
53271 + {
53272 + tmpReg &= PRS_TPID2_MASK;
53273 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
53274 + << PRS_PCTPID_SHIFT;
53275 + }
53276 + if (p_PcdParams->p_PrsParams->setVlanTpid2)
53277 + {
53278 + tmpReg &= PRS_TPID1_MASK;
53279 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
53280 + }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
53281 +
53282 + /* enable parser */
53283 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
53284 +
53285 + if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
53286 + p_FmPort->privateInfo =
53287 + p_PcdParams->p_PrsParams->prsResultPrivateInfo;
53288 +
53289 + } /* end parser */
53290 + else {
53291 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53292 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53293 + {
53294 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53295 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
53296 + (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
53297 + }
53298 +
53299 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53300 +
53301 + p_FmPort->privateInfo = 0;
53302 + }
53303 +
53304 + FmPortCheckNApplyMacsec(p_FmPort);
53305 +
53306 + WRITE_UINT32(
53307 + *p_BmiPrsStartOffset,
53308 + GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
53309 +
53310 + /* set initial parser result - used for all engines */
53311 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
53312 + {
53313 + if (!i)
53314 + WRITE_UINT32(
53315 + *(p_BmiInitPrsResult),
53316 + (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
53317 + else
53318 + {
53319 + if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
53320 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
53321 + else
53322 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
53323 + }
53324 + }
53325 +
53326 + return E_OK;
53327 +}
53328 +
53329 +static t_Error DeletePcd(t_FmPort *p_FmPort)
53330 +{
53331 + t_Error err = E_OK;
53332 + volatile uint32_t *p_BmiNia = NULL;
53333 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53334 +
53335 + ASSERT_COND(p_FmPort);
53336 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53337 +
53338 + if (p_FmPort->imEn)
53339 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53340 + ("available for non-independant mode ports only"));
53341 +
53342 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
53343 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
53344 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53345 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53346 + ("available for Rx and offline parsing ports only"));
53347 +
53348 + if (!p_FmPort->pcdEngines)
53349 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
53350 +
53351 + /* get PCD registers pointers */
53352 + switch (p_FmPort->portType)
53353 + {
53354 + case (e_FM_PORT_TYPE_RX_10G):
53355 + case (e_FM_PORT_TYPE_RX):
53356 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53357 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53358 + break;
53359 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53360 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53361 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53362 + break;
53363 + default:
53364 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53365 + }
53366 +
53367 + if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53368 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53369 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53370 + ("port has to be detached previousely"));
53371 +
53372 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53373 +
53374 + /* "cut" PCD out of the port's flow - go to BMI */
53375 + /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
53376 +
53377 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
53378 + {
53379 + /* stop parser */
53380 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
53381 + /* wait for parser to be in idle state */
53382 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
53383 + ;
53384 + }
53385 +
53386 + if (p_FmPort->pcdEngines & FM_PCD_KG)
53387 + {
53388 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
53389 +
53390 + /* unbind all schemes */
53391 + p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
53392 + &schemeBind);
53393 +
53394 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
53395 + if (err)
53396 + RETURN_ERROR(MAJOR, err, NO_MSG);
53397 +
53398 + err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
53399 + p_FmPort->hardwarePortId,
53400 + p_FmPort->clsPlanGrpId);
53401 + if (err)
53402 + RETURN_ERROR(MAJOR, err, NO_MSG);
53403 + p_FmPort->useClsPlan = FALSE;
53404 + }
53405 +
53406 + if (p_FmPort->pcdEngines & FM_PCD_CC)
53407 + {
53408 + /* unbind - we need to get the treeId too */
53409 + err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
53410 + if (err)
53411 + RETURN_ERROR(MAJOR, err, NO_MSG);
53412 + }
53413 +
53414 + p_FmPort->pcdEngines = 0;
53415 +
53416 + return E_OK;
53417 +}
53418 +
53419 +static t_Error AttachPCD(t_FmPort *p_FmPort)
53420 +{
53421 + volatile uint32_t *p_BmiNia = NULL;
53422 +
53423 + ASSERT_COND(p_FmPort);
53424 +
53425 + /* get PCD registers pointers */
53426 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53427 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53428 + else
53429 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53430 +
53431 + /* check that current NIA is BMI to BMI */
53432 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
53433 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53434 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53435 + ("may be called only for ports in BMI-to-BMI state."));
53436 +
53437 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53438 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
53439 + p_FmPort->orFmanCtrl) != E_OK)
53440 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53441 +
53442 + if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
53443 + {
53444 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53445 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
53446 + p_FmPort->savedBmiCmne);
53447 + else
53448 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
53449 + p_FmPort->savedBmiCmne);
53450 + }
53451 +
53452 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53453 + WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
53454 + p_FmPort->savedQmiPnen);
53455 +
53456 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53457 + {
53458 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53459 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53460 + p_FmPort->savedBmiFene);
53461 + else
53462 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53463 + p_FmPort->savedBmiFene);
53464 + }
53465 +
53466 + if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
53467 + {
53468 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53469 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
53470 + p_FmPort->savedBmiFpne);
53471 + else
53472 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
53473 + p_FmPort->savedBmiFpne);
53474 + }
53475 +
53476 + if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
53477 + {
53478 + ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
53479 +
53480 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
53481 + p_FmPort->savedBmiOfp);
53482 + }
53483 +
53484 + WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
53485 +
53486 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53487 + {
53488 + p_FmPort->origNonRxQmiRegsPndn =
53489 + GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
53490 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53491 + p_FmPort->savedNonRxQmiRegsPndn);
53492 + }
53493 +
53494 + return E_OK;
53495 +}
53496 +
53497 +static t_Error DetachPCD(t_FmPort *p_FmPort)
53498 +{
53499 + volatile uint32_t *p_BmiNia = NULL;
53500 +
53501 + ASSERT_COND(p_FmPort);
53502 +
53503 + /* get PCD registers pointers */
53504 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53505 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53506 + p_FmPort->origNonRxQmiRegsPndn);
53507 +
53508 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53509 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53510 + else
53511 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53512 +
53513 + WRITE_UINT32(
53514 + *p_BmiNia,
53515 + (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
53516 +
53517 + if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
53518 + FmPcdHcSync(p_FmPort->h_FmPcd);
53519 +
53520 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53521 + {
53522 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53523 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53524 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53525 + else
53526 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53527 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53528 + }
53529 +
53530 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53531 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
53532 + NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
53533 +
53534 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53535 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
53536 + p_FmPort->orFmanCtrl) != E_OK)
53537 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53538 +
53539 + p_FmPort->requiredAction = 0;
53540 +
53541 + return E_OK;
53542 +}
53543 +
53544 +/*****************************************************************************/
53545 +/* Inter-module API routines */
53546 +/*****************************************************************************/
53547 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
53548 +{
53549 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53550 + volatile uint32_t *p_BmiCfgReg = NULL;
53551 + uint32_t tmpReg;
53552 +
53553 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
53554 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53555 +
53556 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
53557 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
53558 + {
53559 + REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
53560 + return;
53561 + }
53562 +
53563 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
53564 + tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
53565 + tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
53566 + tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
53567 + & BMI_CMD_ATTR_MACCMD_SC_MASK);
53568 +
53569 + WRITE_UINT32(*p_BmiCfgReg, tmpReg);
53570 +}
53571 +
53572 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
53573 +{
53574 + return ((t_FmPort*)h_FmPort)->netEnvId;
53575 +}
53576 +
53577 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
53578 +{
53579 + return ((t_FmPort*)h_FmPort)->hardwarePortId;
53580 +}
53581 +
53582 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
53583 +{
53584 + return ((t_FmPort*)h_FmPort)->pcdEngines;
53585 +}
53586 +
53587 +#if (DPAA_VERSION >= 11)
53588 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
53589 + void **p_Value)
53590 +{
53591 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53592 + uint32_t muramPageOffset;
53593 +
53594 + ASSERT_COND(p_FmPort);
53595 + ASSERT_COND(p_Value);
53596 +
53597 + if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
53598 + {
53599 + if (p_FmPort->gprFunc != gprFunc)
53600 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53601 + ("gpr was assigned with different func"));
53602 + }
53603 + else
53604 + {
53605 + switch (gprFunc)
53606 + {
53607 + case (e_FM_PORT_GPR_MURAM_PAGE):
53608 + p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
53609 + 256, 8);
53610 + if (!p_FmPort->p_ParamsPage)
53611 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
53612 +
53613 + IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
53614 + muramPageOffset =
53615 + (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
53616 + - p_FmPort->fmMuramPhysBaseAddr);
53617 + switch (p_FmPort->portType)
53618 + {
53619 + case (e_FM_PORT_TYPE_RX_10G):
53620 + case (e_FM_PORT_TYPE_RX):
53621 + WRITE_UINT32(
53622 + p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
53623 + muramPageOffset);
53624 + break;
53625 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53626 + WRITE_UINT32(
53627 + p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
53628 + muramPageOffset);
53629 + break;
53630 + default:
53631 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53632 + ("Invalid port type"));
53633 + }
53634 + break;
53635 + default:
53636 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53637 + }
53638 + p_FmPort->gprFunc = gprFunc;
53639 + }
53640 +
53641 + switch (p_FmPort->gprFunc)
53642 + {
53643 + case (e_FM_PORT_GPR_MURAM_PAGE):
53644 + *p_Value = p_FmPort->p_ParamsPage;
53645 + break;
53646 + default:
53647 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53648 + }
53649 +
53650 + return E_OK;
53651 +}
53652 +#endif /* (DPAA_VERSION >= 11) */
53653 +
53654 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort,
53655 + t_FmPortGetSetCcParams *p_CcParams)
53656 +{
53657 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53658 + int tmpInt;
53659 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53660 +
53661 + /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
53662 +
53663 + if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
53664 + && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
53665 + {
53666 + p_CcParams->getCcParams.prOffset =
53667 + (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
53668 + p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
53669 + }
53670 + if (p_CcParams->getCcParams.type & HW_PORT_ID)
53671 + {
53672 + p_CcParams->getCcParams.hardwarePortId =
53673 + (uint8_t)p_FmPort->hardwarePortId;
53674 + p_CcParams->getCcParams.type &= ~HW_PORT_ID;
53675 + }
53676 + if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
53677 + && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
53678 + {
53679 + p_CcParams->getCcParams.dataOffset =
53680 + (uint16_t)p_FmPort->bufferOffsets.dataOffset;
53681 + p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
53682 + }
53683 + if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
53684 + {
53685 + p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
53686 + p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
53687 + }
53688 + if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
53689 + {
53690 + p_CcParams->getCcParams.numOfExtraTasks =
53691 + (uint8_t)p_FmPort->tasks.extra;
53692 + p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
53693 + }
53694 + if (p_CcParams->getCcParams.type & FM_REV)
53695 + {
53696 + p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
53697 + p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
53698 + p_CcParams->getCcParams.type &= ~FM_REV;
53699 + }
53700 + if (p_CcParams->getCcParams.type & DISCARD_MASK)
53701 + {
53702 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53703 + p_CcParams->getCcParams.discardMask =
53704 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
53705 + else
53706 + p_CcParams->getCcParams.discardMask =
53707 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
53708 + p_CcParams->getCcParams.type &= ~DISCARD_MASK;
53709 + }
53710 + if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
53711 + {
53712 + p_CcParams->getCcParams.internalBufferOffset =
53713 + p_FmPort->internalBufferOffset;
53714 + p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE;
53715 + }
53716 + if (p_CcParams->getCcParams.type & GET_NIA_FPNE)
53717 + {
53718 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53719 + p_CcParams->getCcParams.nia =
53720 + GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne);
53721 + else
53722 + p_CcParams->getCcParams.nia =
53723 + GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne);
53724 + p_CcParams->getCcParams.type &= ~GET_NIA_FPNE;
53725 + }
53726 + if (p_CcParams->getCcParams.type & GET_NIA_PNDN)
53727 + {
53728 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53729 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53730 + p_CcParams->getCcParams.nia =
53731 + GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn);
53732 + p_CcParams->getCcParams.type &= ~GET_NIA_PNDN;
53733 + }
53734 +
53735 + if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53736 + && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
53737 + {
53738 + p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
53739 + p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl;
53740 + }
53741 +
53742 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53743 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
53744 + {
53745 + p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
53746 + p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
53747 + }
53748 + else
53749 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53750 + {
53751 + if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
53752 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53753 + ("PNEN was defined previously different"));
53754 + }
53755 +
53756 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
53757 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
53758 + {
53759 + p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
53760 + p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
53761 + }
53762 + else
53763 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
53764 + {
53765 + if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
53766 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53767 + ("PNDN was defined previously different"));
53768 + }
53769 +
53770 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
53771 + && (p_CcParams->setCcParams.overwrite
53772 + || !(p_FmPort->requiredAction & UPDATE_NIA_FENE)))
53773 + {
53774 + p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia;
53775 + p_FmPort->requiredAction |= UPDATE_NIA_FENE;
53776 + }
53777 + else
53778 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
53779 + {
53780 + if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia)
53781 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53782 + ("xFENE was defined previously different"));
53783 + }
53784 +
53785 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
53786 + && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE))
53787 + {
53788 + p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia;
53789 + p_FmPort->requiredAction |= UPDATE_NIA_FPNE;
53790 + }
53791 + else
53792 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
53793 + {
53794 + if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia)
53795 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53796 + ("xFPNE was defined previously different"));
53797 + }
53798 +
53799 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
53800 + && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE))
53801 + {
53802 + p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia;
53803 + p_FmPort->requiredAction |= UPDATE_NIA_CMNE;
53804 + }
53805 + else
53806 + if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
53807 + {
53808 + if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia)
53809 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53810 + ("xCMNE was defined previously different"));
53811 + }
53812 +
53813 + if ((p_CcParams->setCcParams.type & UPDATE_PSO)
53814 + && !(p_FmPort->requiredAction & UPDATE_PSO))
53815 + {
53816 + /* get PCD registers pointers */
53817 + switch (p_FmPort->portType)
53818 + {
53819 + case (e_FM_PORT_TYPE_RX_10G):
53820 + case (e_FM_PORT_TYPE_RX):
53821 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53822 + break;
53823 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53824 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53825 + break;
53826 + default:
53827 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53828 + }
53829 +
53830 + /* set start parsing offset */
53831 + tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)
53832 + + p_CcParams->setCcParams.psoSize;
53833 + if (tmpInt > 0)
53834 + WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
53835 +
53836 + p_FmPort->requiredAction |= UPDATE_PSO;
53837 + p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
53838 + }
53839 + else
53840 + if (p_CcParams->setCcParams.type & UPDATE_PSO)
53841 + {
53842 + if (p_FmPort->savedPrsStartOffset
53843 + != p_CcParams->setCcParams.psoSize)
53844 + RETURN_ERROR(
53845 + MAJOR,
53846 + E_INVALID_STATE,
53847 + ("parser start offset was defoned previousley different"));
53848 + }
53849 +
53850 + if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE)
53851 + && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE))
53852 + {
53853 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53854 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53855 + p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp);
53856 + p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK;
53857 + p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde
53858 + << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
53859 + p_FmPort->requiredAction |= UPDATE_OFP_DPTE;
53860 + }
53861 +
53862 + return E_OK;
53863 +}
53864 +/*********************** End of inter-module routines ************************/
53865 +
53866 +/****************************************/
53867 +/* API Init unit functions */
53868 +/****************************************/
53869 +
53870 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
53871 +{
53872 + t_FmPort *p_FmPort;
53873 + uintptr_t baseAddr = p_FmPortParams->baseAddr;
53874 + uint32_t tmpReg;
53875 +
53876 + /* Allocate FM structure */
53877 + p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort));
53878 + if (!p_FmPort)
53879 + {
53880 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
53881 + return NULL;
53882 + }
53883 + memset(p_FmPort, 0, sizeof(t_FmPort));
53884 +
53885 + /* Allocate the FM driver's parameters structure */
53886 + p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(
53887 + sizeof(t_FmPortDriverParam));
53888 + if (!p_FmPort->p_FmPortDriverParam)
53889 + {
53890 + XX_Free(p_FmPort);
53891 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
53892 + return NULL;
53893 + }
53894 + memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
53895 +
53896 + /* Initialize FM port parameters which will be kept by the driver */
53897 + p_FmPort->portType = p_FmPortParams->portType;
53898 + p_FmPort->portId = p_FmPortParams->portId;
53899 + p_FmPort->pcdEngines = FM_PCD_NONE;
53900 + p_FmPort->f_Exception = p_FmPortParams->f_Exception;
53901 + p_FmPort->h_App = p_FmPortParams->h_App;
53902 + p_FmPort->h_Fm = p_FmPortParams->h_Fm;
53903 +
53904 + /* get FM revision */
53905 + FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo);
53906 +
53907 + /* calculate global portId number */
53908 + p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType,
53909 + p_FmPortParams->portId,
53910 + p_FmPort->fmRevInfo.majorRev,
53911 + p_FmPort->fmRevInfo.minorRev);
53912 +
53913 + if (p_FmPort->fmRevInfo.majorRev >= 6)
53914 + {
53915 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
53916 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
53917 + DBG(WARNING,
53918 + ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.",
53919 + FM_OH_PORT_ID));
53920 +
53921 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53922 + && (p_FmPortParams->portId == FM_OH_PORT_ID))
53923 + DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0."));
53924 + }
53925 +
53926 + /* Set up FM port parameters for initialization phase only */
53927 +
53928 + /* First, fill in flibs struct */
53929 + fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg,
53930 + (enum fman_port_type)p_FmPort->portType);
53931 + /* Overwrite some integration specific parameters */
53932 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation =
53933 + DEFAULT_PORT_rxFifoPriElevationLevel;
53934 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr =
53935 + DEFAULT_PORT_rxFifoThreshold;
53936 +
53937 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
53938 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE;
53939 +#else
53940 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE;
53941 +#endif
53942 + if ((p_FmPort->fmRevInfo.majorRev == 6)
53943 + && (p_FmPort->fmRevInfo.minorRev == 0))
53944 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE;
53945 + else
53946 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE;
53947 +
53948 + /* Excessive Threshold register - exists for pre-FMv3 chips only */
53949 + if (p_FmPort->fmRevInfo.majorRev < 6)
53950 + {
53951 +#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC
53952 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
53953 + TRUE;
53954 +#endif
53955 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE;
53956 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE;
53957 + }
53958 + else
53959 + {
53960 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
53961 + FALSE;
53962 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE;
53963 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE;
53964 + }
53965 + if (p_FmPort->fmRevInfo.majorRev == 4)
53966 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE;
53967 + else
53968 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE;
53969 +
53970 + /* Continue with other parameters */
53971 + p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
53972 + /* set memory map pointers */
53973 + p_FmPort->p_FmPortQmiRegs =
53974 + (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET);
53975 + p_FmPort->p_FmPortBmiRegs =
53976 + (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET);
53977 + p_FmPort->p_FmPortPrsRegs =
53978 + (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET);
53979 +
53980 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize =
53981 + DEFAULT_PORT_bufferPrefixContent_privDataSize;
53982 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult =
53983 + DEFAULT_PORT_bufferPrefixContent_passPrsResult;
53984 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp =
53985 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
53986 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo =
53987 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
53988 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
53989 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
53990 + /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData;
53991 + p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr;
53992 + p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr;
53993 + p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr;
53994 + p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize;
53995 + */
53996 + p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
53997 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore =
53998 + DEFAULT_PORT_cheksumLastBytesIgnore;
53999 +
54000 + p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength;
54001 + /* resource distribution. */
54002 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)
54003 + * BMI_FIFO_UNITS;
54004 + p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs
54005 + * BMI_FIFO_UNITS;
54006 + p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
54007 + p_FmPort->openDmas.extra =
54008 + DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
54009 + p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
54010 + p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
54011 +
54012 +
54013 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
54014 + if ((p_FmPort->fmRevInfo.majorRev == 6)
54015 + && (p_FmPort->fmRevInfo.minorRev == 0)
54016 + && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54017 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)))
54018 + {
54019 + p_FmPort->openDmas.num = 16;
54020 + p_FmPort->openDmas.extra = 0;
54021 + }
54022 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
54023 +
54024 + /* Port type specific initialization: */
54025 + switch (p_FmPort->portType)
54026 + {
54027 + case (e_FM_PORT_TYPE_RX):
54028 + case (e_FM_PORT_TYPE_RX_10G):
54029 + /* Initialize FM port parameters for initialization phase only */
54030 + p_FmPort->p_FmPortDriverParam->cutBytesFromEnd =
54031 + DEFAULT_PORT_cutBytesFromEnd;
54032 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
54033 + p_FmPort->p_FmPortDriverParam->frmDiscardOverride =
54034 + DEFAULT_PORT_frmDiscardOverride;
54035 +
54036 + tmpReg =
54037 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp);
54038 + p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel =
54039 + (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK)
54040 + >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1)
54041 + * BMI_FIFO_UNITS;
54042 + p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg
54043 + & BMI_RX_FIFO_THRESHOLD_MASK)
54044 + >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS;
54045 +
54046 + p_FmPort->p_FmPortDriverParam->bufMargins.endMargins =
54047 + DEFAULT_PORT_BufMargins_endMargins;
54048 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
54049 + DEFAULT_PORT_errorsToDiscard;
54050 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext =
54051 + DEFAULT_PORT_forwardIntContextReuse;
54052 +#if (DPAA_VERSION >= 11)
54053 + p_FmPort->p_FmPortDriverParam->noScatherGather =
54054 + DEFAULT_PORT_noScatherGather;
54055 +#endif /* (DPAA_VERSION >= 11) */
54056 + break;
54057 +
54058 + case (e_FM_PORT_TYPE_TX):
54059 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
54060 +#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
54061 + tmpReg = 0x00001013;
54062 + WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp,
54063 + tmpReg);
54064 +#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */
54065 + case (e_FM_PORT_TYPE_TX_10G):
54066 + tmpReg =
54067 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp);
54068 + p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg
54069 + & BMI_TX_FIFO_MIN_FILL_MASK)
54070 + >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS;
54071 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54072 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
54073 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
54074 + p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg
54075 + & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1)
54076 + * BMI_FIFO_UNITS;
54077 +
54078 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
54079 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
54080 + DEFAULT_PORT_deqPrefetchOption;
54081 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
54082 + (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G :
54083 + DEFAULT_PORT_deqHighPriority_10G);
54084 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
54085 + (uint16_t)(
54086 + (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G :
54087 + DEFAULT_PORT_deqByteCnt_10G);
54088 + break;
54089 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54090 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
54091 + DEFAULT_PORT_errorsToDiscard;
54092 +#if (DPAA_VERSION >= 11)
54093 + p_FmPort->p_FmPortDriverParam->noScatherGather =
54094 + DEFAULT_PORT_noScatherGather;
54095 +#endif /* (DPAA_VERSION >= 11) */
54096 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54097 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
54098 + DEFAULT_PORT_deqPrefetchOption_HC;
54099 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
54100 + DEFAULT_PORT_deqHighPriority_1G;
54101 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
54102 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
54103 + DEFAULT_PORT_deqByteCnt_1G;
54104 +
54105 + tmpReg =
54106 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp);
54107 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54108 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
54109 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
54110 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
54111 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
54112 + {
54113 + /* Overwrite HC defaults */
54114 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54115 + DEFAULT_PORT_fifoDeqPipelineDepth_OH;
54116 + }
54117 +
54118 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
54119 + if (p_FmPort->fmRevInfo.majorRev < 6)
54120 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported;
54121 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
54122 +
54123 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
54124 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54125 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54126 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported;
54127 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54128 + break;
54129 +
54130 + default:
54131 + XX_Free(p_FmPort->p_FmPortDriverParam);
54132 + XX_Free(p_FmPort);
54133 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54134 + return NULL;
54135 + }
54136 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
54137 + if (p_FmPort->fmRevInfo.majorRev == 4)
54138 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported;
54139 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
54140 +
54141 + p_FmPort->imEn = p_FmPortParams->independentModeEnable;
54142 +
54143 + if (p_FmPort->imEn)
54144 + {
54145 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
54146 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
54147 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54148 + DEFAULT_PORT_fifoDeqPipelineDepth_IM;
54149 + FmPortConfigIM(p_FmPort, p_FmPortParams);
54150 + }
54151 + else
54152 + {
54153 + switch (p_FmPort->portType)
54154 + {
54155 + case (e_FM_PORT_TYPE_RX):
54156 + case (e_FM_PORT_TYPE_RX_10G):
54157 + /* Initialize FM port parameters for initialization phase only */
54158 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54159 + &p_FmPortParams->specificParams.rxParams.extBufPools,
54160 + sizeof(t_FmExtPools));
54161 + p_FmPort->p_FmPortDriverParam->errFqid =
54162 + p_FmPortParams->specificParams.rxParams.errFqid;
54163 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54164 + p_FmPortParams->specificParams.rxParams.dfltFqid;
54165 + p_FmPort->p_FmPortDriverParam->liodnOffset =
54166 + p_FmPortParams->specificParams.rxParams.liodnOffset;
54167 + break;
54168 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54169 + case (e_FM_PORT_TYPE_TX):
54170 + case (e_FM_PORT_TYPE_TX_10G):
54171 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54172 + p_FmPort->p_FmPortDriverParam->errFqid =
54173 + p_FmPortParams->specificParams.nonRxParams.errFqid;
54174 + p_FmPort->p_FmPortDriverParam->deqSubPortal =
54175 + (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel
54176 + & QMI_DEQ_CFG_SUBPORTAL_MASK);
54177 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54178 + p_FmPortParams->specificParams.nonRxParams.dfltFqid;
54179 + break;
54180 + default:
54181 + XX_Free(p_FmPort->p_FmPortDriverParam);
54182 + XX_Free(p_FmPort);
54183 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54184 + return NULL;
54185 + }
54186 + }
54187 +
54188 + memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
54189 + if (Sprint(
54190 + p_FmPort->name,
54191 + "FM-%d-port-%s-%d",
54192 + FmGetId(p_FmPort->h_Fm),
54193 + ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING
54194 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" :
54195 + (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" :
54196 + (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" :
54197 + (p_FmPort->portType
54198 + == e_FM_PORT_TYPE_RX_10G ? "10g-RX" :
54199 + "10g-TX")))),
54200 + p_FmPort->portId) == 0)
54201 + {
54202 + XX_Free(p_FmPort->p_FmPortDriverParam);
54203 + XX_Free(p_FmPort);
54204 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54205 + return NULL;
54206 + }
54207 +
54208 + p_FmPort->h_Spinlock = XX_InitSpinlock();
54209 + if (!p_FmPort->h_Spinlock)
54210 + {
54211 + XX_Free(p_FmPort->p_FmPortDriverParam);
54212 + XX_Free(p_FmPort);
54213 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54214 + return NULL;
54215 + }
54216 +
54217 + return p_FmPort;
54218 +}
54219 +
54220 +t_FmPort *rx_port = 0;
54221 +t_FmPort *tx_port = 0;
54222 +
54223 +/**************************************************************************//**
54224 + @Function FM_PORT_Init
54225 +
54226 + @Description Initializes the FM module
54227 +
54228 + @Param[in] h_FmPort - FM module descriptor
54229 +
54230 + @Return E_OK on success; Error code otherwise.
54231 + *//***************************************************************************/
54232 +t_Error FM_PORT_Init(t_Handle h_FmPort)
54233 +{
54234 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54235 + t_FmPortDriverParam *p_DriverParams;
54236 + t_Error errCode;
54237 + t_FmInterModulePortInitParams fmParams;
54238 + t_FmRevisionInfo revInfo;
54239 +
54240 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
54241 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54242 +
54243 + errCode = FmSpBuildBufferStructure(
54244 + &p_FmPort->p_FmPortDriverParam->intContext,
54245 + &p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54246 + &p_FmPort->p_FmPortDriverParam->bufMargins,
54247 + &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset);
54248 + if (errCode != E_OK)
54249 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54250 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
54251 + if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) &&
54252 + (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54253 + {
54254 + p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL;
54255 + if (!p_FmPort->fifoBufs.num)
54256 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS;
54257 + p_FmPort->fifoBufs.num += 4*KILOBYTE;
54258 + }
54259 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
54260 +
54261 + CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
54262 +
54263 + p_DriverParams = p_FmPort->p_FmPortDriverParam;
54264 +
54265 + /* Set up flibs port structure */
54266 + memset(&p_FmPort->port, 0, sizeof(struct fman_port));
54267 + p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType;
54268 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54269 + p_FmPort->port.fm_rev_maj = revInfo.majorRev;
54270 + p_FmPort->port.fm_rev_min = revInfo.minorRev;
54271 + p_FmPort->port.bmi_regs =
54272 + (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET);
54273 + p_FmPort->port.qmi_regs =
54274 + (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET);
54275 + p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8);
54276 + p_FmPort->port.im_en = p_FmPort->imEn;
54277 + p_FmPort->p_FmPortPrsRegs =
54278 + (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET);
54279 +
54280 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54281 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn)
54282 + {
54283 + /* Call the external Buffer routine which also checks fifo
54284 + size and updates it if necessary */
54285 + /* define external buffer pools and pool depletion*/
54286 + errCode = SetExtBufferPools(p_FmPort);
54287 + if (errCode)
54288 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54289 + /* check if the largest external buffer pool is large enough */
54290 + if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE
54291 + + p_DriverParams->bufMargins.endMargins
54292 + > p_FmPort->rxPoolsParams.largestBufSize)
54293 + RETURN_ERROR(
54294 + MAJOR,
54295 + E_INVALID_VALUE,
54296 + ("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));
54297 + }
54298 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54299 + {
54300 + {
54301 +#ifdef FM_NO_OP_OBSERVED_POOLS
54302 + t_FmRevisionInfo revInfo;
54303 +
54304 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54305 + if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion))
54306 +#endif /* FM_NO_OP_OBSERVED_POOLS */
54307 + {
54308 + /* define external buffer pools */
54309 + errCode = SetExtBufferPools(p_FmPort);
54310 + if (errCode)
54311 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54312 + }
54313 + }
54314 + }
54315 +
54316 + /************************************************************/
54317 + /* Call FM module routine for communicating parameters */
54318 + /************************************************************/
54319 + memset(&fmParams, 0, sizeof(fmParams));
54320 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54321 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54322 + fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
54323 + fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
54324 + fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
54325 + fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
54326 +
54327 + if (p_FmPort->fifoBufs.num)
54328 + {
54329 + errCode = VerifySizeOfFifo(p_FmPort);
54330 + if (errCode != E_OK)
54331 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54332 + }
54333 + fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
54334 + fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
54335 + fmParams.independentMode = p_FmPort->imEn;
54336 + fmParams.liodnOffset = p_DriverParams->liodnOffset;
54337 + fmParams.liodnBase = p_DriverParams->liodnBase;
54338 + fmParams.deqPipelineDepth =
54339 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54340 + fmParams.maxFrameLength = p_FmPort->maxFrameLength;
54341 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
54342 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
54343 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
54344 + {
54345 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54346 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54347 + /* HC ports do not have fifoDeqPipelineDepth, but it is needed only
54348 + * for deq threshold calculation.
54349 + */
54350 + fmParams.deqPipelineDepth = 2;
54351 + }
54352 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54353 +
54354 + errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
54355 + if (errCode)
54356 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54357 +
54358 + /* get params for use in init */
54359 + p_FmPort->fmMuramPhysBaseAddr =
54360 + (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low)
54361 + | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
54362 + p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm);
54363 +
54364 + errCode = InitLowLevelDriver(p_FmPort);
54365 + if (errCode != E_OK)
54366 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54367 +
54368 + FmPortDriverParamFree(p_FmPort);
54369 +
54370 +#if (DPAA_VERSION >= 11)
54371 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54372 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
54373 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54374 + {
54375 + t_FmPcdCtrlParamsPage *p_ParamsPage;
54376 +
54377 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
54378 + (void**)&p_ParamsPage);
54379 + ASSERT_COND(p_ParamsPage);
54380 +
54381 + WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON);
54382 +#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
54383 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54384 + {
54385 + WRITE_UINT32(
54386 + p_ParamsPage->misc,
54387 + (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN));
54388 + WRITE_UINT32(
54389 + p_ParamsPage->discardMask,
54390 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
54391 + }
54392 +#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */
54393 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
54394 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54395 + WRITE_UINT32(
54396 + p_ParamsPage->errorsDiscardMask,
54397 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem)));
54398 + else
54399 + WRITE_UINT32(
54400 + p_ParamsPage->errorsDiscardMask,
54401 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem)));
54402 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
54403 + }
54404 +#endif /* (DPAA_VERSION >= 11) */
54405 +
54406 + if (p_FmPort->deepSleepVars.autoResMaxSizes)
54407 + FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
54408 + return E_OK;
54409 +}
54410 +
54411 +/**************************************************************************//**
54412 + @Function FM_PORT_Free
54413 +
54414 + @Description Frees all resources that were assigned to FM module.
54415 +
54416 + Calling this routine invalidates the descriptor.
54417 +
54418 + @Param[in] h_FmPort - FM module descriptor
54419 +
54420 + @Return E_OK on success; Error code otherwise.
54421 + *//***************************************************************************/
54422 +t_Error FM_PORT_Free(t_Handle h_FmPort)
54423 +{
54424 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54425 + t_FmInterModulePortFreeParams fmParams;
54426 +
54427 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54428 +
54429 + if (p_FmPort->pcdEngines)
54430 + RETURN_ERROR(
54431 + MAJOR,
54432 + E_INVALID_STATE,
54433 + ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
54434 +
54435 + if (p_FmPort->enabled)
54436 + {
54437 + if (FM_PORT_Disable(p_FmPort) != E_OK)
54438 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
54439 + }
54440 +
54441 + if (p_FmPort->imEn)
54442 + FmPortImFree(p_FmPort);
54443 +
54444 + FmPortDriverParamFree(p_FmPort);
54445 +
54446 + memset(&fmParams, 0, sizeof(fmParams));
54447 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54448 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54449 + fmParams.deqPipelineDepth =
54450 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54451 +
54452 + FmFreePortParams(p_FmPort->h_Fm, &fmParams);
54453 +
54454 +#if (DPAA_VERSION >= 11)
54455 + if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId)
54456 + != E_OK)
54457 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED"));
54458 +
54459 + if (p_FmPort->p_ParamsPage)
54460 + FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage);
54461 +#endif /* (DPAA_VERSION >= 11) */
54462 +
54463 + if (p_FmPort->h_Spinlock)
54464 + XX_FreeSpinlock(p_FmPort->h_Spinlock);
54465 +
54466 + XX_Free(p_FmPort);
54467 +
54468 + return E_OK;
54469 +}
54470 +
54471 +/*************************************************/
54472 +/* API Advanced Init unit functions */
54473 +/*************************************************/
54474 +
54475 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas)
54476 +{
54477 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54478 +
54479 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54480 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54481 +
54482 + p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE;
54483 + memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc));
54484 +
54485 + return E_OK;
54486 +}
54487 +
54488 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
54489 +{
54490 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54491 +
54492 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54493 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54494 +
54495 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
54496 + p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE;
54497 + return E_OK;
54498 +}
54499 +
54500 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
54501 +{
54502 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54503 +
54504 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54505 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54506 +
54507 + p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE;
54508 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
54509 +
54510 + return E_OK;
54511 +}
54512 +
54513 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
54514 +{
54515 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54516 +
54517 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54518 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54519 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54520 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54521 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
54522 +
54523 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri;
54524 +
54525 + return E_OK;
54526 +}
54527 +
54528 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
54529 +{
54530 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54531 +
54532 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54533 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54534 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54535 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54536 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54537 + ("not available for Rx ports"));
54538 +
54539 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type =
54540 + (enum fman_port_deq_type)deqType;
54541 +
54542 + return E_OK;
54543 +}
54544 +
54545 +t_Error FM_PORT_ConfigDeqPrefetchOption(
54546 + t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
54547 +{
54548 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54549 +
54550 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54551 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54552 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54553 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54554 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54555 + ("not available for Rx ports"));
54556 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt =
54557 + (enum fman_port_deq_prefetch)deqPrefetchOption;
54558 +
54559 + return E_OK;
54560 +}
54561 +
54562 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort,
54563 + t_FmBackupBmPools *p_BackupBmPools)
54564 +{
54565 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54566 +
54567 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54568 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54569 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54570 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54571 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54572 + ("available for Rx ports only"));
54573 +
54574 + p_FmPort->p_FmPortDriverParam->p_BackupBmPools =
54575 + (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
54576 + if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
54577 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
54578 + memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools,
54579 + sizeof(t_FmBackupBmPools));
54580 +
54581 + return E_OK;
54582 +}
54583 +
54584 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
54585 +{
54586 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54587 +
54588 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54589 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54590 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54591 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54592 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54593 + ("not available for Rx ports"));
54594 +
54595 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt;
54596 +
54597 + return E_OK;
54598 +}
54599 +
54600 +t_Error FM_PORT_ConfigBufferPrefixContent(
54601 + t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
54602 +{
54603 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54604 +
54605 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54606 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54607 +
54608 + memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54609 + p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
54610 + /* if dataAlign was not initialized by user, we return to driver's default */
54611 + if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
54612 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
54613 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
54614 +
54615 + return E_OK;
54616 +}
54617 +
54618 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort,
54619 + uint8_t checksumLastBytesIgnore)
54620 +{
54621 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54622 +
54623 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54624 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54625 +
54626 + p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore =
54627 + checksumLastBytesIgnore;
54628 +
54629 + return E_OK;
54630 +}
54631 +
54632 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort,
54633 + uint8_t cutBytesFromEnd)
54634 +{
54635 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54636 +
54637 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54638 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54639 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54640 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54641 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54642 + ("available for Rx ports only"));
54643 +
54644 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd;
54645 +
54646 + return E_OK;
54647 +}
54648 +
54649 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort,
54650 + t_FmBufPoolDepletion *p_BufPoolDepletion)
54651 +{
54652 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54653 +
54654 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54655 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54656 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54657 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54658 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54659 + ("available for Rx ports only"));
54660 +
54661 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54662 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion,
54663 + sizeof(t_FmBufPoolDepletion));
54664 +
54665 + return E_OK;
54666 +}
54667 +
54668 +t_Error FM_PORT_ConfigObservedPoolDepletion(
54669 + t_Handle h_FmPort,
54670 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
54671 +{
54672 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54673 +
54674 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54675 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54676 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54677 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54678 + ("available for OP ports only"));
54679 +
54680 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54681 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion,
54682 + &p_FmPortObservedBufPoolDepletion->poolDepletionParams,
54683 + sizeof(t_FmBufPoolDepletion));
54684 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54685 + &p_FmPortObservedBufPoolDepletion->poolsParams,
54686 + sizeof(t_FmExtPools));
54687 +
54688 + return E_OK;
54689 +}
54690 +
54691 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools)
54692 +{
54693 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54694 +
54695 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54696 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54697 +
54698 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54699 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54700 + ("available for OP ports only"));
54701 +
54702 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools,
54703 + sizeof(t_FmExtPools));
54704 +
54705 + return E_OK;
54706 +}
54707 +
54708 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
54709 +{
54710 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54711 +
54712 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54713 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54714 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
54715 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
54716 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54717 + ("available for Tx ports only"));
54718 +
54719 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
54720 +
54721 + return E_OK;
54722 +}
54723 +
54724 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
54725 +{
54726 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54727 +
54728 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54729 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54730 + p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color;
54731 +
54732 + return E_OK;
54733 +}
54734 +
54735 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
54736 +{
54737 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54738 +
54739 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54740 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54741 +
54742 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54743 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54744 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54745 + ("Not available for Tx ports"));
54746 +
54747 + p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq;
54748 +
54749 + return E_OK;
54750 +}
54751 +
54752 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
54753 +{
54754 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54755 +
54756 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54757 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54758 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54759 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54760 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54761 + ("Not available for Tx ports"));
54762 +
54763 + p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override;
54764 +
54765 + return E_OK;
54766 +}
54767 +
54768 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort,
54769 + fmPortFrameErrSelect_t errs)
54770 +{
54771 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54772 +
54773 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54774 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54775 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54776 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
54777 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54778 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
54779 + ("available for Rx and offline parsing ports only"));
54780 +
54781 + p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
54782 +
54783 + return E_OK;
54784 +}
54785 +
54786 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData)
54787 +{
54788 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54789 +
54790 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54791 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54792 +
54793 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data =
54794 + (enum fman_port_dma_swap)swapData;
54795 +
54796 + return E_OK;
54797 +}
54798 +
54799 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort,
54800 + e_FmDmaCacheOption intContextCacheAttr)
54801 +{
54802 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54803 +
54804 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54805 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54806 +
54807 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on =
54808 + (bool)(intContextCacheAttr == e_FM_DMA_STASH);
54809 +
54810 + return E_OK;
54811 +}
54812 +
54813 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort,
54814 + e_FmDmaCacheOption headerCacheAttr)
54815 +{
54816 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54817 +
54818 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54819 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54820 +
54821 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on =
54822 + (bool)(headerCacheAttr == e_FM_DMA_STASH);
54823 +
54824 + return E_OK;
54825 +}
54826 +
54827 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(
54828 + t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr)
54829 +{
54830 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54831 +
54832 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54833 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54834 +
54835 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on =
54836 + (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH);
54837 +
54838 + return E_OK;
54839 +}
54840 +
54841 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
54842 +{
54843 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54844 +
54845 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54846 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54847 +
54848 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54849 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54850 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54851 + ("Not available for Tx ports"));
54852 +
54853 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize;
54854 +
54855 + return E_OK;
54856 +}
54857 +
54858 +#if (DPAA_VERSION >= 11)
54859 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather)
54860 +{
54861 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54862 +
54863 + UNUSED(noScatherGather);
54864 + UNUSED(p_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->noScatherGather = noScatherGather;
54870 +
54871 + return E_OK;
54872 +}
54873 +#endif /* (DPAA_VERSION >= 11) */
54874 +
54875 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort,
54876 + bool forwardReuse)
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 +
54883 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54884 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54885 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54886 + ("available for Rx ports only"));
54887 +
54888 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
54889 +
54890 + return E_OK;
54891 +}
54892 +
54893 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length)
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 +
54900 + p_FmPort->maxFrameLength = length;
54901 +
54902 + return E_OK;
54903 +}
54904 +
54905 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
54906 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort)
54907 +{
54908 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54909 +
54910 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54911 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54912 +
54913 + p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE;
54914 +
54915 + return E_OK;
54916 +}
54917 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
54918 +
54919 +/****************************************************/
54920 +/* Hidden-DEBUG Only API */
54921 +/****************************************************/
54922 +
54923 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort,
54924 + uint32_t minFillLevel)
54925 +{
54926 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54927 +
54928 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54929 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54930 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
54931 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
54932 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54933 + ("available for Tx ports only"));
54934 +
54935 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel;
54936 +
54937 + return E_OK;
54938 +}
54939 +
54940 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort,
54941 + uint8_t deqPipelineDepth)
54942 +{
54943 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54944 +
54945 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54946 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54947 +
54948 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54949 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54950 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54951 + ("Not available for Rx ports"));
54952 +
54953 + if (p_FmPort->imEn)
54954 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54955 + ("Not available for IM ports!"));
54956 +
54957 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54958 + deqPipelineDepth;
54959 +
54960 + return E_OK;
54961 +}
54962 +
54963 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort,
54964 + uint32_t fifoLowComfLevel)
54965 +{
54966 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54967 +
54968 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54969 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54970 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
54971 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
54972 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54973 + ("available for Tx ports only"));
54974 +
54975 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level =
54976 + fifoLowComfLevel;
54977 +
54978 + return E_OK;
54979 +}
54980 +
54981 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
54982 +{
54983 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54984 +
54985 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54986 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54987 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54988 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54989 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54990 + ("available for Rx ports only"));
54991 +
54992 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold;
54993 +
54994 + return E_OK;
54995 +}
54996 +
54997 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort,
54998 + uint32_t priElevationLevel)
54999 +{
55000 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55001 +
55002 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55003 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55004 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55005 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55006 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55007 + ("available for Rx ports only"));
55008 +
55009 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel;
55010 +
55011 + return E_OK;
55012 +}
55013 +/****************************************************/
55014 +/* API Run-time Control unit functions */
55015 +/****************************************************/
55016 +
55017 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort,
55018 + t_FmPortRsrc *p_NumOfOpenDmas)
55019 +{
55020 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55021 + t_Error err;
55022 +
55023 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55024 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55025 +
55026 + if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
55027 + RETURN_ERROR( MAJOR, E_INVALID_VALUE,
55028 + ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
55029 + if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
55030 + RETURN_ERROR(
55031 + MAJOR,
55032 + E_INVALID_VALUE,
55033 + ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
55034 + err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55035 + (uint8_t*)&p_NumOfOpenDmas->num,
55036 + (uint8_t*)&p_NumOfOpenDmas->extra, FALSE);
55037 + if (err)
55038 + RETURN_ERROR(MAJOR, err, NO_MSG);
55039 +
55040 + memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
55041 +
55042 + return E_OK;
55043 +}
55044 +
55045 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
55046 +{
55047 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55048 + t_Error err;
55049 +
55050 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55051 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55052 +
55053 + /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */
55054 + ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND);
55055 +
55056 + if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
55057 + RETURN_ERROR(
55058 + MAJOR, E_INVALID_VALUE,
55059 + ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
55060 + if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
55061 + RETURN_ERROR(
55062 + MAJOR,
55063 + E_INVALID_VALUE,
55064 + ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
55065 +
55066 + err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55067 + (uint8_t*)&p_NumOfTasks->num,
55068 + (uint8_t*)&p_NumOfTasks->extra, FALSE);
55069 + if (err)
55070 + RETURN_ERROR(MAJOR, err, NO_MSG);
55071 +
55072 + /* update driver's struct */
55073 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
55074 + return E_OK;
55075 +}
55076 +
55077 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
55078 +{
55079 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55080 + t_Error err;
55081 +
55082 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55083 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55084 +
55085 + if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE))
55086 + RETURN_ERROR(
55087 + MAJOR,
55088 + E_INVALID_VALUE,
55089 + ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
55090 + if (p_SizeOfFifo->num % BMI_FIFO_UNITS)
55091 + RETURN_ERROR(
55092 + MAJOR, E_INVALID_VALUE,
55093 + ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
55094 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55095 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55096 + {
55097 + /* extra FIFO size (allowed only to Rx ports) */
55098 + if (p_SizeOfFifo->extra % BMI_FIFO_UNITS)
55099 + RETURN_ERROR(
55100 + MAJOR,
55101 + E_INVALID_VALUE,
55102 + ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
55103 + }
55104 + else
55105 + if (p_SizeOfFifo->extra)
55106 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
55107 + (" No SizeOfFifo-extra for non Rx ports"));
55108 +
55109 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
55110 +
55111 + /* we do not change user's parameter */
55112 + err = VerifySizeOfFifo(p_FmPort);
55113 + if (err)
55114 + RETURN_ERROR(MAJOR, err, NO_MSG);
55115 +
55116 + err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55117 + &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE);
55118 + if (err)
55119 + RETURN_ERROR(MAJOR, err, NO_MSG);
55120 +
55121 + return E_OK;
55122 +}
55123 +
55124 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
55125 +{
55126 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55127 +
55128 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55129 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55130 + 0);
55131 +
55132 + return p_FmPort->bufferOffsets.dataOffset;
55133 +}
55134 +
55135 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
55136 +{
55137 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55138 +
55139 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55140 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55141 + NULL);
55142 +
55143 + if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
55144 + return NULL;
55145 +
55146 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
55147 +}
55148 +
55149 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
55150 +{
55151 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55152 +
55153 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55154 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55155 + NULL);
55156 +
55157 + if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
55158 + return NULL;
55159 +
55160 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
55161 +}
55162 +
55163 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
55164 +{
55165 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55166 +
55167 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55168 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55169 + NULL);
55170 +
55171 + if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
55172 + return NULL;
55173 +
55174 + return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
55175 +}
55176 +
55177 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
55178 +{
55179 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55180 +
55181 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55182 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55183 + NULL);
55184 +
55185 + if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
55186 + return NULL;
55187 +
55188 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
55189 +}
55190 +
55191 +t_Error FM_PORT_Disable(t_Handle h_FmPort)
55192 +{
55193 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55194 + int err;
55195 +
55196 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55197 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55198 +
55199 + if (p_FmPort->imEn)
55200 + FmPortImDisable(p_FmPort);
55201 +
55202 + err = fman_port_disable(&p_FmPort->port);
55203 + if (err == -EBUSY)
55204 + {
55205 + DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down",
55206 + p_FmPort->name));
55207 + }
55208 + else
55209 + if (err != 0)
55210 + {
55211 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable"));
55212 + }
55213 +
55214 + p_FmPort->enabled = FALSE;
55215 +
55216 + return E_OK;
55217 +}
55218 +
55219 +t_Error FM_PORT_Enable(t_Handle h_FmPort)
55220 +{
55221 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55222 + int err;
55223 +
55224 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55225 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55226 +
55227 + /* Used by FM_PORT_Free routine as indication
55228 + if to disable port. Thus set it to TRUE prior
55229 + to enabling itself. This way if part of enable
55230 + process fails there will be still things
55231 + to disable during Free. For example, if BMI
55232 + enable succeeded but QMI failed, still BMI
55233 + needs to be disabled by Free. */
55234 + p_FmPort->enabled = TRUE;
55235 +
55236 + if (p_FmPort->imEn)
55237 + FmPortImEnable(p_FmPort);
55238 +
55239 + err = fman_port_enable(&p_FmPort->port);
55240 + if (err != 0)
55241 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable"));
55242 +
55243 + return E_OK;
55244 +}
55245 +
55246 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
55247 +{
55248 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55249 + uint8_t factor, countUnitBit;
55250 + uint16_t baseGran;
55251 + struct fman_port_rate_limiter params;
55252 + int err;
55253 +
55254 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55255 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55256 +
55257 + switch (p_FmPort->portType)
55258 + {
55259 + case (e_FM_PORT_TYPE_TX_10G):
55260 + case (e_FM_PORT_TYPE_TX):
55261 + baseGran = BMI_RATE_LIMIT_GRAN_TX;
55262 + break;
55263 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55264 + baseGran = BMI_RATE_LIMIT_GRAN_OP;
55265 + break;
55266 + default:
55267 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55268 + ("available for Tx and Offline parsing ports only"));
55269 + }
55270 +
55271 + countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
55272 + /* normally, we use 1 usec as the reference count */
55273 + factor = 1;
55274 + /* if ratelimit is too small for a 1usec factor, multiply the factor */
55275 + while (p_RateLimit->rateLimit < baseGran / factor)
55276 + {
55277 + if (countUnitBit == 31)
55278 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
55279 +
55280 + countUnitBit++;
55281 + factor <<= 1;
55282 + }
55283 + /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
55284 + if (p_RateLimit->rateLimit
55285 + > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor))
55286 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
55287 +
55288 + if (!p_RateLimit->maxBurstSize
55289 + || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE))
55290 + RETURN_ERROR(
55291 + MAJOR,
55292 + E_INVALID_VALUE,
55293 + ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE));
55294 +
55295 + params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm);
55296 + params.high_burst_size_gran = FALSE;
55297 + params.burst_size = p_RateLimit->maxBurstSize;
55298 + params.rate = p_RateLimit->rateLimit;
55299 + params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE;
55300 +
55301 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55302 + {
55303 +#ifndef FM_NO_ADVANCED_RATE_LIMITER
55304 +
55305 + if ((p_FmPort->fmRevInfo.majorRev == 4)
55306 + || (p_FmPort->fmRevInfo.majorRev >= 6))
55307 + {
55308 + params.high_burst_size_gran = TRUE;
55309 + }
55310 + else
55311 +#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
55312 + {
55313 + if (p_RateLimit->rateLimitDivider
55314 + != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
55315 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
55316 + ("FM_PORT_ConfigDualRateLimitScaleDown"));
55317 +
55318 + if (p_RateLimit->maxBurstSize % 1000)
55319 + {
55320 + p_RateLimit->maxBurstSize =
55321 + (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1);
55322 + DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
55323 + }
55324 + else
55325 + p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize
55326 + / 1000);
55327 + }
55328 + params.rate_factor =
55329 + (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider;
55330 + params.burst_size = p_RateLimit->maxBurstSize;
55331 + }
55332 +
55333 + err = fman_port_set_rate_limiter(&p_FmPort->port, &params);
55334 + if (err != 0)
55335 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55336 +
55337 + return E_OK;
55338 +}
55339 +
55340 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
55341 +{
55342 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55343 + int err;
55344 +
55345 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55346 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55347 +
55348 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
55349 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
55350 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55351 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55352 + ("available for Tx and Offline parsing ports only"));
55353 +
55354 + err = fman_port_delete_rate_limiter(&p_FmPort->port);
55355 + if (err != 0)
55356 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55357 + return E_OK;
55358 +}
55359 +
55360 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio,
55361 + uint8_t wq)
55362 +{
55363 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55364 + uint32_t tmpReg;
55365 + uint32_t wqTmpReg;
55366 +
55367 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55368 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55369 +
55370 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX)
55371 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
55372 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55373 + ("PFC mapping is available for Tx ports only"));
55374 +
55375 + if (prio > 7)
55376 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55377 + ("PFC priority (%d) is out of range (0-7)", prio));
55378 + if (wq > 7)
55379 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55380 + ("WQ (%d) is out of range (0-7)", wq));
55381 +
55382 + tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]);
55383 + tmpReg &= ~(0xf << ((7 - prio) * 4));
55384 + wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4));
55385 + tmpReg |= wqTmpReg;
55386 +
55387 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0],
55388 + tmpReg);
55389 +
55390 + return E_OK;
55391 +}
55392 +
55393 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
55394 +{
55395 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55396 +
55397 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55398 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55399 +
55400 + fman_port_set_queue_cnt_mode(&p_FmPort->port, enable);
55401 +
55402 + return E_OK;
55403 +}
55404 +
55405 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
55406 +{
55407 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55408 + int err;
55409 +
55410 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55411 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55412 +
55413 + err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable);
55414 + if (err != 0)
55415 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode"));
55416 + return E_OK;
55417 +}
55418 +
55419 +t_Error FM_PORT_SetPerformanceCountersParams(
55420 + t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
55421 +{
55422 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55423 + struct fman_port_perf_cnt_params params;
55424 + int err;
55425 +
55426 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55427 +
55428 + /* check parameters */
55429 + if (!p_FmPortPerformanceCnt->taskCompVal
55430 + || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
55431 + RETURN_ERROR(
55432 + MAJOR,
55433 + E_INVALID_VALUE,
55434 + ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num));
55435 + if (!p_FmPortPerformanceCnt->dmaCompVal
55436 + || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
55437 + RETURN_ERROR(
55438 + MAJOR,
55439 + E_INVALID_VALUE,
55440 + ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num));
55441 + if (!p_FmPortPerformanceCnt->fifoCompVal
55442 + || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
55443 + RETURN_ERROR(
55444 + MAJOR,
55445 + E_INVALID_VALUE,
55446 + ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num));
55447 + if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
55448 + RETURN_ERROR(
55449 + MAJOR,
55450 + E_INVALID_VALUE,
55451 + ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS));
55452 +
55453 + switch (p_FmPort->portType)
55454 + {
55455 + case (e_FM_PORT_TYPE_RX_10G):
55456 + case (e_FM_PORT_TYPE_RX):
55457 + if (!p_FmPortPerformanceCnt->queueCompVal
55458 + || (p_FmPortPerformanceCnt->queueCompVal
55459 + > MAX_PERFORMANCE_RX_QUEUE_COMP))
55460 + RETURN_ERROR(
55461 + MAJOR,
55462 + E_INVALID_VALUE,
55463 + ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP));
55464 + break;
55465 + case (e_FM_PORT_TYPE_TX_10G):
55466 + case (e_FM_PORT_TYPE_TX):
55467 + if (!p_FmPortPerformanceCnt->queueCompVal
55468 + || (p_FmPortPerformanceCnt->queueCompVal
55469 + > MAX_PERFORMANCE_TX_QUEUE_COMP))
55470 + RETURN_ERROR(
55471 + MAJOR,
55472 + E_INVALID_VALUE,
55473 + ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP));
55474 + break;
55475 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55476 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
55477 + if (p_FmPortPerformanceCnt->queueCompVal)
55478 + RETURN_ERROR(
55479 + MAJOR,
55480 + E_INVALID_VALUE,
55481 + ("performanceCnt.queueCompVal is not relevant for H/O ports."));
55482 + break;
55483 + default:
55484 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55485 + }
55486 +
55487 + params.task_val = p_FmPortPerformanceCnt->taskCompVal;
55488 + params.queue_val = p_FmPortPerformanceCnt->queueCompVal;
55489 + params.dma_val = p_FmPortPerformanceCnt->dmaCompVal;
55490 + params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal;
55491 +
55492 + err = fman_port_set_perf_cnt_params(&p_FmPort->port, &params);
55493 + if (err != 0)
55494 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params"));
55495 +
55496 + return E_OK;
55497 +}
55498 +
55499 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
55500 +{
55501 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55502 + t_FmPortPerformanceCnt currParams, savedParams;
55503 + t_Error err;
55504 + bool underTest, failed = FALSE;
55505 +
55506 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55507 +
55508 + XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
55509 + p_FmPort->portType, p_FmPort->portId);
55510 +
55511 + currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
55512 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55513 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55514 + currParams.queueCompVal = 0;
55515 + else
55516 + currParams.queueCompVal = 1;
55517 + currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
55518 + currParams.fifoCompVal = p_FmPort->fifoBufs.num;
55519 +
55520 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55521 + ClearPerfCnts(p_FmPort);
55522 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55523 + != E_OK)
55524 + RETURN_ERROR(MAJOR, err, NO_MSG);
55525 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55526 + XX_UDelay(1000000);
55527 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55528 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55529 + {
55530 + XX_Print(
55531 + "Max num of defined port tasks (%d) utilized - Please enlarge\n",
55532 + p_FmPort->tasks.num);
55533 + failed = TRUE;
55534 + }
55535 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55536 + {
55537 + XX_Print(
55538 + "Max num of defined port openDmas (%d) utilized - Please enlarge\n",
55539 + p_FmPort->openDmas.num);
55540 + failed = TRUE;
55541 + }
55542 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55543 + {
55544 + XX_Print(
55545 + "Max size of defined port fifo (%d) utilized - Please enlarge\n",
55546 + p_FmPort->fifoBufs.num);
55547 + failed = TRUE;
55548 + }
55549 + if (failed)
55550 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
55551 +
55552 + memset(&savedParams, 0, sizeof(savedParams));
55553 + while (TRUE)
55554 + {
55555 + underTest = FALSE;
55556 + if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
55557 + {
55558 + currParams.taskCompVal--;
55559 + underTest = TRUE;
55560 + }
55561 + if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
55562 + {
55563 + currParams.dmaCompVal--;
55564 + underTest = TRUE;
55565 + }
55566 + if ((currParams.fifoCompVal != BMI_FIFO_UNITS)
55567 + && !savedParams.fifoCompVal)
55568 + {
55569 + currParams.fifoCompVal -= BMI_FIFO_UNITS;
55570 + underTest = TRUE;
55571 + }
55572 + if (!underTest)
55573 + break;
55574 +
55575 + ClearPerfCnts(p_FmPort);
55576 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55577 + != E_OK)
55578 + RETURN_ERROR(MAJOR, err, NO_MSG);
55579 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55580 + XX_UDelay(1000000);
55581 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55582 +
55583 + if (!savedParams.taskCompVal
55584 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55585 + savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2);
55586 + if (!savedParams.dmaCompVal
55587 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55588 + savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2);
55589 + if (!savedParams.fifoCompVal
55590 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55591 + savedParams.fifoCompVal = currParams.fifoCompVal
55592 + + (2 * BMI_FIFO_UNITS);
55593 + }
55594 +
55595 + XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
55596 + savedParams.taskCompVal, savedParams.dmaCompVal,
55597 + savedParams.fifoCompVal);
55598 + return E_OK;
55599 +}
55600 +
55601 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
55602 +{
55603 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55604 + int err;
55605 +
55606 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55607 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55608 +
55609 + err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable);
55610 + if (err != 0)
55611 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode"));
55612 + return E_OK;
55613 +}
55614 +
55615 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
55616 +{
55617 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55618 + volatile uint32_t *p_ErrDiscard = NULL;
55619 + int err;
55620 +
55621 + UNUSED(p_ErrDiscard);
55622 + err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs);
55623 + if (err != 0)
55624 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask"));
55625 +
55626 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
55627 + if (p_FmPort->fmRevInfo.majorRev >= 6)
55628 + {
55629 + t_FmPcdCtrlParamsPage *p_ParamsPage;
55630 +
55631 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
55632 + (void**)&p_ParamsPage);
55633 + ASSERT_COND(p_ParamsPage);
55634 + switch (p_FmPort->portType)
55635 + {
55636 + case (e_FM_PORT_TYPE_RX_10G):
55637 + case (e_FM_PORT_TYPE_RX):
55638 + p_ErrDiscard =
55639 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
55640 + break;
55641 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55642 + p_ErrDiscard =
55643 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
55644 + break;
55645 + default:
55646 + RETURN_ERROR(
55647 + MAJOR, E_INVALID_OPERATION,
55648 + ("available for Rx and offline parsing ports only"));
55649 + }
55650 + WRITE_UINT32(p_ParamsPage->errorsDiscardMask,
55651 + GET_UINT32(*p_ErrDiscard) | errs);
55652 + }
55653 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
55654 +
55655 + return E_OK;
55656 +}
55657 +
55658 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
55659 + bool enable)
55660 +{
55661 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55662 + int err;
55663 +
55664 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55665 + SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
55666 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55667 +
55668 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55669 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55670 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55671 + ("available for Rx ports only"));
55672 +
55673 + err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable);
55674 + if (err != 0)
55675 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode"));
55676 + return E_OK;
55677 +}
55678 +
55679 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats)
55680 +{
55681 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55682 +
55683 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55684 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){
55685 + p_BmiStats->cntCycle =
55686 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55687 + /* fmbm_rccn */
55688 + p_BmiStats->cntTaskUtil =
55689 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55690 + /* fmbm_rtuc */
55691 + p_BmiStats->cntQueueUtil =
55692 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55693 + /* fmbm_rrquc */
55694 + p_BmiStats->cntDmaUtil =
55695 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55696 + /* fmbm_rduc */
55697 + p_BmiStats->cntFifoUtil =
55698 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55699 + /* fmbm_rfuc */
55700 + p_BmiStats->cntRxPauseActivation =
55701 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION);
55702 + /* fmbm_rpac */
55703 + p_BmiStats->cntFrame =
55704 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55705 + /* fmbm_rfrc */
55706 + p_BmiStats->cntDiscardFrame =
55707 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55708 + /* fmbm_rfdc */
55709 + p_BmiStats->cntDeallocBuf =
55710 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55711 + /* fmbm_rbdc */
55712 + p_BmiStats->cntRxBadFrame =
55713 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME);
55714 + /* fmbm_rfbc */
55715 + p_BmiStats->cntRxLargeFrame =
55716 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME);
55717 + /* fmbm_rlfc */
55718 + p_BmiStats->cntRxFilterFrame =
55719 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
55720 + /* fmbm_rffc */
55721 + p_BmiStats->cntRxListDmaErr =
55722 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
55723 + /* fmbm_rfldec */
55724 + p_BmiStats->cntRxOutOfBuffersDiscard =
55725 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
55726 + /* fmbm_rodc */
55727 + p_BmiStats->cntWredDiscard = 0;
55728 + p_BmiStats->cntLengthErr = 0;
55729 + p_BmiStats->cntUnsupportedFormat = 0;
55730 + }
55731 + else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
55732 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){
55733 + p_BmiStats->cntCycle =
55734 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55735 + /* fmbm_tccn */
55736 + p_BmiStats->cntTaskUtil =
55737 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55738 + /* fmbm_ttuc */
55739 + p_BmiStats->cntQueueUtil =
55740 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55741 + /* fmbm_ttcquc */
55742 + p_BmiStats->cntDmaUtil =
55743 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55744 + /* fmbm_tduc */
55745 + p_BmiStats->cntFifoUtil =
55746 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55747 + /* fmbm_tfuc */
55748 + p_BmiStats->cntRxPauseActivation = 0;
55749 + p_BmiStats->cntFrame =
55750 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55751 + /* fmbm_tfrc */
55752 + p_BmiStats->cntDiscardFrame =
55753 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55754 + /* fmbm_tfdc */
55755 + p_BmiStats->cntDeallocBuf =
55756 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55757 + /* fmbm_tbdc */
55758 + p_BmiStats->cntRxBadFrame = 0;
55759 + p_BmiStats->cntRxLargeFrame = 0;
55760 + p_BmiStats->cntRxFilterFrame = 0;
55761 + p_BmiStats->cntRxListDmaErr = 0;
55762 + p_BmiStats->cntRxOutOfBuffersDiscard = 0;
55763 + p_BmiStats->cntWredDiscard = 0;
55764 + p_BmiStats->cntLengthErr =
55765 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
55766 + /* fmbm_tfledc */
55767 + p_BmiStats->cntUnsupportedFormat =
55768 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
55769 + /* fmbm_tfufdc */
55770 + }
55771 + else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
55772 + p_BmiStats->cntCycle =
55773 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55774 + /* fmbm_occn */
55775 + p_BmiStats->cntTaskUtil =
55776 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55777 + /* fmbm_otuc */
55778 + p_BmiStats->cntQueueUtil = 0;
55779 + p_BmiStats->cntDmaUtil =
55780 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55781 + /* fmbm_oduc */
55782 + p_BmiStats->cntFifoUtil =
55783 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55784 + /* fmbm_ofuc*/
55785 + p_BmiStats->cntRxPauseActivation = 0;
55786 + p_BmiStats->cntFrame =
55787 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55788 + /* fmbm_ofrc */
55789 + p_BmiStats->cntDiscardFrame =
55790 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55791 + /* fmbm_ofdc */
55792 + p_BmiStats->cntDeallocBuf =
55793 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55794 + /* fmbm_obdc*/
55795 + p_BmiStats->cntRxBadFrame = 0;
55796 + p_BmiStats->cntRxLargeFrame = 0;
55797 + p_BmiStats->cntRxFilterFrame =
55798 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
55799 + /* fmbm_offc */
55800 + p_BmiStats->cntRxListDmaErr =
55801 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
55802 + /* fmbm_ofldec */
55803 + p_BmiStats->cntRxOutOfBuffersDiscard =
55804 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
55805 + /* fmbm_rodc */
55806 + p_BmiStats->cntWredDiscard =
55807 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD);
55808 + /* fmbm_ofwdc */
55809 + p_BmiStats->cntLengthErr =
55810 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
55811 + /* fmbm_ofledc */
55812 + p_BmiStats->cntUnsupportedFormat =
55813 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
55814 + /* fmbm_ofufdc */
55815 + }
55816 + return E_OK;
55817 +}
55818 +
55819 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
55820 +{
55821 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55822 + bool bmiCounter = FALSE;
55823 + enum fman_port_stats_counters statsType;
55824 + enum fman_port_perf_counters perfType;
55825 + enum fman_port_qmi_counters queueType;
55826 + bool isStats;
55827 + t_Error errCode;
55828 +
55829 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55830 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55831 +
55832 + switch (counter)
55833 + {
55834 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55835 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55836 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55837 + /* check that counter is available for the port type */
55838 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55839 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55840 + {
55841 + REPORT_ERROR(MINOR, E_INVALID_STATE,
55842 + ("Requested counter is not available for Rx ports"));
55843 + return 0;
55844 + }
55845 + bmiCounter = FALSE;
55846 + break;
55847 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55848 + bmiCounter = FALSE;
55849 + break;
55850 + default: /* BMI counters (or error - will be checked in BMI routine )*/
55851 + bmiCounter = TRUE;
55852 + break;
55853 + }
55854 +
55855 + if (bmiCounter)
55856 + {
55857 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
55858 + &perfType, &isStats);
55859 + if (errCode != E_OK)
55860 + {
55861 + REPORT_ERROR(MINOR, errCode, NO_MSG);
55862 + return 0;
55863 + }
55864 + if (isStats)
55865 + return fman_port_get_stats_counter(&p_FmPort->port, statsType);
55866 + else
55867 + return fman_port_get_perf_counter(&p_FmPort->port, perfType);
55868 + }
55869 + else /* QMI counter */
55870 + {
55871 + /* check that counters are enabled */
55872 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
55873 + & QMI_PORT_CFG_EN_COUNTERS))
55874 +
55875 + {
55876 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
55877 + return 0;
55878 + }
55879 +
55880 + /* Set counter */
55881 + switch (counter)
55882 + {
55883 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55884 + queueType = E_FMAN_PORT_ENQ_TOTAL;
55885 + break;
55886 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55887 + queueType = E_FMAN_PORT_DEQ_TOTAL;
55888 + break;
55889 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55890 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
55891 + break;
55892 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55893 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
55894 + break;
55895 + default:
55896 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
55897 + return 0;
55898 + }
55899 +
55900 + return fman_port_get_qmi_counter(&p_FmPort->port, queueType);
55901 + }
55902 +
55903 + return 0;
55904 +}
55905 +
55906 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter,
55907 + uint32_t value)
55908 +{
55909 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55910 + bool bmiCounter = FALSE;
55911 + enum fman_port_stats_counters statsType;
55912 + enum fman_port_perf_counters perfType;
55913 + enum fman_port_qmi_counters queueType;
55914 + bool isStats;
55915 + t_Error errCode;
55916 +
55917 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55918 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55919 +
55920 + switch (counter)
55921 + {
55922 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55923 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55924 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55925 + /* check that counter is available for the port type */
55926 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55927 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55928 + RETURN_ERROR(
55929 + MINOR, E_INVALID_STATE,
55930 + ("Requested counter is not available for Rx ports"));
55931 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55932 + bmiCounter = FALSE;
55933 + break;
55934 + default: /* BMI counters (or error - will be checked in BMI routine )*/
55935 + bmiCounter = TRUE;
55936 + break;
55937 + }
55938 +
55939 + if (bmiCounter)
55940 + {
55941 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
55942 + &perfType, &isStats);
55943 + if (errCode != E_OK)
55944 + {
55945 + RETURN_ERROR(MINOR, errCode, NO_MSG);
55946 + }
55947 + if (isStats)
55948 + fman_port_set_stats_counter(&p_FmPort->port, statsType, value);
55949 + else
55950 + fman_port_set_perf_counter(&p_FmPort->port, perfType, value);
55951 + }
55952 + else /* QMI counter */
55953 + {
55954 + /* check that counters are enabled */
55955 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
55956 + & QMI_PORT_CFG_EN_COUNTERS))
55957 + {
55958 + RETURN_ERROR(MINOR, E_INVALID_STATE,
55959 + ("Requested counter was not enabled"));
55960 + }
55961 +
55962 + /* Set counter */
55963 + switch (counter)
55964 + {
55965 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55966 + queueType = E_FMAN_PORT_ENQ_TOTAL;
55967 + break;
55968 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55969 + queueType = E_FMAN_PORT_DEQ_TOTAL;
55970 + break;
55971 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55972 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
55973 + break;
55974 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55975 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
55976 + break;
55977 + default:
55978 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
55979 + ("Requested counter is not available"));
55980 + }
55981 +
55982 + fman_port_set_qmi_counter(&p_FmPort->port, queueType, value);
55983 + }
55984 +
55985 + return E_OK;
55986 +}
55987 +
55988 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
55989 +{
55990 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55991 +
55992 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55993 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55994 +
55995 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
55996 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55997 + {
55998 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
55999 + return 0;
56000 + }
56001 + return fman_port_get_bpool_counter(&p_FmPort->port, poolId);
56002 +}
56003 +
56004 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
56005 + uint32_t value)
56006 +{
56007 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
56008 +
56009 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56010 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56011 +
56012 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
56013 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56014 + RETURN_ERROR( MINOR, E_INVALID_STATE,
56015 + ("Requested counter is not available for non-Rx ports"));
56016 +
56017 + fman_port_set_bpool_counter(&p_FmPort->port, poolId, value);
56018 + return E_OK;
56019 +}
56020 +bool FM_PORT_IsStalled(t_Handle h_FmPort)
56021 +{
56022 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56023 + t_Error err;
56024 + bool isStalled;
56025 +
56026 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
56027 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
56028 + FALSE);
56029 +
56030 + err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
56031 + if (err != E_OK)
56032 + {
56033 + REPORT_ERROR(MAJOR, err, NO_MSG);
56034 + return TRUE;
56035 + }
56036 + return isStalled;
56037 +}
56038 +
56039 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
56040 +{
56041 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56042 +
56043 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56044 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56045 +
56046 + return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
56047 +}
56048 +
56049 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
56050 +{
56051 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56052 + int err;
56053 +
56054 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56055 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56056 +
56057 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56058 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56059 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56060 + ("available for Rx ports only"));
56061 +
56062 + if (l4Checksum)
56063 + err = fman_port_modify_rx_fd_bits(
56064 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
56065 + TRUE);
56066 + else
56067 + err = fman_port_modify_rx_fd_bits(
56068 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
56069 + FALSE);
56070 + if (err != 0)
56071 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits"));
56072 +
56073 + return E_OK;
56074 +}
56075 +
56076 +/*****************************************************************************/
56077 +/* API Run-time PCD Control unit functions */
56078 +/*****************************************************************************/
56079 +
56080 +#if (DPAA_VERSION >= 11)
56081 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams)
56082 +{
56083 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56084 + t_Error err = E_OK;
56085 + volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL;
56086 + uint32_t tmpReg = 0, tmp = 0;
56087 + uint16_t hwStoragePrflId;
56088 +
56089 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56090 + SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE);
56091 + /*for numOfProfiles = 0 don't call this function*/
56092 + SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE);
56093 + /*dfltRelativeId should be in the range of numOfProfiles*/
56094 + SANITY_CHECK_RETURN_ERROR(
56095 + p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles,
56096 + E_INVALID_VALUE);
56097 + /*p_FmPort should be from Rx type or OP*/
56098 + SANITY_CHECK_RETURN_ERROR(
56099 + ((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)),
56100 + E_INVALID_VALUE);
56101 + /*port should be disabled*/
56102 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE);
56103 + /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/
56104 + SANITY_CHECK_RETURN_ERROR(
56105 + ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
56106 + E_INVALID_VALUE);
56107 + /*should be called before SetPCD - this port should be without PCD*/
56108 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE);
56109 +
56110 + /*alloc window of VSPs for this port*/
56111 + err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType,
56112 + p_FmPort->portId, p_VSPParams->numOfProfiles);
56113 + if (err != E_OK)
56114 + RETURN_ERROR(MAJOR, err, NO_MSG);
56115 +
56116 + /*get absolute VSP ID for dfltRelative*/
56117 + err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType,
56118 + p_FmPort->portId,
56119 + p_VSPParams->dfltRelativeId,
56120 + &hwStoragePrflId);
56121 + if (err != E_OK)
56122 + RETURN_ERROR(MAJOR, err, NO_MSG);
56123 +
56124 + /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/
56125 + switch (p_FmPort->portType)
56126 + {
56127 + case (e_FM_PORT_TYPE_RX_10G):
56128 + case (e_FM_PORT_TYPE_RX):
56129 + p_BmiStorageProfileId =
56130 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid);
56131 + p_BmiVspe =
56132 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne);
56133 +
56134 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56135 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56136 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56137 +
56138 + tmpReg = GET_UINT32(*p_BmiVspe);
56139 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN);
56140 +
56141 + p_BmiStorageProfileId =
56142 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid;
56143 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp;
56144 + hwStoragePrflId = p_VSPParams->dfltRelativeId;
56145 + break;
56146 +
56147 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56148 + tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME;
56149 + WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn,
56150 + tmpReg);
56151 +
56152 + p_BmiStorageProfileId =
56153 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid;
56154 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp;
56155 + tmp |= BMI_EBD_EN;
56156 + break;
56157 +
56158 + default:
56159 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56160 + ("available for Rx and offline parsing ports only"));
56161 + }
56162 +
56163 + p_FmPort->vspe = TRUE;
56164 + p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId;
56165 +
56166 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56167 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56168 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56169 +
56170 + tmpReg = GET_UINT32(*p_BmiVspe);
56171 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp);
56172 + return E_OK;
56173 +}
56174 +#endif /* (DPAA_VERSION >= 11) */
56175 +
56176 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
56177 +{
56178 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56179 + t_Error err = E_OK;
56180 +
56181 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56182 + ASSERT_COND(p_FmPort->h_FmPcd);
56183 +
56184 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56185 + {
56186 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56187 + return ERROR_CODE(E_BUSY);
56188 + }
56189 +
56190 + if (numOfProfiles)
56191 + {
56192 + err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd,
56193 + p_FmPort->hardwarePortId, numOfProfiles);
56194 + if (err)
56195 + RETURN_ERROR(MAJOR, err, NO_MSG);
56196 + }
56197 + /* set the port handle within the PCD policer, even if no profiles defined */
56198 + FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
56199 +
56200 + RELEASE_LOCK(p_FmPort->lock);
56201 +
56202 + return E_OK;
56203 +}
56204 +
56205 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
56206 +{
56207 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56208 + t_Error err = E_OK;
56209 +
56210 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56211 + {
56212 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56213 + return ERROR_CODE(E_BUSY);
56214 + }
56215 +
56216 + err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
56217 +
56218 + RELEASE_LOCK(p_FmPort->lock);
56219 +
56220 + if (err)
56221 + RETURN_ERROR(MAJOR, err, NO_MSG);
56222 +
56223 + return E_OK;
56224 +}
56225 +
56226 +t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort,
56227 + t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
56228 +{
56229 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56230 + volatile uint32_t *p_BmiHpnia = NULL;
56231 + uint32_t tmpReg;
56232 + uint8_t relativeSchemeId;
56233 + uint8_t physicalSchemeId;
56234 +
56235 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56236 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56237 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
56238 + E_INVALID_STATE);
56239 +
56240 + tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0);
56241 + switch (p_FmPort->portType)
56242 + {
56243 + case (e_FM_PORT_TYPE_RX_10G):
56244 + case (e_FM_PORT_TYPE_RX):
56245 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56246 + break;
56247 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56248 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56249 + break;
56250 + default:
56251 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56252 + ("available for Rx and offline parsing ports only"));
56253 + }
56254 +
56255 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56256 + {
56257 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56258 + return ERROR_CODE(E_BUSY);
56259 + }
56260 +
56261 + /* if we want to change to direct scheme, we need to check that this scheme is valid */
56262 + if (p_FmPcdKgScheme->direct)
56263 + {
56264 + physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme);
56265 + /* check that this scheme is bound to this port */
56266 + if (!(p_FmPort->schemesPerPortVector
56267 + & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
56268 + {
56269 + RELEASE_LOCK(p_FmPort->lock);
56270 + RETURN_ERROR(
56271 + MAJOR, E_INVALID_STATE,
56272 + ("called with a scheme that is not bound to this port"));
56273 + }
56274 +
56275 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd,
56276 + physicalSchemeId);
56277 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
56278 + {
56279 + RELEASE_LOCK(p_FmPort->lock);
56280 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
56281 + ("called with invalid Scheme "));
56282 + }
56283 +
56284 + if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme))
56285 + {
56286 + RELEASE_LOCK(p_FmPort->lock);
56287 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56288 + ("called with uninitialized Scheme "));
56289 + }
56290 +
56291 + WRITE_UINT32(
56292 + *p_BmiHpnia,
56293 + NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
56294 + }
56295 + else
56296 + /* change to indirect scheme */
56297 + WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
56298 + RELEASE_LOCK(p_FmPort->lock);
56299 +
56300 + return E_OK;
56301 +}
56302 +
56303 +t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort,
56304 + t_Handle h_Profile)
56305 +{
56306 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56307 + volatile uint32_t *p_BmiNia;
56308 + volatile uint32_t *p_BmiHpnia;
56309 + uint32_t tmpReg;
56310 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
56311 +
56312 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56313 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56314 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR,
56315 + E_INVALID_STATE);
56316 +
56317 + /* check relevance of this routine - only when policer is used
56318 + directly after BMI or Parser */
56319 + if ((p_FmPort->pcdEngines & FM_PCD_KG)
56320 + || (p_FmPort->pcdEngines & FM_PCD_CC))
56321 + RETURN_ERROR(
56322 + MAJOR,
56323 + E_INVALID_STATE,
56324 + ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
56325 +
56326 + switch (p_FmPort->portType)
56327 + {
56328 + case (e_FM_PORT_TYPE_RX_10G):
56329 + case (e_FM_PORT_TYPE_RX):
56330 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56331 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56332 + tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
56333 + break;
56334 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56335 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56336 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56337 + tmpReg = 0;
56338 + break;
56339 + default:
56340 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56341 + ("available for Rx and offline parsing ports only"));
56342 + }
56343 +
56344 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56345 + {
56346 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56347 + return ERROR_CODE(E_BUSY);
56348 + }
56349 +
56350 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
56351 + {
56352 + RELEASE_LOCK(p_FmPort->lock);
56353 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
56354 + }
56355 +
56356 + tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
56357 +
56358 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
56359 + {
56360 + /* update BMI HPNIA */
56361 + WRITE_UINT32(*p_BmiHpnia, tmpReg);
56362 + }
56363 + else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
56364 + {
56365 + /* rfne may contain FDCS bits, so first we read them. */
56366 + tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
56367 + /* update BMI NIA */
56368 + WRITE_UINT32(*p_BmiNia, tmpReg);
56369 + }RELEASE_LOCK(p_FmPort->lock);
56370 +
56371 + return E_OK;
56372 +}
56373 +
56374 +t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree)
56375 +{
56376 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56377 + t_Error err = E_OK;
56378 + volatile uint32_t *p_BmiCcBase = NULL;
56379 + volatile uint32_t *p_BmiNia = NULL;
56380 + uint32_t ccTreePhysOffset;
56381 +
56382 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56383 + SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE);
56384 +
56385 + if (p_FmPort->imEn)
56386 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56387 + ("available for non-independent mode ports only"));
56388 +
56389 + /* get PCD registers pointers */
56390 + switch (p_FmPort->portType)
56391 + {
56392 + case (e_FM_PORT_TYPE_RX_10G):
56393 + case (e_FM_PORT_TYPE_RX):
56394 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56395 + break;
56396 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56397 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56398 + break;
56399 + default:
56400 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56401 + ("available for Rx and offline parsing ports only"));
56402 + }
56403 +
56404 + /* check that current NIA is BMI to BMI */
56405 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
56406 + != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd))
56407 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56408 + ("may be called only for ports in BMI-to-BMI state."));
56409 +
56410 + if (p_FmPort->pcdEngines & FM_PCD_CC)
56411 + {
56412 + if (p_FmPort->h_IpReassemblyManip)
56413 + {
56414 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56415 + p_FmPort->h_IpReassemblyManip, FALSE);
56416 + if (err != E_OK)
56417 + {
56418 + RETURN_ERROR(MAJOR, err, NO_MSG);
56419 + }
56420 + }
56421 + else
56422 + if (p_FmPort->h_CapwapReassemblyManip)
56423 + {
56424 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56425 + p_FmPort->h_CapwapReassemblyManip,
56426 + FALSE);
56427 + if (err != E_OK)
56428 + {
56429 + RETURN_ERROR(MAJOR, err, NO_MSG);
56430 + }
56431 + }
56432 + switch (p_FmPort->portType)
56433 + {
56434 + case (e_FM_PORT_TYPE_RX_10G):
56435 + case (e_FM_PORT_TYPE_RX):
56436 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
56437 + break;
56438 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56439 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
56440 + break;
56441 + default:
56442 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
56443 + }
56444 +
56445 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56446 + {
56447 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56448 + return ERROR_CODE(E_BUSY);
56449 + }
56450 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree,
56451 + &ccTreePhysOffset, h_FmPort);
56452 + if (err)
56453 + {
56454 + RELEASE_LOCK(p_FmPort->lock);
56455 + RETURN_ERROR(MAJOR, err, NO_MSG);
56456 + }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
56457 +
56458 + p_FmPort->ccTreeId = h_CcTree;
56459 + RELEASE_LOCK(p_FmPort->lock);
56460 + }
56461 + else
56462 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56463 + ("Coarse Classification not defined for this port."));
56464 +
56465 + return E_OK;
56466 +}
56467 +
56468 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
56469 +{
56470 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56471 + t_Error err = E_OK;
56472 +
56473 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56474 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56475 +
56476 + if (p_FmPort->imEn)
56477 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56478 + ("available for non-independent mode ports only"));
56479 +
56480 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56481 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56482 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56483 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56484 + ("available for Rx and offline parsing ports only"));
56485 +
56486 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56487 + {
56488 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56489 + return ERROR_CODE(E_BUSY);
56490 + }
56491 +
56492 + if (p_FmPort->h_ReassemblyTree)
56493 + p_FmPort->pcdEngines |= FM_PCD_CC;
56494 +
56495 + err = AttachPCD(h_FmPort);
56496 + RELEASE_LOCK(p_FmPort->lock);
56497 +
56498 + return err;
56499 +}
56500 +
56501 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
56502 +{
56503 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56504 + t_Error err = E_OK;
56505 +
56506 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56507 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56508 +
56509 + if (p_FmPort->imEn)
56510 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56511 + ("available for non-independent mode ports only"));
56512 +
56513 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56514 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56515 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56516 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56517 + ("available for Rx and offline parsing ports only"));
56518 +
56519 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56520 + {
56521 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56522 + return ERROR_CODE(E_BUSY);
56523 + }
56524 +
56525 + err = DetachPCD(h_FmPort);
56526 + if (err != E_OK)
56527 + {
56528 + RELEASE_LOCK(p_FmPort->lock);
56529 + RETURN_ERROR(MAJOR, err, NO_MSG);
56530 + }
56531 +
56532 + if (p_FmPort->h_ReassemblyTree)
56533 + p_FmPort->pcdEngines &= ~FM_PCD_CC;
56534 + RELEASE_LOCK(p_FmPort->lock);
56535 +
56536 + return E_OK;
56537 +}
56538 +
56539 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam)
56540 +{
56541 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56542 + t_Error err = E_OK;
56543 + t_FmPortPcdParams modifiedPcdParams, *p_PcdParams;
56544 + t_FmPcdCcTreeParams *p_FmPcdCcTreeParams;
56545 + t_FmPortPcdCcParams fmPortPcdCcParams;
56546 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
56547 +
56548 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56549 + SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER);
56550 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56551 +
56552 + if (p_FmPort->imEn)
56553 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56554 + ("available for non-independent mode ports only"));
56555 +
56556 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56557 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56558 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56559 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56560 + ("available for Rx and offline parsing ports only"));
56561 +
56562 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56563 + {
56564 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56565 + return ERROR_CODE(E_BUSY);
56566 + }
56567 +
56568 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56569 + ASSERT_COND(p_FmPort->h_FmPcd);
56570 +
56571 + if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree)
56572 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
56573 + ("Tree handle must be given if CC is required"));
56574 +
56575 + memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams));
56576 + p_PcdParams = &modifiedPcdParams;
56577 + if ((p_PcdParams->h_IpReassemblyManip)
56578 +#if (DPAA_VERSION >= 11)
56579 + || (p_PcdParams->h_CapwapReassemblyManip)
56580 +#endif /* (DPAA_VERSION >= 11) */
56581 + )
56582 + {
56583 + if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56584 + && (p_PcdParams->pcdSupport
56585 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC)
56586 + && (p_PcdParams->pcdSupport
56587 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR)
56588 + && (p_PcdParams->pcdSupport
56589 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))
56590 + {
56591 + RELEASE_LOCK(p_FmPort->lock);
56592 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56593 + ("pcdSupport must have KG for supporting Reassembly"));
56594 + }
56595 + p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip;
56596 +#if (DPAA_VERSION >= 11)
56597 + if ((p_PcdParams->h_IpReassemblyManip)
56598 + && (p_PcdParams->h_CapwapReassemblyManip))
56599 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56600 + ("Either IP-R or CAPWAP-R is allowed"));
56601 + if ((p_PcdParams->h_CapwapReassemblyManip)
56602 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56603 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56604 + ("CAPWAP-R is allowed only on offline-port"));
56605 + if (p_PcdParams->h_CapwapReassemblyManip)
56606 + p_FmPort->h_CapwapReassemblyManip =
56607 + p_PcdParams->h_CapwapReassemblyManip;
56608 +#endif /* (DPAA_VERSION >= 11) */
56609 +
56610 + if (!p_PcdParams->p_CcParams)
56611 + {
56612 + if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56613 + || (p_PcdParams->pcdSupport
56614 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)))
56615 + {
56616 + RELEASE_LOCK(p_FmPort->lock);
56617 + RETURN_ERROR(
56618 + MAJOR,
56619 + E_INVALID_STATE,
56620 + ("PCD initialization structure is not consistent with pcdSupport"));
56621 + }
56622 +
56623 + /* No user-tree, need to build internal tree */
56624 + p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc(
56625 + sizeof(t_FmPcdCcTreeParams));
56626 + if (!p_FmPcdCcTreeParams)
56627 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams"));
56628 + memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams));
56629 + p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv;
56630 + p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild(
56631 + p_FmPort->h_FmPcd, p_FmPcdCcTreeParams);
56632 +
56633 + if (!p_FmPort->h_ReassemblyTree)
56634 + {
56635 + RELEASE_LOCK(p_FmPort->lock);
56636 + XX_Free(p_FmPcdCcTreeParams);
56637 + RETURN_ERROR( MAJOR, E_INVALID_HANDLE,
56638 + ("FM_PCD_CcBuildTree for Reassembly failed"));
56639 + }
56640 + if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56641 + p_PcdParams->pcdSupport =
56642 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC;
56643 + else
56644 + p_PcdParams->pcdSupport =
56645 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR;
56646 +
56647 + memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams));
56648 + fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree;
56649 + p_PcdParams->p_CcParams = &fmPortPcdCcParams;
56650 + XX_Free(p_FmPcdCcTreeParams);
56651 + }
56652 +
56653 + if (p_FmPort->h_IpReassemblyManip)
56654 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd,
56655 + p_PcdParams->p_CcParams->h_CcTree,
56656 + p_PcdParams->h_NetEnv,
56657 + p_FmPort->h_IpReassemblyManip, TRUE);
56658 +#if (DPAA_VERSION >= 11)
56659 + else
56660 + if (p_FmPort->h_CapwapReassemblyManip)
56661 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd,
56662 + p_PcdParams->p_CcParams->h_CcTree,
56663 + p_PcdParams->h_NetEnv,
56664 + p_FmPort->h_CapwapReassemblyManip,
56665 + TRUE);
56666 +#endif /* (DPAA_VERSION >= 11) */
56667 +
56668 + if (err != E_OK)
56669 + {
56670 + if (p_FmPort->h_ReassemblyTree)
56671 + {
56672 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56673 + p_FmPort->h_ReassemblyTree = NULL;
56674 + }RELEASE_LOCK(p_FmPort->lock);
56675 + RETURN_ERROR(MAJOR, err, NO_MSG);
56676 + }
56677 + }
56678 +
56679 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
56680 + {
56681 + if (p_FmPort->h_ReassemblyTree)
56682 + {
56683 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56684 + p_FmPort->h_ReassemblyTree = NULL;
56685 + }RELEASE_LOCK(p_FmPort->lock);
56686 + DBG(TRACE, ("Try LockAll - BUSY"));
56687 + return ERROR_CODE(E_BUSY);
56688 + }
56689 +
56690 + err = SetPcd(h_FmPort, p_PcdParams);
56691 + if (err)
56692 + {
56693 + if (p_FmPort->h_ReassemblyTree)
56694 + {
56695 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56696 + p_FmPort->h_ReassemblyTree = NULL;
56697 + }
56698 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56699 + RELEASE_LOCK(p_FmPort->lock);
56700 + RETURN_ERROR(MAJOR, err, NO_MSG);
56701 + }
56702 +
56703 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
56704 + && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
56705 + {
56706 + err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
56707 + p_FmPort->hardwarePortId, TRUE);
56708 + if (err)
56709 + {
56710 + DeletePcd(p_FmPort);
56711 + if (p_FmPort->h_ReassemblyTree)
56712 + {
56713 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56714 + p_FmPort->h_ReassemblyTree = NULL;
56715 + }
56716 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56717 + RELEASE_LOCK(p_FmPort->lock);
56718 + RETURN_ERROR(MAJOR, err, NO_MSG);
56719 + }
56720 + p_FmPort->includeInPrsStatistics = TRUE;
56721 + }
56722 +
56723 + FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
56724 +
56725 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56726 + {
56727 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
56728 +
56729 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56730 + {
56731 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
56732 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
56733 + (p_FmPort->pcdEngines & FM_PCD_KG))
56734 + {
56735 + int i;
56736 + for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
56737 + /* The following function must be locked */
56738 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd,
56739 + p_PcdParams->p_KgParams->h_Schemes[i],
56740 + UPDATE_KG_NIA_CC_WA,
56741 + 0);
56742 + }
56743 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
56744 +
56745 +#if (DPAA_VERSION >= 11)
56746 + {
56747 + t_FmPcdCtrlParamsPage *p_ParamsPage;
56748 +
56749 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
56750 + (void**)&p_ParamsPage);
56751 + ASSERT_COND(p_ParamsPage);
56752 + WRITE_UINT32(p_ParamsPage->postBmiFetchNia,
56753 + p_FmPort->savedBmiNia);
56754 + }
56755 +#endif /* (DPAA_VERSION >= 11) */
56756 +
56757 + /* Set post-bmi-fetch nia */
56758 + p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK;
56759 + p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH
56760 + | NIA_ENG_FM_CTL);
56761 +
56762 + /* Set pre-bmi-fetch nia */
56763 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
56764 +#if (DPAA_VERSION >= 11)
56765 + fmPortGetSetCcParams.setCcParams.nia =
56766 + (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL);
56767 +#else
56768 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL);
56769 +#endif /* (DPAA_VERSION >= 11) */
56770 + if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams))
56771 + != E_OK)
56772 + {
56773 + DeletePcd(p_FmPort);
56774 + if (p_FmPort->h_ReassemblyTree)
56775 + {
56776 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56777 + p_FmPort->h_ReassemblyTree = NULL;
56778 + }
56779 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56780 + RELEASE_LOCK(p_FmPort->lock);
56781 + RETURN_ERROR(MAJOR, err, NO_MSG);
56782 + }
56783 + }
56784 +
56785 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56786 +
56787 + /* Set pop-to-next-step nia */
56788 +#if (DPAA_VERSION == 10)
56789 + if (p_FmPort->fmRevInfo.majorRev < 6)
56790 + {
56791 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
56792 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
56793 + }
56794 + else
56795 + {
56796 +#endif /* (DPAA_VERSION == 10) */
56797 + fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE;
56798 +#if (DPAA_VERSION == 10)
56799 + }
56800 +#endif /* (DPAA_VERSION == 10) */
56801 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56802 + != E_OK)
56803 + {
56804 + DeletePcd(p_FmPort);
56805 + if (p_FmPort->h_ReassemblyTree)
56806 + {
56807 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56808 + p_FmPort->h_ReassemblyTree = NULL;
56809 + }RELEASE_LOCK(p_FmPort->lock);
56810 + RETURN_ERROR(MAJOR, err, NO_MSG);
56811 + }
56812 +
56813 + /* Set post-bmi-prepare-to-enq nia */
56814 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
56815 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ
56816 + | NIA_ENG_FM_CTL);
56817 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56818 + != E_OK)
56819 + {
56820 + DeletePcd(p_FmPort);
56821 + if (p_FmPort->h_ReassemblyTree)
56822 + {
56823 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56824 + p_FmPort->h_ReassemblyTree = NULL;
56825 + }RELEASE_LOCK(p_FmPort->lock);
56826 + RETURN_ERROR(MAJOR, err, NO_MSG);
56827 + }
56828 +
56829 + if ((p_FmPort->h_IpReassemblyManip)
56830 + || (p_FmPort->h_CapwapReassemblyManip))
56831 + {
56832 +#if (DPAA_VERSION == 10)
56833 + if (p_FmPort->fmRevInfo.majorRev < 6)
56834 + {
56835 + /* Overwrite post-bmi-prepare-to-enq nia */
56836 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
56837 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR);
56838 + fmPortGetSetCcParams.setCcParams.overwrite = TRUE;
56839 + }
56840 + else
56841 + {
56842 +#endif /* (DPAA_VERSION == 10) */
56843 + /* Set the ORR bit (for order-restoration) */
56844 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE;
56845 + fmPortGetSetCcParams.setCcParams.nia =
56846 + fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR;
56847 +#if (DPAA_VERSION == 10)
56848 + }
56849 +#endif /* (DPAA_VERSION == 10) */
56850 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56851 + != E_OK)
56852 + {
56853 + DeletePcd(p_FmPort);
56854 + if (p_FmPort->h_ReassemblyTree)
56855 + {
56856 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56857 + p_FmPort->h_ReassemblyTree = NULL;
56858 + }RELEASE_LOCK(p_FmPort->lock);
56859 + RETURN_ERROR(MAJOR, err, NO_MSG);
56860 + }
56861 + }
56862 + }
56863 + else
56864 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56865 +
56866 +#if (DPAA_VERSION >= 11)
56867 + {
56868 + t_FmPcdCtrlParamsPage *p_ParamsPage;
56869 +
56870 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
56871 +
56872 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE;
56873 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56874 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP
56875 + | NIA_ENG_FM_CTL;
56876 + else
56877 + fmPortGetSetCcParams.setCcParams.nia =
56878 + NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
56879 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56880 + != E_OK)
56881 + {
56882 + DeletePcd(p_FmPort);
56883 + if (p_FmPort->h_ReassemblyTree)
56884 + {
56885 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56886 + p_FmPort->h_ReassemblyTree = NULL;
56887 + }RELEASE_LOCK(p_FmPort->lock);
56888 + RETURN_ERROR(MAJOR, err, NO_MSG);
56889 + }
56890 +
56891 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
56892 + (void**)&p_ParamsPage);
56893 + ASSERT_COND(p_ParamsPage);
56894 +
56895 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56896 + WRITE_UINT32(
56897 + p_ParamsPage->misc,
56898 + GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN);
56899 +
56900 + if ((p_FmPort->h_IpReassemblyManip)
56901 + || (p_FmPort->h_CapwapReassemblyManip))
56902 + {
56903 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56904 + WRITE_UINT32(
56905 + p_ParamsPage->discardMask,
56906 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
56907 + else
56908 + WRITE_UINT32(
56909 + p_ParamsPage->discardMask,
56910 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm));
56911 + }
56912 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
56913 + if (p_FmPort->vspe)
56914 + WRITE_UINT32(
56915 + p_ParamsPage->misc,
56916 + GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK));
56917 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
56918 + }
56919 +#endif /* (DPAA_VERSION >= 11) */
56920 +
56921 + err = AttachPCD(h_FmPort);
56922 + if (err)
56923 + {
56924 + DeletePcd(p_FmPort);
56925 + if (p_FmPort->h_ReassemblyTree)
56926 + {
56927 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56928 + p_FmPort->h_ReassemblyTree = NULL;
56929 + }RELEASE_LOCK(p_FmPort->lock);
56930 + RETURN_ERROR(MAJOR, err, NO_MSG);
56931 + }
56932 +
56933 + RELEASE_LOCK(p_FmPort->lock);
56934 +
56935 + return err;
56936 +}
56937 +
56938 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
56939 +{
56940 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56941 + t_Error err = E_OK;
56942 +
56943 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56944 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56945 +
56946 + if (p_FmPort->imEn)
56947 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56948 + ("available for non-independant mode ports only"));
56949 +
56950 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56951 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56952 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56953 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56954 + ("available for Rx and offline parsing ports only"));
56955 +
56956 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56957 + {
56958 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56959 + return ERROR_CODE(E_BUSY);
56960 + }
56961 +
56962 + err = DetachPCD(h_FmPort);
56963 + if (err)
56964 + {
56965 + RELEASE_LOCK(p_FmPort->lock);
56966 + RETURN_ERROR(MAJOR, err, NO_MSG);
56967 + }
56968 +
56969 + FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
56970 +
56971 + /* we do it anyway, instead of checking if included */
56972 + if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics)
56973 + {
56974 + FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
56975 + p_FmPort->hardwarePortId, FALSE);
56976 + p_FmPort->includeInPrsStatistics = FALSE;
56977 + }
56978 +
56979 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
56980 + {
56981 + RELEASE_LOCK(p_FmPort->lock);
56982 + DBG(TRACE, ("Try LockAll - BUSY"));
56983 + return ERROR_CODE(E_BUSY);
56984 + }
56985 +
56986 + err = DeletePcd(h_FmPort);
56987 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56988 + if (err)
56989 + {
56990 + RELEASE_LOCK(p_FmPort->lock);
56991 + RETURN_ERROR(MAJOR, err, NO_MSG);
56992 + }
56993 +
56994 + if (p_FmPort->h_ReassemblyTree)
56995 + {
56996 + err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56997 + if (err)
56998 + {
56999 + RELEASE_LOCK(p_FmPort->lock);
57000 + RETURN_ERROR(MAJOR, err, NO_MSG);
57001 + }
57002 + p_FmPort->h_ReassemblyTree = NULL;
57003 + }RELEASE_LOCK(p_FmPort->lock);
57004 +
57005 + return err;
57006 +}
57007 +
57008 +t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort,
57009 + t_FmPcdPortSchemesParams *p_PortScheme)
57010 +{
57011 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57012 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
57013 + t_Error err = E_OK;
57014 + uint32_t tmpScmVec = 0;
57015 + int i;
57016 +
57017 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57018 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57019 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
57020 + E_INVALID_STATE);
57021 +
57022 + schemeBind.netEnvId = p_FmPort->netEnvId;
57023 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
57024 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
57025 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
57026 + for (i = 0; i < schemeBind.numOfSchemes; i++)
57027 + {
57028 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
57029 + p_PortScheme->h_Schemes[i]);
57030 + /* build vector */
57031 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
57032 + }
57033 +
57034 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57035 + {
57036 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57037 + return ERROR_CODE(E_BUSY);
57038 + }
57039 +
57040 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
57041 + if (err == E_OK)
57042 + p_FmPort->schemesPerPortVector |= tmpScmVec;
57043 +
57044 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
57045 + if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) &&
57046 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
57047 + (p_FmPort->fmRevInfo.majorRev < 6))
57048 + {
57049 + for (i=0; i<p_PortScheme->numOfSchemes; i++)
57050 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0);
57051 + }
57052 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
57053 +
57054 + RELEASE_LOCK(p_FmPort->lock);
57055 +
57056 + return err;
57057 +}
57058 +
57059 +t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort,
57060 + t_FmPcdPortSchemesParams *p_PortScheme)
57061 +{
57062 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57063 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
57064 + t_Error err = E_OK;
57065 + uint32_t tmpScmVec = 0;
57066 + int i;
57067 +
57068 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57069 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57070 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
57071 + E_INVALID_STATE);
57072 +
57073 + schemeBind.netEnvId = p_FmPort->netEnvId;
57074 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
57075 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
57076 + for (i = 0; i < schemeBind.numOfSchemes; i++)
57077 + {
57078 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
57079 + p_PortScheme->h_Schemes[i]);
57080 + /* build vector */
57081 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
57082 + }
57083 +
57084 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57085 + {
57086 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57087 + return ERROR_CODE(E_BUSY);
57088 + }
57089 +
57090 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
57091 + if (err == E_OK)
57092 + p_FmPort->schemesPerPortVector &= ~tmpScmVec;
57093 + RELEASE_LOCK(p_FmPort->lock);
57094 +
57095 + return err;
57096 +}
57097 +
57098 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort,
57099 + t_FmPortCongestionGrps *p_CongestionGrps)
57100 +{
57101 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57102 + uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS];
57103 + uint8_t mod, index;
57104 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
57105 + int err;
57106 +#if (DPAA_VERSION >= 11)
57107 + int j;
57108 +#endif /* (DPAA_VERSION >= 11) */
57109 +
57110 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57111 +
57112 + /* un-necessary check of the indexes; probably will be needed in the future when there
57113 + will be more CGs available ....
57114 + for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57115 + if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS)
57116 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!"));
57117 + */
57118 +
57119 +#ifdef FM_NO_OP_OBSERVED_CGS
57120 + if ((p_FmPort->fmRevInfo.majorRev != 4) &&
57121 + (p_FmPort->fmRevInfo.majorRev < 6))
57122 + {
57123 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
57124 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57125 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57126 + }
57127 + else
57128 +#endif /* FM_NO_OP_OBSERVED_CGS */
57129 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57130 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57131 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57132 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57133 + ("Available for Rx & OP ports only"));
57134 +
57135 + /* Prepare groups map array */
57136 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57137 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57138 + {
57139 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57140 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57141 + if (p_FmPort->fmRevInfo.majorRev != 4)
57142 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57143 + else
57144 + grpsMap[0] |= (uint32_t)(1 << mod);
57145 + }
57146 +
57147 + memset(&priorityTmpArray, 0,
57148 + FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t));
57149 +
57150 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57151 + {
57152 +#if (DPAA_VERSION >= 11)
57153 + for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++)
57154 + if (p_CongestionGrps->pfcPrioritiesEn[i][j])
57155 + priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |=
57156 + (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1));
57157 +#endif /* (DPAA_VERSION >= 11) */
57158 + }
57159 +
57160 +#if (DPAA_VERSION >= 11)
57161 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++)
57162 + {
57163 + err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i,
57164 + priorityTmpArray[i]);
57165 + if (err)
57166 + return err;
57167 + }
57168 +#endif /* (DPAA_VERSION >= 11) */
57169 +
57170 + err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap);
57171 + if (err != 0)
57172 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps"));
57173 +
57174 + return E_OK;
57175 +}
57176 +
57177 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort,
57178 + t_FmPortCongestionGrps *p_CongestionGrps)
57179 +{
57180 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57181 + uint8_t mod, index;
57182 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
57183 + int err;
57184 +
57185 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57186 +
57187 + {
57188 +#ifdef FM_NO_OP_OBSERVED_CGS
57189 + t_FmRevisionInfo revInfo;
57190 +
57191 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
57192 + if (revInfo.majorRev != 4)
57193 + {
57194 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
57195 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57196 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57197 + }
57198 + else
57199 +#endif /* FM_NO_OP_OBSERVED_CGS */
57200 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57201 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57202 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57203 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57204 + ("Available for Rx & OP ports only"));
57205 + }
57206 +
57207 + /* Prepare groups map array */
57208 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57209 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57210 + {
57211 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57212 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57213 + if (p_FmPort->fmRevInfo.majorRev != 4)
57214 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57215 + else
57216 + grpsMap[0] |= (uint32_t)(1 << mod);
57217 + }
57218 +
57219 +#if (DPAA_VERSION >= 11)
57220 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57221 + {
57222 + t_Error err = FmSetCongestionGroupPFCpriority(
57223 + p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i],
57224 + 0);
57225 + if (err)
57226 + return err;
57227 + }
57228 +#endif /* (DPAA_VERSION >= 11) */
57229 +
57230 + err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap);
57231 + if (err != 0)
57232 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
57233 + ("fman_port_remove_congestion_grps"));
57234 + return E_OK;
57235 +}
57236 +
57237 +#if (DPAA_VERSION >= 11)
57238 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort,
57239 + uint32_t *p_Ipv4OptionsCount)
57240 +{
57241 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57242 +
57243 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57244 + SANITY_CHECK_RETURN_ERROR(
57245 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING),
57246 + E_INVALID_VALUE);
57247 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE);
57248 + SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER);
57249 +
57250 + *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter);
57251 +
57252 + return E_OK;
57253 +}
57254 +#endif /* (DPAA_VERSION >= 11) */
57255 +
57256 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx,
57257 + t_FmPortDsarTablesSizes *params)
57258 +{
57259 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57260 + p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(
57261 + sizeof(struct t_FmPortDsarTablesSizes));
57262 + memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params,
57263 + sizeof(struct t_FmPortDsarTablesSizes));
57264 + return E_OK;
57265 +}
57266 +
57267 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
57268 +{
57269 + uint32_t *param_page;
57270 + t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
57271 + t_ArCommonDesc *ArCommonDescPtr;
57272 + uint32_t size = sizeof(t_ArCommonDesc);
57273 + // ARP
57274 + // should put here if (params->max_num_of_arp_entries)?
57275 + size = ROUND_UP(size,4);
57276 + size += sizeof(t_DsarArpDescriptor);
57277 + size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
57278 + size += sizeof(t_DsarArpStatistics);
57279 + //ICMPV4
57280 + size = ROUND_UP(size,4);
57281 + size += sizeof(t_DsarIcmpV4Descriptor);
57282 + size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
57283 + size += sizeof(t_DsarIcmpV4Statistics);
57284 + //ICMPV6
57285 + size = ROUND_UP(size,4);
57286 + size += sizeof(t_DsarIcmpV6Descriptor);
57287 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
57288 + size += sizeof(t_DsarIcmpV6Statistics);
57289 + //ND
57290 + size = ROUND_UP(size,4);
57291 + size += sizeof(t_DsarNdDescriptor);
57292 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
57293 + size += sizeof(t_DsarIcmpV6Statistics);
57294 + //SNMP
57295 + size = ROUND_UP(size,4);
57296 + size += sizeof(t_DsarSnmpDescriptor);
57297 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57298 + * params->maxNumOfSnmpIPV4Entries;
57299 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57300 + * params->maxNumOfSnmpIPV6Entries;
57301 + size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
57302 + size += params->maxNumOfSnmpOidChar;
57303 + size += sizeof(t_DsarIcmpV6Statistics);
57304 + //filters
57305 + size = ROUND_UP(size,4);
57306 + size += params->maxNumOfIpProtFiltering;
57307 + size = ROUND_UP(size,4);
57308 + size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
57309 + size = ROUND_UP(size,4);
57310 + size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
57311 +
57312 + // add here for more protocols
57313 +
57314 + // statistics
57315 + size = ROUND_UP(size,4);
57316 + size += sizeof(t_ArStatistics);
57317 +
57318 + ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
57319 +
57320 + param_page =
57321 + XX_PhysToVirt(
57322 + p_FmPort->fmMuramPhysBaseAddr
57323 + + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57324 + WRITE_UINT32(
57325 + *param_page,
57326 + (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
57327 + return E_OK;
57328 +}
57329 +
57330 +t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
57331 +{
57332 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57333 + return p_FmPort->deepSleepVars.autoResMaxSizes;
57334 +}
57335 +
57336 +struct arOffsets
57337 +{
57338 + uint32_t arp;
57339 + uint32_t nd;
57340 + uint32_t icmpv4;
57341 + uint32_t icmpv6;
57342 + uint32_t snmp;
57343 + uint32_t stats;
57344 + uint32_t filtIp;
57345 + uint32_t filtUdp;
57346 + uint32_t filtTcp;
57347 +};
57348 +
57349 +static uint32_t AR_ComputeOffsets(struct arOffsets* of,
57350 + struct t_FmPortDsarParams *params,
57351 + t_FmPort *p_FmPort)
57352 +{
57353 + uint32_t size = sizeof(t_ArCommonDesc);
57354 + // ARP
57355 + if (params->p_AutoResArpInfo)
57356 + {
57357 + size = ROUND_UP(size,4);
57358 + of->arp = size;
57359 + size += sizeof(t_DsarArpDescriptor);
57360 + size += sizeof(t_DsarArpBindingEntry)
57361 + * params->p_AutoResArpInfo->tableSize;
57362 + size += sizeof(t_DsarArpStatistics);
57363 + }
57364 + // ICMPV4
57365 + if (params->p_AutoResEchoIpv4Info)
57366 + {
57367 + size = ROUND_UP(size,4);
57368 + of->icmpv4 = size;
57369 + size += sizeof(t_DsarIcmpV4Descriptor);
57370 + size += sizeof(t_DsarIcmpV4BindingEntry)
57371 + * params->p_AutoResEchoIpv4Info->tableSize;
57372 + size += sizeof(t_DsarIcmpV4Statistics);
57373 + }
57374 + // ICMPV6
57375 + if (params->p_AutoResEchoIpv6Info)
57376 + {
57377 + size = ROUND_UP(size,4);
57378 + of->icmpv6 = size;
57379 + size += sizeof(t_DsarIcmpV6Descriptor);
57380 + size += sizeof(t_DsarIcmpV6BindingEntry)
57381 + * params->p_AutoResEchoIpv6Info->tableSize;
57382 + size += sizeof(t_DsarIcmpV6Statistics);
57383 + }
57384 + // ND
57385 + if (params->p_AutoResNdpInfo)
57386 + {
57387 + size = ROUND_UP(size,4);
57388 + of->nd = size;
57389 + size += sizeof(t_DsarNdDescriptor);
57390 + size += sizeof(t_DsarIcmpV6BindingEntry)
57391 + * (params->p_AutoResNdpInfo->tableSizeAssigned
57392 + + params->p_AutoResNdpInfo->tableSizeTmp);
57393 + size += sizeof(t_DsarIcmpV6Statistics);
57394 + }
57395 + // SNMP
57396 + if (params->p_AutoResSnmpInfo)
57397 + {
57398 + size = ROUND_UP(size,4);
57399 + of->snmp = size;
57400 + size += sizeof(t_DsarSnmpDescriptor);
57401 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57402 + * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
57403 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57404 + * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
57405 + size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
57406 + size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
57407 + size += sizeof(t_DsarIcmpV6Statistics);
57408 + }
57409 + //filters
57410 + size = ROUND_UP(size,4);
57411 + if (params->p_AutoResFilteringInfo)
57412 + {
57413 + of->filtIp = size;
57414 + size += params->p_AutoResFilteringInfo->ipProtTableSize;
57415 + size = ROUND_UP(size,4);
57416 + of->filtUdp = size;
57417 + size += params->p_AutoResFilteringInfo->udpPortsTableSize
57418 + * sizeof(t_PortTblEntry);
57419 + size = ROUND_UP(size,4);
57420 + of->filtTcp = size;
57421 + size += params->p_AutoResFilteringInfo->tcpPortsTableSize
57422 + * sizeof(t_PortTblEntry);
57423 + }
57424 + // add here for more protocols
57425 + // statistics
57426 + size = ROUND_UP(size,4);
57427 + of->stats = size;
57428 + size += sizeof(t_ArStatistics);
57429 + return size;
57430 +}
57431 +
57432 +uint32_t* ARDesc;
57433 +void PrsEnable(t_Handle p_FmPcd);
57434 +void PrsDisable(t_Handle p_FmPcd);
57435 +int PrsIsEnabled(t_Handle p_FmPcd);
57436 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
57437 +
57438 +static t_Error DsarCheckParams(t_FmPortDsarParams *params,
57439 + t_FmPortDsarTablesSizes *sizes)
57440 +{
57441 + bool macInit = FALSE;
57442 + uint8_t mac[6];
57443 + int i = 0;
57444 +
57445 + // check table sizes
57446 + if (params->p_AutoResArpInfo
57447 + && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
57448 + RETURN_ERROR(
57449 + MAJOR, E_INVALID_VALUE,
57450 + ("DSAR: Arp table size exceeds the configured maximum size."));
57451 + if (params->p_AutoResEchoIpv4Info
57452 + && sizes->maxNumOfEchoIpv4Entries
57453 + < params->p_AutoResEchoIpv4Info->tableSize)
57454 + RETURN_ERROR(
57455 + MAJOR,
57456 + E_INVALID_VALUE,
57457 + ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
57458 + if (params->p_AutoResNdpInfo
57459 + && sizes->maxNumOfNdpEntries
57460 + < params->p_AutoResNdpInfo->tableSizeAssigned
57461 + + params->p_AutoResNdpInfo->tableSizeTmp)
57462 + RETURN_ERROR(
57463 + MAJOR, E_INVALID_VALUE,
57464 + ("DSAR: NDP table size exceeds the configured maximum size."));
57465 + if (params->p_AutoResEchoIpv6Info
57466 + && sizes->maxNumOfEchoIpv6Entries
57467 + < params->p_AutoResEchoIpv6Info->tableSize)
57468 + RETURN_ERROR(
57469 + MAJOR,
57470 + E_INVALID_VALUE,
57471 + ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
57472 + if (params->p_AutoResSnmpInfo
57473 + && sizes->maxNumOfSnmpOidEntries
57474 + < params->p_AutoResSnmpInfo->oidsTblSize)
57475 + RETURN_ERROR(
57476 + MAJOR,
57477 + E_INVALID_VALUE,
57478 + ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
57479 + if (params->p_AutoResSnmpInfo
57480 + && sizes->maxNumOfSnmpIPV4Entries
57481 + < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
57482 + RETURN_ERROR(
57483 + MAJOR,
57484 + E_INVALID_VALUE,
57485 + ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
57486 + if (params->p_AutoResSnmpInfo
57487 + && sizes->maxNumOfSnmpIPV6Entries
57488 + < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
57489 + RETURN_ERROR(
57490 + MAJOR,
57491 + E_INVALID_VALUE,
57492 + ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
57493 + if (params->p_AutoResFilteringInfo)
57494 + {
57495 + if (sizes->maxNumOfIpProtFiltering
57496 + < params->p_AutoResFilteringInfo->ipProtTableSize)
57497 + RETURN_ERROR(
57498 + MAJOR,
57499 + E_INVALID_VALUE,
57500 + ("DSAR: ip filter table size exceeds the configured maximum size."));
57501 + if (sizes->maxNumOfTcpPortFiltering
57502 + < params->p_AutoResFilteringInfo->udpPortsTableSize)
57503 + RETURN_ERROR(
57504 + MAJOR,
57505 + E_INVALID_VALUE,
57506 + ("DSAR: udp filter table size exceeds the configured maximum size."));
57507 + if (sizes->maxNumOfUdpPortFiltering
57508 + < params->p_AutoResFilteringInfo->tcpPortsTableSize)
57509 + RETURN_ERROR(
57510 + MAJOR,
57511 + E_INVALID_VALUE,
57512 + ("DSAR: tcp filter table size exceeds the configured maximum size."));
57513 + }
57514 + /* check only 1 MAC address is configured (this is what ucode currently supports) */
57515 + if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
57516 + {
57517 + memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
57518 + i = 1;
57519 + macInit = TRUE;
57520 +
57521 + for (; i < params->p_AutoResArpInfo->tableSize; i++)
57522 + if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
57523 + RETURN_ERROR(
57524 + MAJOR, E_INVALID_VALUE,
57525 + ("DSAR: Only 1 mac address is currently supported."));
57526 + }
57527 + if (params->p_AutoResEchoIpv4Info
57528 + && params->p_AutoResEchoIpv4Info->tableSize)
57529 + {
57530 + i = 0;
57531 + if (!macInit)
57532 + {
57533 + memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac,
57534 + 6);
57535 + i = 1;
57536 + macInit = TRUE;
57537 + }
57538 + for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57539 + if (memcmp(mac,
57540 + params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
57541 + RETURN_ERROR(
57542 + MAJOR, E_INVALID_VALUE,
57543 + ("DSAR: Only 1 mac address is currently supported."));
57544 + }
57545 + if (params->p_AutoResEchoIpv6Info
57546 + && params->p_AutoResEchoIpv6Info->tableSize)
57547 + {
57548 + i = 0;
57549 + if (!macInit)
57550 + {
57551 + memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac,
57552 + 6);
57553 + i = 1;
57554 + macInit = TRUE;
57555 + }
57556 + for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57557 + if (memcmp(mac,
57558 + params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
57559 + RETURN_ERROR(
57560 + MAJOR, E_INVALID_VALUE,
57561 + ("DSAR: Only 1 mac address is currently supported."));
57562 + }
57563 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
57564 + {
57565 + i = 0;
57566 + if (!macInit)
57567 + {
57568 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac,
57569 + 6);
57570 + i = 1;
57571 + macInit = TRUE;
57572 + }
57573 + for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
57574 + if (memcmp(mac,
57575 + params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac,
57576 + 6))
57577 + RETURN_ERROR(
57578 + MAJOR, E_INVALID_VALUE,
57579 + ("DSAR: Only 1 mac address is currently supported."));
57580 + }
57581 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
57582 + {
57583 + i = 0;
57584 + if (!macInit)
57585 + {
57586 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
57587 + i = 1;
57588 + }
57589 + for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
57590 + if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac,
57591 + 6))
57592 + RETURN_ERROR(
57593 + MAJOR, E_INVALID_VALUE,
57594 + ("DSAR: Only 1 mac address is currently supported."));
57595 + }
57596 + return E_OK;
57597 +}
57598 +
57599 +static int GetBERLen(uint8_t* buf)
57600 +{
57601 + if (*buf & 0x80)
57602 + {
57603 + if ((*buf & 0x7F) == 1)
57604 + return buf[1];
57605 + else
57606 + return *(uint16_t*)&buf[1]; // assuming max len is 2
57607 + }
57608 + else
57609 + return buf[0];
57610 +}
57611 +#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
57612 +
57613 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
57614 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
57615 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
57616 +static int fm_soc_suspend(void)
57617 +{
57618 + uint32_t *fmclk, tmp32;
57619 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57620 + tmp32 = GET_UINT32(*fmclk);
57621 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
57622 + tmp32 = GET_UINT32(*fmclk);
57623 + iounmap(fmclk);
57624 + return 0;
57625 +}
57626 +
57627 +void fm_clk_down(void)
57628 +{
57629 + uint32_t *fmclk, tmp32;
57630 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57631 + tmp32 = GET_UINT32(*fmclk);
57632 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
57633 + tmp32 = GET_UINT32(*fmclk);
57634 + iounmap(fmclk);
57635 +}
57636 +
57637 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
57638 +{
57639 + int i, j;
57640 + t_Error err;
57641 + uint32_t nia;
57642 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57643 + t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
57644 + t_DsarArpDescriptor *ArpDescriptor;
57645 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
57646 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
57647 + t_DsarNdDescriptor* NDDescriptor;
57648 +
57649 + uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
57650 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57651 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
57652 + struct arOffsets* of;
57653 + uint8_t tmp = 0;
57654 + t_FmGetSetParams fmGetSetParams;
57655 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57656 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
57657 + fmGetSetParams.setParams.sleep = 1;
57658 +
57659 + err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
57660 + if (err != E_OK)
57661 + return err;
57662 +
57663 + p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
57664 + of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
57665 + IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
57666 +
57667 + // common
57668 + WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
57669 + nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
57670 + if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
57671 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
57672 + else
57673 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
57674 + WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
57675 +
57676 + // ARP
57677 + if (params->p_AutoResArpInfo)
57678 + {
57679 + t_DsarArpBindingEntry* arp_bindings;
57680 + ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
57681 + WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
57682 + arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
57683 + if (params->p_AutoResArpInfo->enableConflictDetection)
57684 + WRITE_UINT16(ArpDescriptor->control, 1);
57685 + else
57686 + WRITE_UINT16(ArpDescriptor->control, 0);
57687 + if (params->p_AutoResArpInfo->tableSize)
57688 + {
57689 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
57690 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57691 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57692 + WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
57693 +
57694 + for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
57695 + {
57696 + WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57697 + if (arp_entry[i].isVlan)
57698 + WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57699 + }
57700 + WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
57701 + }
57702 + WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
57703 + sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
57704 + }
57705 +
57706 + // ICMPV4
57707 + if (params->p_AutoResEchoIpv4Info)
57708 + {
57709 + t_DsarIcmpV4BindingEntry* icmpv4_bindings;
57710 + ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
57711 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
57712 + icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
57713 + WRITE_UINT16(ICMPV4Descriptor->control, 0);
57714 + if (params->p_AutoResEchoIpv4Info->tableSize)
57715 + {
57716 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
57717 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57718 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57719 + WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
57720 +
57721 + for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57722 + {
57723 + WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57724 + if (arp_entry[i].isVlan)
57725 + WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57726 + }
57727 + WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
57728 + }
57729 + WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
57730 + sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
57731 + }
57732 +
57733 + // ICMPV6
57734 + if (params->p_AutoResEchoIpv6Info)
57735 + {
57736 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
57737 + ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
57738 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
57739 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
57740 + WRITE_UINT16(ICMPV6Descriptor->control, 0);
57741 + if (params->p_AutoResEchoIpv6Info->tableSize)
57742 + {
57743 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
57744 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
57745 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
57746 + WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
57747 +
57748 + for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57749 + {
57750 + for (j = 0; j < 4; j++)
57751 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57752 + if (ndp_entry[i].isVlan)
57753 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57754 + }
57755 + WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
57756 + }
57757 + WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
57758 + sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
57759 + }
57760 +
57761 + // ND
57762 + if (params->p_AutoResNdpInfo)
57763 + {
57764 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
57765 + NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
57766 + WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
57767 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
57768 + if (params->p_AutoResNdpInfo->enableConflictDetection)
57769 + WRITE_UINT16(NDDescriptor->control, 1);
57770 + else
57771 + WRITE_UINT16(NDDescriptor->control, 0);
57772 + if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
57773 + {
57774 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
57775 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
57776 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
57777 + WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
57778 + + params->p_AutoResNdpInfo->tableSizeTmp);
57779 +
57780 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
57781 + {
57782 + for (j = 0; j < 4; j++)
57783 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57784 + if (ndp_entry[i].isVlan)
57785 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57786 + }
57787 + ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
57788 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
57789 + {
57790 + for (j = 0; j < 4; j++)
57791 + WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57792 + if (ndp_entry[i].isVlan)
57793 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57794 + }
57795 + WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
57796 + }
57797 + WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
57798 + * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
57799 + - fmMuramVirtBaseAddr);
57800 + WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
57801 + }
57802 +
57803 + // SNMP
57804 + if (params->p_AutoResSnmpInfo)
57805 + {
57806 + t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
57807 + t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
57808 + t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
57809 + t_OidsTblEntry* snmpOid;
57810 + uint8_t *charPointer;
57811 + int len;
57812 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
57813 + WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
57814 + WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
57815 + WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
57816 + snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
57817 + if (snmpSrc->numOfIpv4Addresses)
57818 + {
57819 + t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
57820 + WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
57821 + for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
57822 + {
57823 + WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
57824 + if (snmpIpv4AddrSrc[i].isVlan)
57825 + WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
57826 + }
57827 + WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
57828 + }
57829 + snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
57830 + + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
57831 + if (snmpSrc->numOfIpv6Addresses)
57832 + {
57833 + t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
57834 + WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
57835 + for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
57836 + {
57837 + for (j = 0; j < 4; j++)
57838 + WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
57839 + if (snmpIpv6AddrSrc[i].isVlan)
57840 + WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
57841 + }
57842 + WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
57843 + }
57844 + snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
57845 + + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
57846 + charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
57847 + + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
57848 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
57849 + Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
57850 + WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57851 + charPointer += len;
57852 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
57853 + Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
57854 + WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57855 + charPointer += len;
57856 + WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
57857 + WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
57858 + for (i = 0; i < snmpSrc->oidsTblSize; i++)
57859 + {
57860 + WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
57861 + WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
57862 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize);
57863 + WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57864 + charPointer += snmpSrc->p_OidsTbl[i].oidSize;
57865 + if (snmpSrc->p_OidsTbl[i].resSize <= 4)
57866 + WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal);
57867 + else
57868 + {
57869 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize);
57870 + WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57871 + charPointer += snmpSrc->p_OidsTbl[i].resSize;
57872 + }
57873 + snmpOid++;
57874 + }
57875 + charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
57876 + WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57877 + }
57878 +
57879 + // filtering
57880 + if (params->p_AutoResFilteringInfo)
57881 + {
57882 + if (params->p_AutoResFilteringInfo->ipProtPassOnHit)
57883 + tmp |= IP_PROT_TBL_PASS_MASK;
57884 + if (params->p_AutoResFilteringInfo->udpPortPassOnHit)
57885 + tmp |= UDP_PORT_TBL_PASS_MASK;
57886 + if (params->p_AutoResFilteringInfo->tcpPortPassOnHit)
57887 + tmp |= TCP_PORT_TBL_PASS_MASK;
57888 + WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
57889 + WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask);
57890 +
57891 + // ip filtering
57892 + if (params->p_AutoResFilteringInfo->ipProtTableSize)
57893 + {
57894 + uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
57895 + WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
57896 + for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
57897 + WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
57898 + WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
57899 + }
57900 +
57901 + // udp filtering
57902 + if (params->p_AutoResFilteringInfo->udpPortsTableSize)
57903 + {
57904 + t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
57905 + WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
57906 + for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
57907 + {
57908 + WRITE_UINT32(udp_tbl[i].Ports,
57909 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
57910 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
57911 + WRITE_UINT32(udp_tbl[i].PortsMask,
57912 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
57913 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
57914 + }
57915 + WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
57916 + }
57917 +
57918 + // tcp filtering
57919 + if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
57920 + {
57921 + t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
57922 + WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
57923 + for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
57924 + {
57925 + WRITE_UINT32(tcp_tbl[i].Ports,
57926 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
57927 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
57928 + WRITE_UINT32(tcp_tbl[i].PortsMask,
57929 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
57930 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
57931 + }
57932 + WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
57933 + }
57934 + }
57935 + // common stats
57936 + WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
57937 +
57938 + // get into Deep Sleep sequence:
57939 +
57940 + // Ensures that FMan do not enter the idle state. This is done by programing
57941 + // FMDPSLPCR[FM_STOP] to one.
57942 + fm_soc_suspend();
57943 +
57944 + ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
57945 + return E_OK;
57946 +
57947 +}
57948 +
57949 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
57950 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
57951 +{
57952 + t_FmGetSetParams fmGetSetParams;
57953 + t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
57954 + t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
57955 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
57956 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
57957 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57958 + fmGetSetParams.setParams.type = UPDATE_FM_CLD;
57959 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57960 +
57961 + /* Issue graceful stop to HC port */
57962 + FM_PORT_Disable(p_FmPortHc);
57963 +
57964 + // config tx port
57965 + p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
57966 + 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);
57967 + // ????
57968 + p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
57969 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
57970 + // Stage 7:echo
57971 + p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
57972 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
57973 + if (!PrsIsEnabled(h_FmPcd))
57974 + {
57975 + p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
57976 + PrsEnable(h_FmPcd);
57977 + }
57978 + else
57979 + p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
57980 +
57981 + p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
57982 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
57983 +
57984 + // save rcfg for restoring: accumulate mode is changed by ucode
57985 + p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
57986 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
57987 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57988 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
57989 + fmGetSetParams.setParams.sleep = 1;
57990 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57991 +
57992 +// ***** issue external request sync command
57993 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57994 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
57995 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57996 + // get
57997 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57998 + fmGetSetParams.getParams.type = GET_FMFP_EXTC;
57999 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58000 + if (fmGetSetParams.getParams.fmfp_extc != 0)
58001 + {
58002 + // clear
58003 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58004 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
58005 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58006 +}
58007 +
58008 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58009 + fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI;
58010 + do
58011 + {
58012 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58013 + } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0);
58014 + if (fmGetSetParams.getParams.fm_npi != 0)
58015 + XX_Print("FM: Sync did not finish\n");
58016 +
58017 + // check that all stoped
58018 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58019 + fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
58020 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58021 + while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
58022 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58023 + if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
58024 + XX_Print("FM: Sleeping\n");
58025 +// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
58026 +
58027 + return E_OK;
58028 +}
58029 +
58030 +EXPORT_SYMBOL(FM_PORT_EnterDsarFinal);
58031 +
58032 +void FM_PORT_Dsar_DumpRegs()
58033 +{
58034 + uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
58035 + DUMP_MEMORY(hh, 0x220);
58036 +}
58037 +
58038 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
58039 +{
58040 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58041 + t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
58042 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
58043 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
58044 + t_FmGetSetParams fmGetSetParams;
58045 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58046 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
58047 + fmGetSetParams.setParams.sleep = 0;
58048 + if (p_FmPort->deepSleepVars.autoResOffsets)
58049 + {
58050 + XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
58051 + p_FmPort->deepSleepVars.autoResOffsets = 0;
58052 + }
58053 +
58054 + if (p_FmPort->deepSleepVars.dsarEnabledParser)
58055 + PrsDisable(FmGetPcd(p_FmPort->h_Fm));
58056 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
58057 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
58058 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg);
58059 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58060 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
58061 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
58062 + FM_PORT_Enable(p_FmPortHc);
58063 +}
58064 +
58065 +bool FM_PORT_IsInDsar(t_Handle h_FmPort)
58066 +{
58067 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
58068 + return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
58069 +}
58070 +
58071 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
58072 +{
58073 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58074 + struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
58075 + uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
58076 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
58077 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
58078 + t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
58079 + t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58080 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
58081 + t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
58082 + t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
58083 + t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58084 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
58085 + t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
58086 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
58087 + t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58088 + stats->arpArCnt = arp_stats->arCnt;
58089 + stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
58090 + stats->ndpArCnt = nd_stats->arCnt;
58091 + stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
58092 + stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
58093 + stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
58094 + return E_OK;
58095 +}
58096 --- /dev/null
58097 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
58098 @@ -0,0 +1,999 @@
58099 +/*
58100 + * Copyright 2008-2012 Freescale Semiconductor Inc.
58101 + *
58102 + * Redistribution and use in source and binary forms, with or without
58103 + * modification, are permitted provided that the following conditions are met:
58104 + * * Redistributions of source code must retain the above copyright
58105 + * notice, this list of conditions and the following disclaimer.
58106 + * * Redistributions in binary form must reproduce the above copyright
58107 + * notice, this list of conditions and the following disclaimer in the
58108 + * documentation and/or other materials provided with the distribution.
58109 + * * Neither the name of Freescale Semiconductor nor the
58110 + * names of its contributors may be used to endorse or promote products
58111 + * derived from this software without specific prior written permission.
58112 + *
58113 + *
58114 + * ALTERNATIVELY, this software may be distributed under the terms of the
58115 + * GNU General Public License ("GPL") as published by the Free Software
58116 + * Foundation, either version 2 of that License or (at your option) any
58117 + * later version.
58118 + *
58119 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
58120 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
58121 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
58122 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
58123 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
58124 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58125 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58126 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58127 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58128 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58129 + */
58130 +
58131 +
58132 +/******************************************************************************
58133 + @File fm_port.h
58134 +
58135 + @Description FM Port internal structures and definitions.
58136 +*//***************************************************************************/
58137 +#ifndef __FM_PORT_H
58138 +#define __FM_PORT_H
58139 +
58140 +#include "error_ext.h"
58141 +#include "std_ext.h"
58142 +#include "fm_port_ext.h"
58143 +
58144 +#include "fm_common.h"
58145 +#include "fm_sp_common.h"
58146 +#include "fsl_fman_sp.h"
58147 +#include "fm_port_ext.h"
58148 +#include "fsl_fman_port.h"
58149 +
58150 +#define __ERR_MODULE__ MODULE_FM_PORT
58151 +
58152 +
58153 +#define MIN_EXT_BUF_SIZE 64
58154 +#define DATA_ALIGNMENT 64
58155 +#define MAX_LIODN_OFFSET 64
58156 +#define MAX_PORT_FIFO_SIZE MIN(BMI_MAX_FIFO_SIZE, 1024*BMI_FIFO_UNITS)
58157 +
58158 +/**************************************************************************//**
58159 + @Description Memory Map defines
58160 +*//***************************************************************************/
58161 +#define BMI_PORT_REGS_OFFSET 0
58162 +#define QMI_PORT_REGS_OFFSET 0x400
58163 +#define PRS_PORT_REGS_OFFSET 0x800
58164 +
58165 +/**************************************************************************//**
58166 + @Description defaults
58167 +*//***************************************************************************/
58168 +#define DEFAULT_PORT_deqHighPriority_1G FALSE
58169 +#define DEFAULT_PORT_deqHighPriority_10G TRUE
58170 +#define DEFAULT_PORT_deqType e_FM_PORT_DEQ_TYPE1
58171 +#define DEFAULT_PORT_deqPrefetchOption e_FM_PORT_DEQ_FULL_PREFETCH
58172 +#define DEFAULT_PORT_deqPrefetchOption_HC e_FM_PORT_DEQ_NO_PREFETCH
58173 +#define DEFAULT_PORT_deqByteCnt_10G 0x1400
58174 +#define DEFAULT_PORT_deqByteCnt_1G 0x400
58175 +#define DEFAULT_PORT_bufferPrefixContent_privDataSize DEFAULT_FM_SP_bufferPrefixContent_privDataSize
58176 +#define DEFAULT_PORT_bufferPrefixContent_passPrsResult DEFAULT_FM_SP_bufferPrefixContent_passPrsResult
58177 +#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp
58178 +#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo
58179 +#define DEFAULT_PORT_bufferPrefixContent_dataAlign DEFAULT_FM_SP_bufferPrefixContent_dataAlign
58180 +#define DEFAULT_PORT_cheksumLastBytesIgnore 0
58181 +#define DEFAULT_PORT_cutBytesFromEnd 4
58182 +#define DEFAULT_PORT_fifoDeqPipelineDepth_IM 2
58183 +
58184 +#define DEFAULT_PORT_frmDiscardOverride FALSE
58185 +
58186 +#define DEFAULT_PORT_dmaSwapData (e_FmDmaSwapOption)DEFAULT_FMAN_SP_DMA_SWAP_DATA
58187 +#define DEFAULT_PORT_dmaIntContextCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR
58188 +#define DEFAULT_PORT_dmaHeaderCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR
58189 +#define DEFAULT_PORT_dmaScatterGatherCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR
58190 +#define DEFAULT_PORT_dmaWriteOptimize DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE
58191 +
58192 +#define DEFAULT_PORT_noScatherGather DEFAULT_FMAN_SP_NO_SCATTER_GATHER
58193 +#define DEFAULT_PORT_forwardIntContextReuse FALSE
58194 +#define DEFAULT_PORT_BufMargins_startMargins 32
58195 +#define DEFAULT_PORT_BufMargins_endMargins 0
58196 +#define DEFAULT_PORT_syncReq TRUE
58197 +#define DEFAULT_PORT_syncReqForHc FALSE
58198 +#define DEFAULT_PORT_color e_FM_PORT_COLOR_GREEN
58199 +#define DEFAULT_PORT_errorsToDiscard FM_PORT_FRM_ERR_CLS_DISCARD
58200 +/* #define DEFAULT_PORT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE */
58201 +/* #define DEFAULT_PORT_rateLimitBurstSizeHighGranularity FALSE */
58202 +#define DEFAULT_PORT_exception IM_EV_BSY
58203 +#define DEFAULT_PORT_maxFrameLength 9600
58204 +
58205 +#define DEFAULT_notSupported 0xff
58206 +
58207 +#if (DPAA_VERSION < 11)
58208 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58209 +#define DEFAULT_PORT_rxFifoThreshold (MAX_PORT_FIFO_SIZE*3/4)
58210 +
58211 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58212 +#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE)
58213 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 1
58214 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58215 +
58216 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58217 +
58218 +/* Host command port MUST NOT be changed to more than 1 !!! */
58219 +#define DEFAULT_PORT_numOfTasks(type) \
58220 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58221 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 16 : \
58222 + ((((type) == e_FM_PORT_TYPE_RX) || \
58223 + ((type) == e_FM_PORT_TYPE_TX) || \
58224 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 3 : 1))
58225 +
58226 +#define DEFAULT_PORT_extraNumOfTasks(type) \
58227 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58228 + (((type) == e_FM_PORT_TYPE_RX) ? 2 : 0))
58229 +
58230 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58231 + (uint32_t)((((type) == e_FM_PORT_TYPE_TX_10G) || \
58232 + ((type) == e_FM_PORT_TYPE_RX_10G)) ? 8 : 1 )
58233 +
58234 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) \
58235 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58236 + (((type) == e_FM_PORT_TYPE_RX) ? 1 : 0))
58237 +
58238 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58239 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58240 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 48 : \
58241 + ((type) == e_FM_PORT_TYPE_RX) ? 45 : \
58242 + ((type) == e_FM_PORT_TYPE_TX) ? 44 : 8)
58243 +
58244 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58245 +
58246 +#else /* (DPAA_VERSION < 11) */
58247 +/* Defaults are registers' reset values */
58248 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58249 +#define DEFAULT_PORT_rxFifoThreshold MAX_PORT_FIFO_SIZE
58250 +
58251 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58252 +#define DEFAULT_PORT_txFifoLowComfLevel (5 * KILOBYTE)
58253 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 2
58254 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58255 +
58256 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58257 +
58258 +#define DEFAULT_PORT_numOfTasks(type) \
58259 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58260 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 14 : \
58261 + (((type) == e_FM_PORT_TYPE_RX) || \
58262 + ((type) == e_FM_PORT_TYPE_TX)) ? 4 : \
58263 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? 6 : 1)
58264 +
58265 +#define DEFAULT_PORT_extraNumOfTasks(type) 0
58266 +
58267 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58268 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58269 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 12 : \
58270 + ((type) == e_FM_PORT_TYPE_RX) ? 2 : \
58271 + ((type) == e_FM_PORT_TYPE_TX) ? 3 : \
58272 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 2 : 4)
58273 +
58274 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) 0
58275 +
58276 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58277 + (uint32_t) (((type) == e_FM_PORT_TYPE_RX_10G) ? 96 : \
58278 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 64 : \
58279 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 10 : 50)
58280 +
58281 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58282 +
58283 +#endif /* (DPAA_VERSION < 11) */
58284 +
58285 +#define DEFAULT_PORT_txBdRingLength 16
58286 +#define DEFAULT_PORT_rxBdRingLength 128
58287 +#define DEFAULT_PORT_ImfwExtStructsMemId 0
58288 +#define DEFAULT_PORT_ImfwExtStructsMemAttr MEMORY_ATTR_CACHEABLE
58289 +
58290 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58291 +
58292 +/**************************************************************************//**
58293 + @Collection PCD Engines
58294 +*//***************************************************************************/
58295 +typedef uint32_t fmPcdEngines_t; /**< options as defined below: */
58296 +
58297 +#define FM_PCD_NONE 0 /**< No PCD Engine indicated */
58298 +#define FM_PCD_PRS 0x80000000 /**< Parser indicated */
58299 +#define FM_PCD_KG 0x40000000 /**< Keygen indicated */
58300 +#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */
58301 +#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */
58302 +#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */
58303 +/* @} */
58304 +
58305 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8
58306 +#define FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256
58307 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58308 +
58309 +#define FM_OH_PORT_ID 0
58310 +
58311 +/***********************************************************************/
58312 +/* SW parser OFFLOAD labels (offsets) */
58313 +/***********************************************************************/
58314 +#if (DPAA_VERSION == 10)
58315 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x300
58316 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x325
58317 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x325
58318 +#else
58319 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x100
58320 +/* Will be used for:
58321 + * 1. identify fragments
58322 + * 2. udp-lite
58323 + */
58324 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x146
58325 +/* Will be used for:
58326 + * 1. will identify the fragmentable area
58327 + * 2. udp-lite
58328 + */
58329 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x261
58330 +#define OFFLOAD_SW_PATCH_CAPWAP_LABEL 0x38d
58331 +#endif /* (DPAA_VERSION == 10) */
58332 +
58333 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
58334 +#define UDP_LITE_SW_PATCH_LABEL 0x2E0
58335 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
58336 +
58337 +
58338 +/**************************************************************************//**
58339 + @Description Memory Mapped Registers
58340 +*//***************************************************************************/
58341 +
58342 +#if defined(__MWERKS__) && !defined(__GNUC__)
58343 +#pragma pack(push,1)
58344 +#endif /* defined(__MWERKS__) && ... */
58345 +
58346 +typedef struct
58347 +{
58348 + volatile uint32_t fmbm_rcfg; /**< Rx Configuration */
58349 + volatile uint32_t fmbm_rst; /**< Rx Status */
58350 + volatile uint32_t fmbm_rda; /**< Rx DMA attributes*/
58351 + volatile uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
58352 + volatile uint32_t fmbm_rfed; /**< Rx Frame End Data*/
58353 + volatile uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
58354 + volatile uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
58355 + volatile uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
58356 + volatile uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
58357 + volatile uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
58358 + volatile uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
58359 + volatile uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
58360 + volatile uint32_t fmbm_rpp; /**< Rx Policer Profile */
58361 + volatile uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
58362 + volatile uint32_t fmbm_reth; /**< Rx Excessive Threshold */
58363 + volatile uint32_t reserved1[0x01];/**< (0x03C) */
58364 + volatile uint32_t fmbm_rprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58365 + /**< Rx Parse Results Array Initialization*/
58366 + volatile uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
58367 + volatile uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
58368 + volatile uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
58369 + volatile uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
58370 + volatile uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
58371 + volatile uint32_t reserved2[0x02];/**< (0x074-0x078) */
58372 + volatile uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
58373 + volatile uint32_t reserved3[0x20];/**< (0x080 0x0FF) */
58374 + volatile uint32_t fmbm_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58375 + /**< Buffer Manager pool Information-*/
58376 + volatile uint32_t fmbm_acnt[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58377 + /**< Allocate Counter-*/
58378 + volatile uint32_t reserved4[0x08];
58379 + /**< 0x130/0x140 - 0x15F reserved -*/
58380 + volatile uint32_t fmbm_rcgm[FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32];
58381 + /**< Congestion Group Map*/
58382 + volatile uint32_t fmbm_rmpd; /**< BM Pool Depletion */
58383 + volatile uint32_t reserved5[0x1F];/**< (0x184 0x1FF) */
58384 + volatile uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
58385 + volatile uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
58386 + volatile uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
58387 + volatile uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
58388 + volatile uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
58389 + volatile uint32_t fmbm_rfcd; /**< Rx Frame Discard Counter*/
58390 + volatile uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
58391 + volatile uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard Counter-*/
58392 + volatile uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter-*/
58393 + volatile uint32_t fmbm_rpec; /**< Rx RX Prepare to enqueue Counter-*/
58394 + volatile uint32_t reserved6[0x16];/**< (0x228 0x27F) */
58395 + volatile uint32_t fmbm_rpc; /**< Rx Performance Counters*/
58396 + volatile uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
58397 + volatile uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
58398 + volatile uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
58399 + volatile uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization Counter*/
58400 + volatile uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
58401 + volatile uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
58402 + volatile uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
58403 + volatile uint32_t reserved7[0x18];/**< (0x2A0-0x2FF) */
58404 + volatile uint32_t fmbm_rdcfg[0x3];/**< Rx Debug-*/
58405 + volatile uint32_t fmbm_rgpr; /**< Rx General Purpose Register. */
58406 + volatile uint32_t reserved8[0x3a];/**< (0x310-0x3FF) */
58407 +} t_FmPortRxBmiRegs;
58408 +
58409 +typedef struct
58410 +{
58411 + volatile uint32_t fmbm_tcfg; /**< Tx Configuration */
58412 + volatile uint32_t fmbm_tst; /**< Tx Status */
58413 + volatile uint32_t fmbm_tda; /**< Tx DMA attributes */
58414 + volatile uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
58415 + volatile uint32_t fmbm_tfed; /**< Tx Frame End Data */
58416 + volatile uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
58417 + volatile uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
58418 + volatile uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
58419 + volatile uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
58420 + volatile uint32_t fmbm_tfeqid; /**< Tx Frame Error Queue ID */
58421 + volatile uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
58422 + volatile uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
58423 + volatile uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
58424 + volatile uint32_t fmbm_tccb; /**< Tx Coarse Classification Base */
58425 + volatile uint32_t reserved0[0x0e];/**< (0x038-0x070) */
58426 + volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
58427 + volatile uint32_t fmbm_tpfcm[0x02];/**< Tx Priority based Flow Control (PFC) Mapping */
58428 + volatile uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
58429 + volatile uint32_t reserved2[0x60];/**< (0x080-0x200) */
58430 + volatile uint32_t fmbm_tstc; /**< Tx Statistics Counters */
58431 + volatile uint32_t fmbm_tfrc; /**< Tx Frame Counter */
58432 + volatile uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
58433 + volatile uint32_t fmbm_tfledc; /**< Tx Frame Length error discard counter */
58434 + volatile uint32_t fmbm_tfufdc; /**< Tx Frame unsupported format discard Counter */
58435 + volatile uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
58436 + volatile uint32_t reserved3[0x1A];/**< (0x218-0x280) */
58437 + volatile uint32_t fmbm_tpc; /**< Tx Performance Counters*/
58438 + volatile uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
58439 + volatile uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
58440 + volatile uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
58441 + volatile uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/
58442 + volatile uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
58443 + volatile uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
58444 + volatile uint32_t reserved4[16]; /**< (0x29C-0x2FF) */
58445 + volatile uint32_t fmbm_tdcfg[0x3];/**< Tx Debug-*/
58446 + volatile uint32_t fmbm_tgpr; /**< O/H General Purpose Register */
58447 + volatile uint32_t reserved5[0x3a];/**< (0x310-0x3FF) */
58448 +} t_FmPortTxBmiRegs;
58449 +
58450 +typedef struct
58451 +{
58452 + volatile uint32_t fmbm_ocfg; /**< O/H Configuration */
58453 + volatile uint32_t fmbm_ost; /**< O/H Status */
58454 + volatile uint32_t fmbm_oda; /**< O/H DMA attributes */
58455 + volatile uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
58456 + volatile uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
58457 + volatile uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
58458 + volatile uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
58459 + volatile uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
58460 + volatile uint32_t fmbm_opso; /**< O/H Parse Start Offset */
58461 + volatile uint32_t fmbm_opp; /**< O/H Policer Profile */
58462 + volatile uint32_t fmbm_occb; /**< O/H Coarse Classification base */
58463 + volatile uint32_t fmbm_oim; /**< O/H Internal margins*/
58464 + volatile uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
58465 + volatile uint32_t fmbm_ofed; /**< O/H Frame End Data*/
58466 + volatile uint32_t reserved0[2]; /**< (0x038 - 0x03F) */
58467 + volatile uint32_t fmbm_oprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58468 + /**< O/H Parse Results Array Initialization */
58469 + volatile uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
58470 + volatile uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
58471 + volatile uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
58472 + volatile uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
58473 + volatile uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
58474 + volatile uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
58475 + volatile uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
58476 + volatile uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
58477 + volatile uint32_t reserved1[0x20];/**< (0x080 - 0x0FF) */
58478 + volatile uint32_t fmbm_oebmpi[2]; /**< Buffer Manager Observed Pool Information */
58479 + volatile uint32_t reserved2[0x16];/**< (0x108 - 0x15F) */
58480 + volatile uint32_t fmbm_ocgm; /**< Observed Congestion Group Map */
58481 + volatile uint32_t reserved3[0x7]; /**< (0x164 - 0x17F) */
58482 + volatile uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
58483 + volatile uint32_t reserved4[0x1F];/**< (0x184 - 0x1FF) */
58484 + volatile uint32_t fmbm_ostc; /**< O/H Statistics Counters */
58485 + volatile uint32_t fmbm_ofrc; /**< O/H Frame Counter */
58486 + volatile uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
58487 + volatile uint32_t fmbm_ofledc; /**< O/H Frames Length Error Discard Counter */
58488 + volatile uint32_t fmbm_ofufdc; /**< O/H Frames Unsupported Format Discard Counter */
58489 + volatile uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
58490 + volatile uint32_t fmbm_ofwdc; /**< - Rx Frames WRED Discard Counter */
58491 + volatile uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Counter */
58492 + volatile uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
58493 + volatile uint32_t fmbm_oodc; /**< O/H Out of Buffers Discard Counter */
58494 + volatile uint32_t fmbm_opec; /**< O/H Prepare to enqueue Counter */
58495 + volatile uint32_t reserved5[0x15];/**< ( - 0x27F) */
58496 + volatile uint32_t fmbm_opc; /**< O/H Performance Counters */
58497 + volatile uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
58498 + volatile uint32_t fmbm_occn; /**< O/H Cycle Counter */
58499 + volatile uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
58500 + volatile uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
58501 + volatile uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
58502 + volatile uint32_t reserved6[26]; /**< (0x298-0x2FF) */
58503 + volatile uint32_t fmbm_odcfg[0x3];/**< O/H Debug (only 1 in P1023) */
58504 + volatile uint32_t fmbm_ogpr; /**< O/H General Purpose Register. */
58505 + volatile uint32_t reserved7[0x3a];/**< (0x310 0x3FF) */
58506 +} t_FmPortOhBmiRegs;
58507 +
58508 +typedef union
58509 +{
58510 + t_FmPortRxBmiRegs rxPortBmiRegs;
58511 + t_FmPortTxBmiRegs txPortBmiRegs;
58512 + t_FmPortOhBmiRegs ohPortBmiRegs;
58513 +} u_FmPortBmiRegs;
58514 +
58515 +typedef struct
58516 +{
58517 + volatile uint32_t reserved1[2]; /**< 0xn024 - 0x02B */
58518 + volatile uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
58519 + volatile uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
58520 + volatile uint32_t fmqm_pndtfc; /**< PortID n Dequeue Total Frame Counter */
58521 + volatile uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID from Default Counter */
58522 + volatile uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
58523 +} t_FmPortNonRxQmiRegs;
58524 +
58525 +typedef struct
58526 +{
58527 + volatile uint32_t fmqm_pnc; /**< PortID n Configuration Register */
58528 + volatile uint32_t fmqm_pns; /**< PortID n Status Register */
58529 + volatile uint32_t fmqm_pnts; /**< PortID n Task Status Register */
58530 + volatile uint32_t reserved0[4]; /**< 0xn00C - 0xn01B */
58531 + volatile uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
58532 + volatile uint32_t fmqm_pnetfc; /**< PortID n Enqueue Total Frame Counter */
58533 + t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */
58534 +} t_FmPortQmiRegs;
58535 +
58536 +typedef struct
58537 +{
58538 + struct
58539 + {
58540 + volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */
58541 + volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */
58542 + } hdrs[FM_PCD_PRS_NUM_OF_HDRS];
58543 + volatile uint32_t reserved0[0xde];
58544 + volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */
58545 + volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */
58546 +} t_FmPortPrsRegs;
58547 +
58548 +/**************************************************************************//*
58549 + @Description Basic buffer descriptor (BD) structure
58550 +*//***************************************************************************/
58551 +typedef _Packed struct
58552 +{
58553 + volatile uint16_t status;
58554 + volatile uint16_t length;
58555 + volatile uint8_t reserved0[0x6];
58556 + volatile uint8_t reserved1[0x1];
58557 + volatile t_FmPhysAddr buff;
58558 +} _PackedType t_FmImBd;
58559 +
58560 +typedef _Packed struct
58561 +{
58562 + volatile uint16_t gen; /**< tbd */
58563 + volatile uint8_t reserved0[0x1];
58564 + volatile t_FmPhysAddr bdRingBase; /**< tbd */
58565 + volatile uint16_t bdRingSize; /**< tbd */
58566 + volatile uint16_t offsetIn; /**< tbd */
58567 + volatile uint16_t offsetOut; /**< tbd */
58568 + volatile uint8_t reserved1[0x12]; /**< 0x0e - 0x1f */
58569 +} _PackedType t_FmPortImQd;
58570 +
58571 +typedef _Packed struct
58572 +{
58573 + volatile uint32_t mode; /**< Mode register */
58574 + volatile uint32_t rxQdPtr; /**< tbd */
58575 + volatile uint32_t txQdPtr; /**< tbd */
58576 + volatile uint16_t mrblr; /**< tbd */
58577 + volatile uint16_t rxQdBsyCnt; /**< tbd */
58578 + volatile uint8_t reserved0[0x10]; /**< 0x10 - 0x1f */
58579 + t_FmPortImQd rxQd;
58580 + t_FmPortImQd txQd;
58581 + volatile uint8_t reserved1[0xa0]; /**< 0x60 - 0xff */
58582 +} _PackedType t_FmPortImPram;
58583 +
58584 +#if defined(__MWERKS__) && !defined(__GNUC__)
58585 +#pragma pack(pop)
58586 +#endif /* defined(__MWERKS__) && ... */
58587 +
58588 +
58589 +/**************************************************************************//**
58590 + @Description Registers bit fields
58591 +*//***************************************************************************/
58592 +
58593 +/**************************************************************************//**
58594 + @Description BMI defines
58595 +*//***************************************************************************/
58596 +#if (DPAA_VERSION >= 11)
58597 +#define BMI_SP_ID_MASK 0xff000000
58598 +#define BMI_SP_ID_SHIFT 24
58599 +#define BMI_SP_EN 0x01000000
58600 +#endif /* (DPAA_VERSION >= 11) */
58601 +
58602 +#define BMI_PORT_CFG_EN 0x80000000
58603 +#define BMI_PORT_CFG_EN_MACSEC 0x00800000
58604 +#define BMI_PORT_CFG_FDOVR 0x02000000
58605 +#define BMI_PORT_CFG_IM 0x01000000
58606 +#define BMI_PORT_CFG_AM 0x00000040
58607 +#define BMI_PORT_STATUS_BSY 0x80000000
58608 +#define BMI_COUNTERS_EN 0x80000000
58609 +
58610 +#define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000
58611 +#define BMI_PORT_RFNE_FRWD_RPD 0x40000000
58612 +#define BMI_RFNE_FDCS_MASK 0xFF000000
58613 +#define BMI_RFNE_HXS_MASK 0x000000FF
58614 +
58615 +#define BMI_CMD_MR_LEAC 0x00200000
58616 +#define BMI_CMD_MR_SLEAC 0x00100000
58617 +#define BMI_CMD_MR_MA 0x00080000
58618 +#define BMI_CMD_MR_DEAS 0x00040000
58619 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
58620 + BMI_CMD_MR_SLEAC | \
58621 + BMI_CMD_MR_MA | \
58622 + BMI_CMD_MR_DEAS)
58623 +#define BMI_CMD_ATTR_ORDER 0x80000000
58624 +#define BMI_CMD_ATTR_SYNC 0x02000000
58625 +#define BMI_CMD_ATTR_MODE_MISS_ALLIGN_ADDR_EN 0x00080000
58626 +#define BMI_CMD_ATTR_MACCMD_MASK 0x0000ff00
58627 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE 0x00008000
58628 +#define BMI_CMD_ATTR_MACCMD_SECURED 0x00001000
58629 +#define BMI_CMD_ATTR_MACCMD_SC_MASK 0x00000f00
58630 +
58631 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
58632 +#define BMI_STATUS_RX_MASK_UNUSED (uint32_t)(~(FM_PORT_FRM_ERR_DMA | \
58633 + FM_PORT_FRM_ERR_PHYSICAL | \
58634 + FM_PORT_FRM_ERR_SIZE | \
58635 + FM_PORT_FRM_ERR_CLS_DISCARD | \
58636 + FM_PORT_FRM_ERR_EXTRACTION | \
58637 + FM_PORT_FRM_ERR_NO_SCHEME | \
58638 + FM_PORT_FRM_ERR_COLOR_RED | \
58639 + FM_PORT_FRM_ERR_COLOR_YELLOW | \
58640 + FM_PORT_FRM_ERR_ILL_PLCR | \
58641 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58642 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58643 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58644 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58645 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58646 + FM_PORT_FRM_ERR_IPRE | \
58647 + FM_PORT_FRM_ERR_IPR_NCSP | \
58648 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW))
58649 +
58650 +#define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \
58651 + ~(FM_PORT_FRM_ERR_LENGTH | \
58652 + FM_PORT_FRM_ERR_NON_FM | \
58653 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT))
58654 +
58655 +#define BMI_RATE_LIMIT_EN 0x80000000
58656 +#define BMI_RATE_LIMIT_BURST_SIZE_GRAN 0x80000000
58657 +#define BMI_RATE_LIMIT_SCALE_BY_2 0x00000001
58658 +#define BMI_RATE_LIMIT_SCALE_BY_4 0x00000002
58659 +#define BMI_RATE_LIMIT_SCALE_BY_8 0x00000003
58660 +
58661 +#define BMI_RX_FIFO_THRESHOLD_BC 0x80000000
58662 +
58663 +#define BMI_PRS_RESULT_HIGH 0x00000000
58664 +#define BMI_PRS_RESULT_LOW 0xFFFFFFFF
58665 +
58666 +
58667 +#define RX_ERRS_TO_ENQ (FM_PORT_FRM_ERR_DMA | \
58668 + FM_PORT_FRM_ERR_PHYSICAL | \
58669 + FM_PORT_FRM_ERR_SIZE | \
58670 + FM_PORT_FRM_ERR_EXTRACTION | \
58671 + FM_PORT_FRM_ERR_NO_SCHEME | \
58672 + FM_PORT_FRM_ERR_ILL_PLCR | \
58673 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58674 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58675 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58676 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58677 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58678 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW | \
58679 + FM_PORT_FRM_ERR_IPRE)
58680 +
58681 +#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \
58682 + FM_PORT_FRM_ERR_LENGTH | \
58683 + FM_PORT_FRM_ERR_NON_FM | \
58684 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)
58685 +
58686 +
58687 +#define BMI_RX_FIFO_PRI_ELEVATION_MASK 0x03FF0000
58688 +#define BMI_RX_FIFO_THRESHOLD_MASK 0x000003FF
58689 +#define BMI_TX_FIFO_MIN_FILL_MASK 0x03FF0000
58690 +#define BMI_FIFO_PIPELINE_DEPTH_MASK 0x0000F000
58691 +#define BMI_TX_LOW_COMF_MASK 0x000003FF
58692 +
58693 +/* shifts */
58694 +#define BMI_PORT_CFG_MS_SEL_SHIFT 16
58695 +#define BMI_DMA_ATTR_IC_CACHE_SHIFT FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT
58696 +#define BMI_DMA_ATTR_HDR_CACHE_SHIFT FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT
58697 +#define BMI_DMA_ATTR_SG_CACHE_SHIFT FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT
58698 +
58699 +#define BMI_IM_FOF_SHIFT 28
58700 +#define BMI_PR_PORTID_SHIFT 24
58701 +
58702 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
58703 +#define BMI_RX_FIFO_THRESHOLD_SHIFT 0
58704 +
58705 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
58706 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
58707 +
58708 +#define BMI_IC_SIZE_SHIFT FMAN_SP_IC_SIZE_SHIFT
58709 +
58710 +#define BMI_INT_BUF_MARG_SHIFT 28
58711 +
58712 +#define BMI_EXT_BUF_MARG_END_SHIFT FMAN_SP_EXT_BUF_MARG_END_SHIFT
58713 +
58714 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
58715 +#define BMI_CMD_ATTR_COM_MODE_SHIFT 16
58716 +#define BMI_CMD_ATTR_MACCMD_SHIFT 8
58717 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE_SHIFT 15
58718 +#define BMI_CMD_ATTR_MACCMD_SECURED_SHIFT 12
58719 +#define BMI_CMD_ATTR_MACCMD_SC_SHIFT 8
58720 +
58721 +#define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24
58722 +
58723 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
58724 +#define BMI_TX_LOW_COMF_SHIFT 0
58725 +
58726 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
58727 +#define BMI_PERFORMANCE_PORT_COMP_SHIFT 16
58728 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
58729 +#define BMI_PERFORMANCE_FIFO_COMP_SHIFT 0
58730 +
58731 +#define BMI_MAX_BURST_SHIFT 16
58732 +#define BMI_COUNT_RATE_UNIT_SHIFT 16
58733 +
58734 +/* sizes */
58735 +#define FRAME_END_DATA_SIZE 16
58736 +#define FRAME_OFFSET_UNITS 16
58737 +#define MIN_TX_INT_OFFSET 16
58738 +#define MAX_FRAME_OFFSET 64
58739 +#define MAX_FIFO_PIPELINE_DEPTH 8
58740 +#define MAX_PERFORMANCE_TASK_COMP 64
58741 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
58742 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
58743 +#define MAX_PERFORMANCE_DMA_COMP 16
58744 +#define MAX_NUM_OF_TASKS 64
58745 +#define MAX_NUM_OF_EXTRA_TASKS 8
58746 +#define MAX_NUM_OF_DMAS 16
58747 +#define MAX_NUM_OF_EXTRA_DMAS 8
58748 +#define MAX_BURST_SIZE 1024
58749 +#define MIN_NUM_OF_OP_DMAS 2
58750 +
58751 +
58752 +/**************************************************************************//**
58753 + @Description QMI defines
58754 +*//***************************************************************************/
58755 +/* masks */
58756 +#define QMI_PORT_CFG_EN 0x80000000
58757 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
58758 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
58759 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
58760 +
58761 +#define QMI_DEQ_CFG_PREFETCH_NO_TNUM 0x02000000
58762 +#define QMI_DEQ_CFG_PREFETCH_WAITING_TNUM 0
58763 +#define QMI_DEQ_CFG_PREFETCH_1_FRAME 0
58764 +#define QMI_DEQ_CFG_PREFETCH_3_FRAMES 0x01000000
58765 +
58766 +#define QMI_DEQ_CFG_PRI 0x80000000
58767 +#define QMI_DEQ_CFG_TYPE1 0x10000000
58768 +#define QMI_DEQ_CFG_TYPE2 0x20000000
58769 +#define QMI_DEQ_CFG_TYPE3 0x30000000
58770 +
58771 +#define QMI_DEQ_CFG_SUBPORTAL_MASK 0x1f
58772 +#define QMI_DEQ_CFG_SUBPORTAL_SHIFT 20
58773 +
58774 +/**************************************************************************//**
58775 + @Description PARSER defines
58776 +*//***************************************************************************/
58777 +/* masks */
58778 +#define PRS_HDR_ERROR_DIS 0x00000800
58779 +#define PRS_HDR_SW_PRS_EN 0x00000400
58780 +#define PRS_CP_OFFSET_MASK 0x0000000F
58781 +#define PRS_TPID1_MASK 0xFFFF0000
58782 +#define PRS_TPID2_MASK 0x0000FFFF
58783 +#define PRS_TPID_DFLT 0x91009100
58784 +
58785 +#define PRS_HDR_MPLS_LBL_INTER_EN 0x00200000
58786 +#define PRS_HDR_IPV6_ROUTE_HDR_EN 0x00008000
58787 +#define PRS_HDR_PPPOE_MTU_CHECK_EN 0x80000000
58788 +#define PRS_HDR_UDP_PAD_REMOVAL 0x80000000
58789 +#define PRS_HDR_TCP_PAD_REMOVAL 0x80000000
58790 +#define PRS_CAC_STOP 0x00000001
58791 +#define PRS_CAC_ACTIVE 0x00000100
58792 +
58793 +/* shifts */
58794 +#define PRS_PCTPID_SHIFT 16
58795 +#define PRS_HDR_MPLS_NEXT_HDR_SHIFT 22
58796 +#define PRS_HDR_ETH_BC_SHIFT 28
58797 +#define PRS_HDR_ETH_MC_SHIFT 24
58798 +#define PRS_HDR_VLAN_STACKED_SHIFT 16
58799 +#define PRS_HDR_MPLS_STACKED_SHIFT 16
58800 +#define PRS_HDR_IPV4_1_BC_SHIFT 28
58801 +#define PRS_HDR_IPV4_1_MC_SHIFT 24
58802 +#define PRS_HDR_IPV4_2_UC_SHIFT 20
58803 +#define PRS_HDR_IPV4_2_MC_BC_SHIFT 16
58804 +#define PRS_HDR_IPV6_1_MC_SHIFT 24
58805 +#define PRS_HDR_IPV6_2_UC_SHIFT 20
58806 +#define PRS_HDR_IPV6_2_MC_SHIFT 16
58807 +
58808 +#define PRS_HDR_ETH_BC_MASK 0x0fffffff
58809 +#define PRS_HDR_ETH_MC_MASK 0xf0ffffff
58810 +#define PRS_HDR_VLAN_STACKED_MASK 0xfff0ffff
58811 +#define PRS_HDR_MPLS_STACKED_MASK 0xfff0ffff
58812 +#define PRS_HDR_IPV4_1_BC_MASK 0x0fffffff
58813 +#define PRS_HDR_IPV4_1_MC_MASK 0xf0ffffff
58814 +#define PRS_HDR_IPV4_2_UC_MASK 0xff0fffff
58815 +#define PRS_HDR_IPV4_2_MC_BC_MASK 0xfff0ffff
58816 +#define PRS_HDR_IPV6_1_MC_MASK 0xf0ffffff
58817 +#define PRS_HDR_IPV6_2_UC_MASK 0xff0fffff
58818 +#define PRS_HDR_IPV6_2_MC_MASK 0xfff0ffff
58819 +
58820 +/* others */
58821 +#define PRS_HDR_ENTRY_SIZE 8
58822 +#define DEFAULT_CLS_PLAN_VECTOR 0xFFFFFFFF
58823 +
58824 +#define IPSEC_SW_PATCH_START 0x20
58825 +#define SCTP_SW_PATCH_START 0x4D
58826 +#define DCCP_SW_PATCH_START 0x41
58827 +
58828 +/**************************************************************************//**
58829 + @Description IM defines
58830 +*//***************************************************************************/
58831 +#define BD_R_E 0x80000000
58832 +#define BD_L 0x08000000
58833 +
58834 +#define BD_RX_CRE 0x00080000
58835 +#define BD_RX_FTL 0x00040000
58836 +#define BD_RX_FTS 0x00020000
58837 +#define BD_RX_OV 0x00010000
58838 +
58839 +#define BD_RX_ERRORS (BD_RX_CRE | BD_RX_FTL | BD_RX_FTS | BD_RX_OV)
58840 +
58841 +#define FM_IM_SIZEOF_BD sizeof(t_FmImBd)
58842 +
58843 +#define BD_STATUS_MASK 0xffff0000
58844 +#define BD_LENGTH_MASK 0x0000ffff
58845 +
58846 +#define BD_STATUS_AND_LENGTH_SET(bd, val) WRITE_UINT32(*(volatile uint32_t*)(bd), (val))
58847 +
58848 +#define BD_STATUS_AND_LENGTH(bd) GET_UINT32(*(volatile uint32_t*)(bd))
58849 +
58850 +#define BD_GET(id) &p_FmPort->im.p_BdRing[id]
58851 +
58852 +#define IM_ILEGAL_BD_ID 0xffff
58853 +
58854 +/* others */
58855 +#define IM_PRAM_ALIGN 0x100
58856 +
58857 +/* masks */
58858 +#define IM_MODE_GBL 0x20000000
58859 +#define IM_MODE_BO_MASK 0x18000000
58860 +#define IM_MODE_BO_SHIFT 3
58861 +#define IM_MODE_GRC_STP 0x00800000
58862 +
58863 +#define IM_MODE_SET_BO(val) (uint32_t)((val << (31-IM_MODE_BO_SHIFT)) & IM_MODE_BO_MASK)
58864 +
58865 +#define IM_RXQD_BSYINTM 0x0008
58866 +#define IM_RXQD_RXFINTM 0x0010
58867 +#define IM_RXQD_FPMEVT_SEL_MASK 0x0003
58868 +
58869 +#define IM_EV_BSY 0x40000000
58870 +#define IM_EV_RX 0x80000000
58871 +
58872 +
58873 +/**************************************************************************//**
58874 + @Description Additional defines
58875 +*//***************************************************************************/
58876 +
58877 +typedef struct {
58878 + t_Handle h_FmMuram;
58879 + t_FmPortImPram *p_FmPortImPram;
58880 + uint8_t fwExtStructsMemId;
58881 + uint32_t fwExtStructsMemAttr;
58882 + uint16_t bdRingSize;
58883 + t_FmImBd *p_BdRing;
58884 + t_Handle *p_BdShadow;
58885 + uint16_t currBdId;
58886 + uint16_t firstBdOfFrameId;
58887 +
58888 + /* Rx port parameters */
58889 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
58890 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
58891 + t_BufferPoolInfo rxPool;
58892 + uint16_t mrblr;
58893 + uint16_t rxFrameAccumLength;
58894 + t_FmPortImRxStoreCallback *f_RxStore;
58895 +
58896 + /* Tx port parameters */
58897 + uint32_t txFirstBdStatus;
58898 + t_FmPortImTxConfCallback *f_TxConf;
58899 +} t_FmMacIm;
58900 +
58901 +
58902 +typedef struct {
58903 + struct fman_port_cfg dfltCfg;
58904 + uint32_t dfltFqid;
58905 + uint32_t confFqid;
58906 + uint32_t errFqid;
58907 + uintptr_t baseAddr;
58908 + uint8_t deqSubPortal;
58909 + bool deqHighPriority;
58910 + e_FmPortDeqType deqType;
58911 + e_FmPortDeqPrefetchOption deqPrefetchOption;
58912 + uint16_t deqByteCnt;
58913 + uint8_t cheksumLastBytesIgnore;
58914 + uint8_t cutBytesFromEnd;
58915 + t_FmBufPoolDepletion bufPoolDepletion;
58916 + uint8_t pipelineDepth;
58917 + uint16_t fifoLowComfLevel;
58918 + bool frmDiscardOverride;
58919 + bool enRateLimit;
58920 + t_FmPortRateLimit rateLimit;
58921 + e_FmPortDualRateLimiterScaleDown rateLimitDivider;
58922 + bool enBufPoolDepletion;
58923 + uint16_t liodnOffset;
58924 + uint16_t liodnBase;
58925 + t_FmExtPools extBufPools;
58926 + e_FmDmaSwapOption dmaSwapData;
58927 + e_FmDmaCacheOption dmaIntContextCacheAttr;
58928 + e_FmDmaCacheOption dmaHeaderCacheAttr;
58929 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
58930 + bool dmaReadOptimize;
58931 + bool dmaWriteOptimize;
58932 + uint32_t txFifoMinFillLevel;
58933 + uint32_t txFifoLowComfLevel;
58934 + uint32_t rxFifoPriElevationLevel;
58935 + uint32_t rxFifoThreshold;
58936 + t_FmSpBufMargins bufMargins;
58937 + t_FmSpIntContextDataCopy intContext;
58938 + bool syncReq;
58939 + e_FmPortColor color;
58940 + fmPortFrameErrSelect_t errorsToDiscard;
58941 + fmPortFrameErrSelect_t errorsToEnq;
58942 + bool forwardReuseIntContext;
58943 + t_FmBufferPrefixContent bufferPrefixContent;
58944 + t_FmBackupBmPools *p_BackupBmPools;
58945 + bool dontReleaseBuf;
58946 + bool setNumOfTasks;
58947 + bool setNumOfOpenDmas;
58948 + bool setSizeOfFifo;
58949 +#if (DPAA_VERSION >= 11)
58950 + bool noScatherGather;
58951 +#endif /* (DPAA_VERSION >= 11) */
58952 +
58953 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
58954 + bool bcbWorkaround;
58955 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
58956 +} t_FmPortDriverParam;
58957 +
58958 +
58959 +typedef struct t_FmPortRxPoolsParams
58960 +{
58961 + uint8_t numOfPools;
58962 + uint16_t secondLargestBufSize;
58963 + uint16_t largestBufSize;
58964 +} t_FmPortRxPoolsParams;
58965 +
58966 +typedef struct t_FmPortDsarVars {
58967 + t_Handle *autoResOffsets;
58968 + t_FmPortDsarTablesSizes *autoResMaxSizes;
58969 + uint32_t fmbm_tcfg;
58970 + uint32_t fmbm_tcmne;
58971 + uint32_t fmbm_rfne;
58972 + uint32_t fmbm_rfpne;
58973 + uint32_t fmbm_rcfg;
58974 + bool dsarEnabledParser;
58975 +} t_FmPortDsarVars;
58976 +typedef struct {
58977 + struct fman_port port;
58978 + t_Handle h_Fm;
58979 + t_Handle h_FmPcd;
58980 + t_Handle h_FmMuram;
58981 + t_FmRevisionInfo fmRevInfo;
58982 + uint8_t portId;
58983 + e_FmPortType portType;
58984 + int enabled;
58985 + char name[MODULE_NAME_SIZE];
58986 + uint8_t hardwarePortId;
58987 + uint16_t fmClkFreq;
58988 + t_FmPortQmiRegs *p_FmPortQmiRegs;
58989 + u_FmPortBmiRegs *p_FmPortBmiRegs;
58990 + t_FmPortPrsRegs *p_FmPortPrsRegs;
58991 + fmPcdEngines_t pcdEngines;
58992 + uint32_t savedBmiNia;
58993 + uint8_t netEnvId;
58994 + uint32_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
58995 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
58996 + uint8_t privateInfo;
58997 + uint32_t schemesPerPortVector;
58998 + bool useClsPlan;
58999 + uint8_t clsPlanGrpId;
59000 + t_Handle ccTreeId;
59001 + t_Handle completeArg;
59002 + void (*f_Complete)(t_Handle arg);
59003 + t_FmSpBufferOffsets bufferOffsets;
59004 + /* Independent-Mode parameters support */
59005 + bool imEn;
59006 + t_FmMacIm im;
59007 + volatile bool lock;
59008 + t_Handle h_Spinlock;
59009 + t_FmPortExceptionCallback *f_Exception;
59010 + t_Handle h_App;
59011 + uint8_t internalBufferOffset;
59012 + uint8_t fmanCtrlEventId;
59013 + uint32_t exceptions;
59014 + bool polling;
59015 + t_FmExtPools extBufPools;
59016 + uint32_t requiredAction;
59017 + uint32_t savedQmiPnen;
59018 + uint32_t savedBmiFene;
59019 + uint32_t savedBmiFpne;
59020 + uint32_t savedBmiCmne;
59021 + uint32_t savedBmiOfp;
59022 + uint32_t savedNonRxQmiRegsPndn;
59023 + uint32_t origNonRxQmiRegsPndn;
59024 + int savedPrsStartOffset;
59025 + bool includeInPrsStatistics;
59026 + uint16_t maxFrameLength;
59027 + t_FmFmanCtrl orFmanCtrl;
59028 + t_FmPortRsrc openDmas;
59029 + t_FmPortRsrc tasks;
59030 + t_FmPortRsrc fifoBufs;
59031 + t_FmPortRxPoolsParams rxPoolsParams;
59032 +// bool explicitUserSizeOfFifo;
59033 + t_Handle h_IpReassemblyManip;
59034 + t_Handle h_CapwapReassemblyManip;
59035 + t_Handle h_ReassemblyTree;
59036 + uint64_t fmMuramPhysBaseAddr;
59037 +#if (DPAA_VERSION >= 11)
59038 + bool vspe;
59039 + uint8_t dfltRelativeId;
59040 + e_FmPortGprFuncType gprFunc;
59041 + t_FmPcdCtrlParamsPage *p_ParamsPage;
59042 +#endif /* (DPAA_VERSION >= 11) */
59043 + t_FmPortDsarVars deepSleepVars;
59044 + t_FmPortDriverParam *p_FmPortDriverParam;
59045 +} t_FmPort;
59046 +
59047 +
59048 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams);
59049 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort);
59050 +
59051 +t_Error FmPortImInit(t_FmPort *p_FmPort);
59052 +void FmPortImFree(t_FmPort *p_FmPort);
59053 +
59054 +t_Error FmPortImEnable (t_FmPort *p_FmPort);
59055 +t_Error FmPortImDisable (t_FmPort *p_FmPort);
59056 +t_Error FmPortImRx (t_FmPort *p_FmPort);
59057 +
59058 +void FmPortSetMacsecLcv(t_Handle h_FmPort);
59059 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci);
59060 +
59061 +
59062 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas);
59063 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
59064 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
59065 +
59066 +static __inline__ uint8_t * BdBufferGet (t_PhysToVirt *f_PhysToVirt, t_FmImBd *p_Bd)
59067 +{
59068 + uint64_t physAddr = (uint64_t)((uint64_t)GET_UINT8(p_Bd->buff.high) << 32);
59069 + physAddr |= GET_UINT32(p_Bd->buff.low);
59070 +
59071 + return (uint8_t *)f_PhysToVirt((physAddress_t)(physAddr));
59072 +}
59073 +
59074 +static __inline__ void SET_ADDR(volatile t_FmPhysAddr *fmPhysAddr, uint64_t value)
59075 +{
59076 + WRITE_UINT8(fmPhysAddr->high,(uint8_t)((value & 0x000000ff00000000LL) >> 32));
59077 + WRITE_UINT32(fmPhysAddr->low,(uint32_t)value);
59078 +}
59079 +
59080 +static __inline__ void BdBufferSet(t_VirtToPhys *f_VirtToPhys, t_FmImBd *p_Bd, uint8_t *p_Buffer)
59081 +{
59082 + uint64_t physAddr = (uint64_t)(f_VirtToPhys(p_Buffer));
59083 + SET_ADDR(&p_Bd->buff, physAddr);
59084 +}
59085 +
59086 +static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id)
59087 +{
59088 + if (id < p_FmPort->im.bdRingSize-1)
59089 + return (uint16_t)(id+1);
59090 + else
59091 + return 0;
59092 +}
59093 +
59094 +void FM_PORT_Dsar_DumpRegs(void);
59095 +
59096 +
59097 +#endif /* __FM_PORT_H */
59098 --- /dev/null
59099 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
59100 @@ -0,0 +1,494 @@
59101 +/*
59102 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59103 + *
59104 + * Redistribution and use in source and binary forms, with or without
59105 + * modification, are permitted provided that the following conditions are met:
59106 + * * Redistributions of source code must retain the above copyright
59107 + * notice, this list of conditions and the following disclaimer.
59108 + * * Redistributions in binary form must reproduce the above copyright
59109 + * notice, this list of conditions and the following disclaimer in the
59110 + * documentation and/or other materials provided with the distribution.
59111 + * * Neither the name of Freescale Semiconductor nor the
59112 + * names of its contributors may be used to endorse or promote products
59113 + * derived from this software without specific prior written permission.
59114 + *
59115 + *
59116 + * ALTERNATIVELY, this software may be distributed under the terms of the
59117 + * GNU General Public License ("GPL") as published by the Free Software
59118 + * Foundation, either version 2 of that License or (at your option) any
59119 + * later version.
59120 + *
59121 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59122 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59123 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59124 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59125 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59126 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59127 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59128 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59129 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59130 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59131 + */
59132 +
59133 +/**************************************************************************//**
59134 + @File fm_port_dsar.h
59135 +
59136 + @Description Deep Sleep Auto Response project - common module header file.
59137 +
59138 + Author - Eyal Harari
59139 +
59140 + @Cautions See the FMan Controller spec and design document for more information.
59141 +*//***************************************************************************/
59142 +
59143 +#ifndef __FM_PORT_DSAR_H_
59144 +#define __FM_PORT_DSAR_H_
59145 +
59146 +#define DSAR_GETSER_MASK 0xFF0000FF
59147 +
59148 +#if defined(__MWERKS__) && !defined(__GNUC__)
59149 +#pragma pack(push,1)
59150 +#endif /* defined(__MWERKS__) && ... */
59151 +
59152 +/**************************************************************************//**
59153 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59154 + Refer to the FMan Controller spec for more details.
59155 +*//***************************************************************************/
59156 +typedef _Packed struct
59157 +{
59158 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59159 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59160 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59161 + uint16_t reserved;
59162 +} _PackedType t_DsarArpBindingEntry;
59163 +
59164 +/**************************************************************************//**
59165 + @Description Deep Sleep Auto Response Address Resolution Protocol Statistics Descriptor
59166 + Refer to the FMan Controller spec for more details.
59167 + 0x00 INVAL_CNT Invalid ARP IPv4-Ethernet counter
59168 + 0x04 ECHO_CNT Echo counter
59169 + 0x08 CD_CNT Conflict Detection counter
59170 + 0x0C AR_CNT Auto-Response counter
59171 + 0x10 RATM_CNT Replies Addressed To Me counter
59172 + 0x14 UKOP_CNT Unknown Operation counter
59173 + 0x18 NMTP_CNT Not my TPA counter
59174 + 0x1C NMVLAN_CNT Not My VLAN counter
59175 +*//***************************************************************************/
59176 +typedef _Packed struct
59177 +{
59178 + uint32_t invalCnt; /**< Invalid ARP IPv4-Ethernet counter. */
59179 + uint32_t echoCnt; /**< Echo counter. */
59180 + uint32_t cdCnt; /**< Conflict Detection counter. */
59181 + uint32_t arCnt; /**< Auto-Response counter. */
59182 + uint32_t ratmCnt; /**< Replies Addressed To Me counter. */
59183 + uint32_t ukopCnt; /**< Unknown Operation counter. */
59184 + uint32_t nmtpCnt; /**< Not my TPA counter. */
59185 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59186 +} _PackedType t_DsarArpStatistics;
59187 +
59188 +
59189 +/**************************************************************************//**
59190 + @Description Deep Sleep Auto Response Address Resolution Protocol Descriptor
59191 + 0x0 0-15 Control bits [0-15]. Bit 15 = CDEN.
59192 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59193 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an IPv4-MAC Addresses Bindings list.
59194 + 0x6 0-15
59195 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ARP Descriptors statistics data structure.
59196 + 0xA 0-15
59197 + 0xC 0-15 Reserved Reserved. Must be cleared.
59198 + 0xE 015
59199 +
59200 +*//***************************************************************************/
59201 +typedef _Packed struct
59202 +{
59203 + uint16_t control; /** Control bits [0-15]. Bit 15 = CDEN */
59204 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59205 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59206 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59207 + uint32_t reserved1; /**< Reserved. */
59208 +} _PackedType t_DsarArpDescriptor;
59209 +
59210 +
59211 +/**************************************************************************//**
59212 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59213 + Refer to the FMan Controller spec for more details.
59214 +*//***************************************************************************/
59215 +typedef _Packed struct
59216 +{
59217 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59218 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59219 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59220 + uint16_t reserved;
59221 +} _PackedType t_DsarIcmpV4BindingEntry;
59222 +
59223 +/**************************************************************************//**
59224 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59225 + Refer to the FMan Controller spec for more details.
59226 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59227 + 0x04 NMVLAN_CNT Not My VLAN counter
59228 + 0x08 NMIP_CNT Not My IP counter
59229 + 0x0C AR_CNT Auto-Response counter
59230 + 0x10 CSERR_CNT Checksum Error counter
59231 + 0x14 Reserved Reserved
59232 + 0x18 Reserved Reserved
59233 + 0x1C Reserved Reserved
59234 +
59235 +*//***************************************************************************/
59236 +typedef _Packed struct
59237 +{
59238 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59239 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59240 + uint32_t nmIpCnt; /**< Not My IP counter */
59241 + uint32_t arCnt; /**< Auto-Response counter */
59242 + uint32_t cserrCnt; /**< Checksum Error counter */
59243 + uint32_t reserved0; /**< Reserved */
59244 + uint32_t reserved1; /**< Reserved */
59245 + uint32_t reserved2; /**< Reserved */
59246 +} _PackedType t_DsarIcmpV4Statistics;
59247 +
59248 +
59249 +
59250 +/**************************************************************************//**
59251 + @Description Deep Sleep Auto Response ICMPv4 Descriptor
59252 + 0x0 0-15 Control bits [0-15]
59253 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59254 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59255 + 0x6 0-15
59256 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59257 + 0xA 0-15
59258 + 0xC 0-15 Reserved Reserved. Must be cleared.
59259 + 0xE 015
59260 +
59261 +*//***************************************************************************/
59262 +typedef _Packed struct
59263 +{
59264 + uint16_t control; /** Control bits [0-15]. */
59265 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59266 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59267 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59268 + uint32_t reserved1; /**< Reserved. */
59269 +} _PackedType t_DsarIcmpV4Descriptor;
59270 +
59271 +/**************************************************************************//**
59272 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59273 + The 4 left-most bits (15:12) of the VlanId parameter are control flags.
59274 + Flags[3:1] (VlanId[15:13]): Reserved, should be cleared.
59275 + Flags[0] (VlanId[12]): Temporary address.
59276 + \95 0 - Assigned IP address.
59277 + \95 1- Temporary (tentative) IP address.
59278 + Refer to the FMan Controller spec for more details.
59279 +*//***************************************************************************/
59280 +typedef _Packed struct
59281 +{
59282 + uint32_t ipv6Addr[4]; /*!< 3 * 32 bit IPv4 Address. */
59283 + uint16_t resFlags:4; /*!< reserved flags. should be cleared */
59284 + uint16_t vlanId:12; /*!< 12 bits VLAN ID. */
59285 + /*!< This field should be 0x000 for an entry with no VLAN tag or a null VLAN ID. */
59286 + uint16_t reserved;
59287 +} _PackedType t_DsarIcmpV6BindingEntry;
59288 +
59289 +/**************************************************************************//**
59290 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59291 + Refer to the FMan Controller spec for more details.
59292 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59293 + 0x04 NMVLAN_CNT Not My VLAN counter
59294 + 0x08 NMIP_CNT Not My IP counter
59295 + 0x0C AR_CNT Auto-Response counter
59296 + 0x10 CSERR_CNT Checksum Error counter
59297 + 0x14 MCAST_CNT Multicast counter
59298 + 0x18 Reserved Reserved
59299 + 0x1C Reserved Reserved
59300 +
59301 +*//***************************************************************************/
59302 +typedef _Packed struct
59303 +{
59304 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59305 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59306 + uint32_t nmIpCnt; /**< Not My IP counter */
59307 + uint32_t arCnt; /**< Auto-Response counter */
59308 + uint32_t reserved1; /**< Reserved */
59309 + uint32_t reserved2; /**< Reserved */
59310 + uint32_t reserved3; /**< Reserved */
59311 + uint32_t reserved4; /**< Reserved */
59312 +} _PackedType t_DsarIcmpV6Statistics;
59313 +
59314 +/**************************************************************************//**
59315 + @Description Deep Sleep Auto Response Neighbor Discovery Statistics Descriptor
59316 + 0x00 INVAL_CNT Invalid Neighbor Discovery message counter
59317 + 0x04 NMVLAN_CNT Not My VLAN counter
59318 + 0x08 NMIP_CNT Not My IP counter
59319 + 0x0C AR_CNT Auto-Response counter
59320 + 0x10 CSERR_CNT Checksum Error counter
59321 + 0x14 USADVERT_CNT Unsolicited Neighbor Advertisements counter
59322 + 0x18 NMMCAST_CNT Not My Multicast group counter
59323 + 0x1C NSLLA_CNT No Source Link-Layer Address counter. Indicates that there was a match on a Target
59324 + Address of a packet that its source IP address is a unicast address, but the ICMPv6
59325 + Source Link-layer Address option is omitted
59326 +*//***************************************************************************/
59327 +typedef _Packed struct
59328 +{
59329 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59330 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59331 + uint32_t nmIpCnt; /**< Not My IP counter */
59332 + uint32_t arCnt; /**< Auto-Response counter */
59333 + uint32_t reserved1; /**< Reserved */
59334 + uint32_t usadvertCnt; /**< Unsolicited Neighbor Advertisements counter */
59335 + uint32_t nmmcastCnt; /**< Not My Multicast group counter */
59336 + uint32_t nsllaCnt; /**< No Source Link-Layer Address counter */
59337 +} _PackedType t_NdStatistics;
59338 +
59339 +/**************************************************************************//**
59340 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59341 + 0x0 0-15 Control bits [0-15]
59342 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59343 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59344 + 0x6 0-15
59345 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59346 + 0xA 0-15
59347 + 0xC 0-15 Reserved Reserved. Must be cleared.
59348 + 0xE 015
59349 +
59350 +*//***************************************************************************/
59351 +typedef _Packed struct
59352 +{
59353 + uint16_t control; /** Control bits [0-15]. */
59354 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59355 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59356 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59357 + uint32_t reserved1; /**< Reserved. */
59358 +} _PackedType t_DsarIcmpV6Descriptor;
59359 +
59360 +
59361 +/**************************************************************************//**
59362 + @Description Internet Control Message Protocol (ICMPv6) Echo message header
59363 + The fields names are taken from RFC 4443.
59364 +*//***************************************************************************/
59365 +/* 0 1 2 3 */
59366 +/* 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 */
59367 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59368 +/* | Type | Code | Checksum | */
59369 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59370 +/* | Identifier | Sequence Number | */
59371 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59372 +/* | Data ... */
59373 +/* +-+-+-+-+- */
59374 +typedef _Packed struct
59375 +{
59376 + uint8_t type;
59377 + uint8_t code;
59378 + uint16_t checksum;
59379 + uint16_t identifier;
59380 + uint16_t sequenceNumber;
59381 +} _PackedType t_IcmpV6EchoHdr;
59382 +
59383 +/**************************************************************************//**
59384 + @Description Internet Control Message Protocol (ICMPv6)
59385 + Neighbor Solicitation/Advertisement header
59386 + The fields names are taken from RFC 4861.
59387 + The R/S/O fields are valid for Neighbor Advertisement only
59388 +*//***************************************************************************/
59389 +/* 0 1 2 3
59390 + * 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
59391 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59392 + * | Type | Code | Checksum |
59393 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59394 + * |R|S|O| Reserved |
59395 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59396 + * | |
59397 + * + +
59398 + * | |
59399 + * + Target Address +
59400 + * | |
59401 + * + +
59402 + * | |
59403 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59404 + * | Options ...
59405 + * +-+-+-+-+-+-+-+-+-+-+-+-
59406 + *
59407 + * Options Format:
59408 + * 0 1 2 3
59409 + * 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
59410 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59411 + * | Type | Length | Link-Layer Address ... |
59412 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59413 + * | Link-Layer Address |
59414 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59415 +*/
59416 +typedef _Packed struct
59417 +{
59418 + uint8_t type;
59419 + uint8_t code;
59420 + uint16_t checksum;
59421 + uint32_t router:1;
59422 + uint32_t solicited:1;
59423 + uint32_t override:1;
59424 + uint32_t reserved:29;
59425 + uint32_t targetAddr[4];
59426 + uint8_t optionType;
59427 + uint8_t optionLength;
59428 + uint8_t linkLayerAddr[6];
59429 +} _PackedType t_IcmpV6NdHdr;
59430 +
59431 +/**************************************************************************//**
59432 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59433 + 0x0 0-15 Control bits [0-15]
59434 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59435 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59436 + 0x6 0-15
59437 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59438 + 0xA 0-15
59439 + 0xC 0-15 Reserved Reserved. Must be cleared.
59440 + 0xE 015
59441 +
59442 +*//***************************************************************************/
59443 +typedef _Packed struct
59444 +{
59445 + uint16_t control; /** Control bits [0-15]. */
59446 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59447 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59448 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59449 + uint32_t solicitedAddr; /**< Solicited Node Multicast Group Address */
59450 +} _PackedType t_DsarNdDescriptor;
59451 +
59452 +/**************************************************************************//**
59453 +@Description Deep Sleep Auto Response SNMP OIDs table entry
59454 +
59455 +*//***************************************************************************/
59456 +typedef struct {
59457 + uint16_t oidSize; /**< Size in octets of the OID. */
59458 + uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */
59459 + uint32_t p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */
59460 + uint32_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */
59461 + uint32_t reserved;
59462 +} t_OidsTblEntry;
59463 +
59464 +/**************************************************************************//**
59465 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
59466 + Refer to the FMan Controller spec for more details.
59467 +*//***************************************************************************/
59468 +typedef struct
59469 +{
59470 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59471 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59472 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59473 + uint16_t reserved;
59474 +} t_DsarSnmpIpv4AddrTblEntry;
59475 +
59476 +/**************************************************************************//**
59477 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
59478 + Refer to the FMan Controller spec for more details.
59479 +*//***************************************************************************/
59480 +#pragma pack(push,1)
59481 +typedef struct
59482 +{
59483 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
59484 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59485 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59486 + uint16_t reserved;
59487 +} t_DsarSnmpIpv6AddrTblEntry;
59488 +#pragma pack(pop)
59489 +
59490 +/**************************************************************************//**
59491 +@Description Deep Sleep Auto Response SNMP statistics table
59492 +
59493 +*//***************************************************************************/
59494 +typedef struct {
59495 + uint32_t snmpErrCnt; /**< Counts SNMP errors (wrong version, BER encoding, format). */
59496 + uint32_t snmpCommunityErrCnt; /**< Counts messages that were dropped due to insufficient permission. */
59497 + uint32_t snmpTotalDiscardCnt; /**< Counts any message that was dropped. */
59498 + uint32_t snmpGetReqCnt; /**< Counts the number of get-request messages */
59499 + uint32_t snmpGetNextReqCnt; /**< Counts the number of get-next-request messages */
59500 +} t_DsarSnmpStatistics;
59501 +
59502 +/**************************************************************************//**
59503 + @Description Deep Sleep Auto Response SNMP Descriptor
59504 +
59505 +*//***************************************************************************/
59506 +typedef struct
59507 +{
59508 + uint16_t control; /**< Control bits [0-15]. */
59509 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
59510 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
59511 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
59512 + uint32_t p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
59513 + uint32_t p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
59514 + uint32_t p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
59515 + uint32_t p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
59516 + uint32_t p_OidsTbl; /**< Pointer to OIDs table. */
59517 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
59518 + uint32_t p_Statistics; /**< Pointer to SNMP statistics table. */
59519 +} t_DsarSnmpDescriptor;
59520 +
59521 +/**************************************************************************//**
59522 +@Description Deep Sleep Auto Response (Common) Statistics
59523 +
59524 +*//***************************************************************************/
59525 +typedef _Packed struct {
59526 + uint32_t dsarDiscarded;
59527 + uint32_t dsarErrDiscarded;
59528 + uint32_t dsarFragDiscarded;
59529 + uint32_t dsarTunnelDiscarded;
59530 + uint32_t dsarArpDiscarded;
59531 + uint32_t dsarIpDiscarded;
59532 + uint32_t dsarTcpDiscarded;
59533 + uint32_t dsarUdpDiscarded;
59534 + uint32_t dsarIcmpV6ChecksumErr; /* ICMPv6 Checksum Error counter */
59535 + uint32_t dsarIcmpV6OtherType; /* ICMPv6 'Other' type (not Echo or Neighbor Solicitaion/Advertisement counter */
59536 + uint32_t dsarIcmpV4OtherType; /* ICMPv4 'Other' type (not Echo) counter */
59537 +} _PackedType t_ArStatistics;
59538 +
59539 +
59540 +/**************************************************************************//**
59541 +@Description Deep Sleep Auto Response TCP/UDP port filter table entry
59542 +
59543 +*//***************************************************************************/
59544 +typedef _Packed struct {
59545 + uint32_t Ports;
59546 + uint32_t PortsMask;
59547 +} _PackedType t_PortTblEntry;
59548 +
59549 +
59550 +
59551 +/**************************************************************************//**
59552 +@Description Deep Sleep Auto Response Common Parameters Descriptor
59553 +
59554 +*//***************************************************************************/
59555 +typedef _Packed struct {
59556 + uint8_t arTxPort; /* 0x00 0-7 Auto Response Transmit Port number */
59557 + uint8_t controlBits; /* 0x00 8-15 Auto Response control bits */
59558 + uint16_t res1; /* 0x00 16-31 Reserved */
59559 + uint32_t activeHPNIA; /* 0x04 0-31 Active mode Hardware Parser NIA */
59560 + uint16_t snmpPort; /* 0x08 0-15 SNMP Port. */
59561 + uint8_t macStationAddr[6]; /* 0x08 16-31 and 0x0C 0-31 MAC Station Address */
59562 + uint8_t res2; /* 0x10 0-7 Reserved */
59563 + uint8_t filterControl; /* 0x10 8-15 Filtering Control Bits. */
59564 + uint16_t tcpControlPass; /* 0x10 16-31 TCP control pass flags */
59565 + uint8_t ipProtocolTblSize; /* 0x14 0-7 IP Protocol Table Size. */
59566 + uint8_t udpPortTblSize; /* 0x14 8-15 UDP Port Table Size. */
59567 + uint8_t tcpPortTblSize; /* 0x14 16-23 TCP Port Table Size. */
59568 + uint8_t res3; /* 0x14 24-31 Reserved */
59569 + uint32_t p_IpProtocolFiltTbl; /* 0x18 0-31 Pointer to IP Protocol Filter Table */
59570 + uint32_t p_UdpPortFiltTbl; /* 0x1C 0-31 Pointer to UDP Port Filter Table */
59571 + uint32_t p_TcpPortFiltTbl; /* 0x20 0-31 Pointer to TCP Port Filter Table */
59572 + uint32_t res4; /* 0x24 Reserved */
59573 + uint32_t p_ArpDescriptor; /* 0x28 0-31 ARP Descriptor Pointer. */
59574 + uint32_t p_NdDescriptor; /* 0x2C 0-31 Neighbor Discovery Descriptor. */
59575 + uint32_t p_IcmpV4Descriptor; /* 0x30 0-31 ICMPv4 Descriptor pointer. */
59576 + uint32_t p_IcmpV6Descriptor; /* 0x34 0-31 ICMPv6 Descriptor pointer. */
59577 + uint32_t p_SnmpDescriptor; /* 0x38 0-31 SNMP Descriptor pointer. */
59578 + uint32_t p_ArStats; /* 0x3C 0-31 Pointer to Auto Response Statistics */
59579 +} _PackedType t_ArCommonDesc;
59580 +
59581 +#if defined(__MWERKS__) && !defined(__GNUC__)
59582 +#pragma pack(pop)
59583 +#endif /* defined(__MWERKS__) && ... */
59584 +
59585 +/* t_ArCommonDesc.filterControl bits */
59586 +#define IP_PROT_TBL_PASS_MASK 0x08
59587 +#define UDP_PORT_TBL_PASS_MASK 0x04
59588 +#define TCP_PORT_TBL_PASS_MASK 0x02
59589 +
59590 +/* Offset of TCF flags within TCP packet */
59591 +#define TCP_FLAGS_OFFSET 12
59592 +
59593 +
59594 +#endif /* __FM_PORT_DSAR_H_ */
59595 --- /dev/null
59596 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
59597 @@ -0,0 +1,753 @@
59598 +/*
59599 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59600 + *
59601 + * Redistribution and use in source and binary forms, with or without
59602 + * modification, are permitted provided that the following conditions are met:
59603 + * * Redistributions of source code must retain the above copyright
59604 + * notice, this list of conditions and the following disclaimer.
59605 + * * Redistributions in binary form must reproduce the above copyright
59606 + * notice, this list of conditions and the following disclaimer in the
59607 + * documentation and/or other materials provided with the distribution.
59608 + * * Neither the name of Freescale Semiconductor nor the
59609 + * names of its contributors may be used to endorse or promote products
59610 + * derived from this software without specific prior written permission.
59611 + *
59612 + *
59613 + * ALTERNATIVELY, this software may be distributed under the terms of the
59614 + * GNU General Public License ("GPL") as published by the Free Software
59615 + * Foundation, either version 2 of that License or (at your option) any
59616 + * later version.
59617 + *
59618 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59619 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59620 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59621 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59622 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59623 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59624 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59625 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59626 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59627 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59628 + */
59629 +
59630 +
59631 +/******************************************************************************
59632 + @File fm_port_im.c
59633 +
59634 + @Description FM Port Independent-Mode ...
59635 +*//***************************************************************************/
59636 +#include "std_ext.h"
59637 +#include "string_ext.h"
59638 +#include "error_ext.h"
59639 +#include "memcpy_ext.h"
59640 +#include "fm_muram_ext.h"
59641 +
59642 +#include "fm_port.h"
59643 +
59644 +
59645 +#define TX_CONF_STATUS_UNSENT 0x1
59646 +
59647 +
59648 +typedef enum e_TxConfType
59649 +{
59650 + e_TX_CONF_TYPE_CHECK = 0 /**< check if all the buffers were touched by the muxator, no confirmation callback */
59651 + ,e_TX_CONF_TYPE_CALLBACK = 1 /**< confirm to user all the available sent buffers */
59652 + ,e_TX_CONF_TYPE_FLUSH = 3 /**< confirm all buffers plus the unsent one with an appropriate status */
59653 +} e_TxConfType;
59654 +
59655 +
59656 +static void ImException(t_Handle h_FmPort, uint32_t event)
59657 +{
59658 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59659 +
59660 + ASSERT_COND(((event & (IM_EV_RX | IM_EV_BSY)) && FmIsMaster(p_FmPort->h_Fm)) ||
59661 + !FmIsMaster(p_FmPort->h_Fm));
59662 +
59663 + if (event & IM_EV_RX)
59664 + FmPortImRx(p_FmPort);
59665 + if ((event & IM_EV_BSY) && p_FmPort->f_Exception)
59666 + p_FmPort->f_Exception(p_FmPort->h_App, e_FM_PORT_EXCEPTION_IM_BUSY);
59667 +}
59668 +
59669 +
59670 +static t_Error TxConf(t_FmPort *p_FmPort, e_TxConfType confType)
59671 +{
59672 + t_Error retVal = E_BUSY;
59673 + uint32_t bdStatus;
59674 + uint16_t savedStartBdId, confBdId;
59675 +
59676 + ASSERT_COND(p_FmPort);
59677 +
59678 + /*
59679 + if (confType==e_TX_CONF_TYPE_CHECK)
59680 + return (WfqEntryIsQueueEmpty(p_FmPort->im.h_WfqEntry) ? E_OK : E_BUSY);
59681 + */
59682 +
59683 + confBdId = savedStartBdId = p_FmPort->im.currBdId;
59684 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59685 +
59686 + /* If R bit is set, we don't enter, or we break.
59687 + we run till we get to R, or complete the loop */
59688 + while ((!(bdStatus & BD_R_E) || (confType == e_TX_CONF_TYPE_FLUSH)) && (retVal != E_OK))
59689 + {
59690 + if (confType & e_TX_CONF_TYPE_CALLBACK) /* if it is confirmation with user callbacks */
59691 + BD_STATUS_AND_LENGTH_SET(BD_GET(confBdId), 0);
59692 +
59693 + /* case 1: R bit is 0 and Length is set -> confirm! */
59694 + if ((confType & e_TX_CONF_TYPE_CALLBACK) && (bdStatus & BD_LENGTH_MASK))
59695 + {
59696 + if (p_FmPort->im.f_TxConf)
59697 + {
59698 + if ((confType == e_TX_CONF_TYPE_FLUSH) && (bdStatus & BD_R_E))
59699 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59700 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59701 + TX_CONF_STATUS_UNSENT,
59702 + p_FmPort->im.p_BdShadow[confBdId]);
59703 + else
59704 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59705 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59706 + 0,
59707 + p_FmPort->im.p_BdShadow[confBdId]);
59708 + }
59709 + }
59710 + /* case 2: R bit is 0 and Length is 0 -> not used yet, nop! */
59711 +
59712 + confBdId = GetNextBdId(p_FmPort, confBdId);
59713 + if (confBdId == savedStartBdId)
59714 + retVal = E_OK;
59715 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59716 + }
59717 +
59718 + return retVal;
59719 +}
59720 +
59721 +t_Error FmPortImEnable(t_FmPort *p_FmPort)
59722 +{
59723 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59724 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg & ~IM_MODE_GRC_STP));
59725 + return E_OK;
59726 +}
59727 +
59728 +t_Error FmPortImDisable(t_FmPort *p_FmPort)
59729 +{
59730 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59731 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg | IM_MODE_GRC_STP));
59732 + return E_OK;
59733 +}
59734 +
59735 +t_Error FmPortImRx(t_FmPort *p_FmPort)
59736 +{
59737 + t_Handle h_CurrUserPriv, h_NewUserPriv;
59738 + uint32_t bdStatus;
59739 + volatile uint8_t buffPos;
59740 + uint16_t length;
59741 + uint16_t errors;
59742 + uint8_t *p_CurData, *p_Data;
59743 + uint32_t flags;
59744 +
59745 + ASSERT_COND(p_FmPort);
59746 +
59747 + flags = XX_LockIntrSpinlock(p_FmPort->h_Spinlock);
59748 + if (p_FmPort->lock)
59749 + {
59750 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
59751 + return E_OK;
59752 + }
59753 + p_FmPort->lock = TRUE;
59754 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
59755 +
59756 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
59757 +
59758 + while (!(bdStatus & BD_R_E)) /* while there is data in the Rx BD */
59759 + {
59760 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_NewUserPriv)) == NULL)
59761 + {
59762 + p_FmPort->lock = FALSE;
59763 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
59764 + }
59765 +
59766 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
59767 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
59768 +
59769 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
59770 + h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId];
59771 + length = (uint16_t)((bdStatus & BD_L) ?
59772 + ((bdStatus & BD_LENGTH_MASK) - p_FmPort->im.rxFrameAccumLength):
59773 + (bdStatus & BD_LENGTH_MASK));
59774 + p_FmPort->im.rxFrameAccumLength += length;
59775 +
59776 + /* determine whether buffer is first, last, first and last (single */
59777 + /* buffer frame) or middle (not first and not last) */
59778 + buffPos = (uint8_t)((p_FmPort->im.currBdId == p_FmPort->im.firstBdOfFrameId) ?
59779 + ((bdStatus & BD_L) ? SINGLE_BUF : FIRST_BUF) :
59780 + ((bdStatus & BD_L) ? LAST_BUF : MIDDLE_BUF));
59781 +
59782 + if (bdStatus & BD_L)
59783 + {
59784 + p_FmPort->im.rxFrameAccumLength = 0;
59785 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
59786 + }
59787 +
59788 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
59789 +
59790 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), BD_R_E);
59791 +
59792 + errors = (uint16_t)((bdStatus & BD_RX_ERRORS) >> 16);
59793 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_NewUserPriv;
59794 +
59795 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
59796 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4));
59797 + /* Pass the buffer if one of the conditions is true:
59798 + - There are no errors
59799 + - This is a part of a larger frame ( the application has already received some buffers ) */
59800 + if ((buffPos != SINGLE_BUF) || !errors)
59801 + {
59802 + if (p_FmPort->im.f_RxStore(p_FmPort->h_App,
59803 + p_CurData,
59804 + length,
59805 + errors,
59806 + buffPos,
59807 + h_CurrUserPriv) == e_RX_STORE_RESPONSE_PAUSE)
59808 + break;
59809 + }
59810 + else if (p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
59811 + p_CurData,
59812 + h_CurrUserPriv))
59813 + {
59814 + p_FmPort->lock = FALSE;
59815 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Failed freeing data buffer"));
59816 + }
59817 +
59818 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
59819 + }
59820 + p_FmPort->lock = FALSE;
59821 + return E_OK;
59822 +}
59823 +
59824 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams)
59825 +{
59826 + ASSERT_COND(p_FmPort);
59827 +
59828 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
59829 +
59830 + p_FmPort->im.h_FmMuram = p_FmPortParams->specificParams.imRxTxParams.h_FmMuram;
59831 + p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.imRxTxParams.liodnOffset;
59832 + p_FmPort->im.dataMemId = p_FmPortParams->specificParams.imRxTxParams.dataMemId;
59833 + p_FmPort->im.dataMemAttributes = p_FmPortParams->specificParams.imRxTxParams.dataMemAttributes;
59834 +
59835 + p_FmPort->im.fwExtStructsMemId = DEFAULT_PORT_ImfwExtStructsMemId;
59836 + p_FmPort->im.fwExtStructsMemAttr = DEFAULT_PORT_ImfwExtStructsMemAttr;
59837 +
59838 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
59839 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
59840 + {
59841 + p_FmPort->im.rxPool.h_BufferPool = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.h_BufferPool;
59842 + p_FmPort->im.rxPool.f_GetBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_GetBuf;
59843 + p_FmPort->im.rxPool.f_PutBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PutBuf;
59844 + p_FmPort->im.rxPool.bufferSize = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.bufferSize;
59845 + p_FmPort->im.rxPool.f_PhysToVirt = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PhysToVirt;
59846 + if (!p_FmPort->im.rxPool.f_PhysToVirt)
59847 + p_FmPort->im.rxPool.f_PhysToVirt = XX_PhysToVirt;
59848 + p_FmPort->im.rxPool.f_VirtToPhys = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_VirtToPhys;
59849 + if (!p_FmPort->im.rxPool.f_VirtToPhys)
59850 + p_FmPort->im.rxPool.f_VirtToPhys = XX_VirtToPhys;
59851 + p_FmPort->im.f_RxStore = p_FmPortParams->specificParams.imRxTxParams.f_RxStore;
59852 +
59853 + p_FmPort->im.mrblr = 0x8000;
59854 + while (p_FmPort->im.mrblr)
59855 + {
59856 + if (p_FmPort->im.rxPool.bufferSize & p_FmPort->im.mrblr)
59857 + break;
59858 + p_FmPort->im.mrblr >>= 1;
59859 + }
59860 + if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize)
59861 + DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr));
59862 + p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength;
59863 + p_FmPort->exceptions = DEFAULT_PORT_exception;
59864 + if (FmIsMaster(p_FmPort->h_Fm))
59865 + p_FmPort->polling = FALSE;
59866 + else
59867 + p_FmPort->polling = TRUE;
59868 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
59869 + }
59870 + else
59871 + {
59872 + p_FmPort->im.f_TxConf = p_FmPortParams->specificParams.imRxTxParams.f_TxConf;
59873 +
59874 + p_FmPort->im.bdRingSize = DEFAULT_PORT_txBdRingLength;
59875 + }
59876 +}
59877 +
59878 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort)
59879 +{
59880 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) &&
59881 + (p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
59882 + (p_FmPort->portType != e_FM_PORT_TYPE_TX) &&
59883 + (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
59884 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
59885 +
59886 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
59887 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
59888 + {
59889 + if (!POWER_OF_2(p_FmPort->im.mrblr))
59890 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!"));
59891 + if (p_FmPort->im.mrblr < 256)
59892 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!"));
59893 + if (p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK)
59894 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
59895 + }
59896 +
59897 + return E_OK;
59898 +}
59899 +
59900 +t_Error FmPortImInit(t_FmPort *p_FmPort)
59901 +{
59902 + t_FmImBd *p_Bd=NULL;
59903 + t_Handle h_BufContext;
59904 + uint64_t tmpPhysBase;
59905 + uint16_t log2Num;
59906 + uint8_t *p_Data/*, *p_Tmp*/;
59907 + int i;
59908 + t_Error err;
59909 + uint16_t tmpReg16;
59910 + uint32_t tmpReg32;
59911 +
59912 + ASSERT_COND(p_FmPort);
59913 +
59914 + p_FmPort->im.p_FmPortImPram =
59915 + (t_FmPortImPram *)FM_MURAM_AllocMem(p_FmPort->im.h_FmMuram, sizeof(t_FmPortImPram), IM_PRAM_ALIGN);
59916 + if (!p_FmPort->im.p_FmPortImPram)
59917 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Parameter-RAM!!!"));
59918 + WRITE_BLOCK(p_FmPort->im.p_FmPortImPram, 0, sizeof(t_FmPortImPram));
59919 +
59920 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
59921 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
59922 + {
59923 + p_FmPort->im.p_BdRing =
59924 + (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize),
59925 + p_FmPort->im.fwExtStructsMemId,
59926 + 4);
59927 + if (!p_FmPort->im.p_BdRing)
59928 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!"));
59929 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
59930 +
59931 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
59932 + if (!p_FmPort->im.p_BdShadow)
59933 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
59934 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
59935 +
59936 + /* Initialize the Rx-BD ring */
59937 + for (i=0; i<p_FmPort->im.bdRingSize; i++)
59938 + {
59939 + p_Bd = BD_GET(i);
59940 + BD_STATUS_AND_LENGTH_SET (p_Bd, BD_R_E);
59941 +
59942 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_BufContext)) == NULL)
59943 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
59944 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, p_Bd, p_Data);
59945 + p_FmPort->im.p_BdShadow[i] = h_BufContext;
59946 + }
59947 +
59948 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
59949 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
59950 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
59951 + else
59952 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
59953 +
59954 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr,
59955 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
59956 + p_FmPort->fmMuramPhysBaseAddr + 0x20));
59957 +
59958 + LOG2((uint64_t)p_FmPort->im.mrblr, log2Num);
59959 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num);
59960 +
59961 + /* Initialize Rx QD */
59962 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
59963 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->rxQd.bdRingBase, tmpPhysBase);
59964 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
59965 +
59966 + /* Update the IM PRAM address in the BMI */
59967 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid,
59968 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
59969 + p_FmPort->fmMuramPhysBaseAddr));
59970 + if (!p_FmPort->polling || p_FmPort->exceptions)
59971 + {
59972 + /* Allocate, configure and register interrupts */
59973 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
59974 + if (err)
59975 + RETURN_ERROR(MAJOR, err, NO_MSG);
59976 +
59977 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
59978 + tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK);
59979 + tmpReg32 = 0;
59980 +
59981 + if (p_FmPort->exceptions & IM_EV_BSY)
59982 + {
59983 + tmpReg16 |= IM_RXQD_BSYINTM;
59984 + tmpReg32 |= IM_EV_BSY;
59985 + }
59986 + if (!p_FmPort->polling)
59987 + {
59988 + tmpReg16 |= IM_RXQD_RXFINTM;
59989 + tmpReg32 |= IM_EV_RX;
59990 + }
59991 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
59992 +
59993 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException , (t_Handle)p_FmPort);
59994 +
59995 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
59996 + }
59997 + else
59998 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
59999 + }
60000 + else
60001 + {
60002 + p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4);
60003 + if (!p_FmPort->im.p_BdRing)
60004 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Tx BD ring!!!"));
60005 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60006 +
60007 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60008 + if (!p_FmPort->im.p_BdShadow)
60009 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
60010 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60011 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60012 +
60013 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
60014 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
60015 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
60016 + else
60017 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
60018 +
60019 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr,
60020 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60021 + p_FmPort->fmMuramPhysBaseAddr + 0x40));
60022 +
60023 + /* Initialize Tx QD */
60024 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
60025 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->txQd.bdRingBase, tmpPhysBase);
60026 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60027 +
60028 + /* Update the IM PRAM address in the BMI */
60029 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid,
60030 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60031 + p_FmPort->fmMuramPhysBaseAddr));
60032 + }
60033 +
60034 +
60035 + return E_OK;
60036 +}
60037 +
60038 +void FmPortImFree(t_FmPort *p_FmPort)
60039 +{
60040 + uint32_t bdStatus;
60041 + uint8_t *p_CurData;
60042 +
60043 + ASSERT_COND(p_FmPort);
60044 + ASSERT_COND(p_FmPort->im.p_FmPortImPram);
60045 +
60046 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60047 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60048 + {
60049 + if (!p_FmPort->polling || p_FmPort->exceptions)
60050 + {
60051 + /* Deallocate and unregister interrupts */
60052 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
60053 +
60054 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60055 +
60056 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
60057 +
60058 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60059 + }
60060 + /* Try first clean what has received */
60061 + FmPortImRx(p_FmPort);
60062 +
60063 + /* Now, get rid of the the empty buffer! */
60064 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60065 +
60066 + while (bdStatus & BD_R_E) /* while there is data in the Rx BD */
60067 + {
60068 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
60069 +
60070 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), NULL);
60071 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), 0);
60072 +
60073 + p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
60074 + p_CurData,
60075 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
60076 +
60077 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60078 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60079 + }
60080 + }
60081 + else
60082 + TxConf(p_FmPort, e_TX_CONF_TYPE_FLUSH);
60083 +
60084 + FM_MURAM_FreeMem(p_FmPort->im.h_FmMuram, p_FmPort->im.p_FmPortImPram);
60085 +
60086 + if (p_FmPort->im.p_BdShadow)
60087 + XX_Free(p_FmPort->im.p_BdShadow);
60088 +
60089 + if (p_FmPort->im.p_BdRing)
60090 + XX_FreeSmart(p_FmPort->im.p_BdRing);
60091 +}
60092 +
60093 +
60094 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal)
60095 +{
60096 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60097 +
60098 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60099 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60100 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60101 +
60102 + p_FmPort->im.mrblr = newVal;
60103 +
60104 + return E_OK;
60105 +}
60106 +
60107 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
60108 +{
60109 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60110 +
60111 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60112 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60113 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60114 +
60115 + p_FmPort->im.bdRingSize = newVal;
60116 +
60117 + return E_OK;
60118 +}
60119 +
60120 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
60121 +{
60122 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60123 +
60124 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60125 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60126 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60127 +
60128 + p_FmPort->im.bdRingSize = newVal;
60129 +
60130 + return E_OK;
60131 +}
60132 +
60133 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
60134 + uint8_t memId,
60135 + uint32_t memAttributes)
60136 +{
60137 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60138 +
60139 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60140 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60141 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60142 +
60143 + p_FmPort->im.fwExtStructsMemId = memId;
60144 + p_FmPort->im.fwExtStructsMemAttr = memAttributes;
60145 +
60146 + return E_OK;
60147 +}
60148 +
60149 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort)
60150 +{
60151 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60152 +
60153 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60154 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60155 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60156 +
60157 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
60158 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only"));
60159 +
60160 + if (!FmIsMaster(p_FmPort->h_Fm))
60161 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available on master-partition only;"
60162 + "in guest-partitions, IM is always in polling!"));
60163 +
60164 + p_FmPort->polling = TRUE;
60165 +
60166 + return E_OK;
60167 +}
60168 +
60169 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable)
60170 +{
60171 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60172 + t_Error err;
60173 + uint16_t tmpReg16;
60174 + uint32_t tmpReg32;
60175 +
60176 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60177 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60178 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60179 +
60180 + if (exception == e_FM_PORT_EXCEPTION_IM_BUSY)
60181 + {
60182 + if (enable)
60183 + {
60184 + p_FmPort->exceptions |= IM_EV_BSY;
60185 + if (p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ)
60186 + {
60187 + /* Allocate, configure and register interrupts */
60188 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
60189 + if (err)
60190 + RETURN_ERROR(MAJOR, err, NO_MSG);
60191 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
60192 +
60193 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException, (t_Handle)p_FmPort);
60194 + tmpReg16 = (uint16_t)((p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK) | IM_RXQD_BSYINTM);
60195 + tmpReg32 = IM_EV_BSY;
60196 + }
60197 + else
60198 + {
60199 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) | IM_RXQD_BSYINTM);
60200 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) | IM_EV_BSY;
60201 + }
60202 +
60203 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60204 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60205 + }
60206 + else
60207 + {
60208 + p_FmPort->exceptions &= ~IM_EV_BSY;
60209 + if (!p_FmPort->exceptions && p_FmPort->polling)
60210 + {
60211 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60212 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60213 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
60214 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
60215 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60216 + }
60217 + else
60218 + {
60219 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) & ~IM_RXQD_BSYINTM);
60220 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60221 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) & ~IM_EV_BSY;
60222 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60223 + }
60224 + }
60225 + }
60226 + else
60227 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Invalid exception."));
60228 +
60229 + return E_OK;
60230 +}
60231 +
60232 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
60233 + uint8_t *p_Data,
60234 + uint16_t length,
60235 + bool lastBuffer,
60236 + t_Handle h_BufContext)
60237 +{
60238 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60239 + uint16_t nextBdId;
60240 + uint32_t bdStatus, nextBdStatus;
60241 + bool firstBuffer;
60242 +
60243 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60244 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60245 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60246 +
60247 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60248 + nextBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60249 + nextBdStatus = BD_STATUS_AND_LENGTH(BD_GET(nextBdId));
60250 +
60251 + if (!(bdStatus & BD_R_E) && !(nextBdStatus & BD_R_E))
60252 + {
60253 + /* Confirm the current BD - BD is available */
60254 + if ((bdStatus & BD_LENGTH_MASK) && (p_FmPort->im.f_TxConf))
60255 + p_FmPort->im.f_TxConf (p_FmPort->h_App,
60256 + BdBufferGet(XX_PhysToVirt, BD_GET(p_FmPort->im.currBdId)),
60257 + 0,
60258 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
60259 +
60260 + bdStatus = length;
60261 +
60262 + /* if this is the first BD of a frame */
60263 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
60264 + {
60265 + firstBuffer = TRUE;
60266 + p_FmPort->im.txFirstBdStatus = (bdStatus | BD_R_E);
60267 +
60268 + if (!lastBuffer)
60269 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
60270 + }
60271 + else
60272 + firstBuffer = FALSE;
60273 +
60274 + BdBufferSet(XX_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
60275 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_BufContext;
60276 +
60277 + /* deal with last */
60278 + if (lastBuffer)
60279 + {
60280 + /* if single buffer frame */
60281 + if (firstBuffer)
60282 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), p_FmPort->im.txFirstBdStatus | BD_L);
60283 + else
60284 + {
60285 + /* Set the last BD of the frame */
60286 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), (bdStatus | BD_R_E | BD_L));
60287 + /* Set the first BD of the frame */
60288 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.firstBdOfFrameId), p_FmPort->im.txFirstBdStatus);
60289 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60290 + }
60291 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.offsetIn, (uint16_t)(GetNextBdId(p_FmPort, p_FmPort->im.currBdId)<<4));
60292 + }
60293 + else if (!firstBuffer) /* mid frame buffer */
60294 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), bdStatus | BD_R_E);
60295 +
60296 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60297 + }
60298 + else
60299 + {
60300 + /* Discard current frame. Return error. */
60301 + if (p_FmPort->im.firstBdOfFrameId != IM_ILEGAL_BD_ID)
60302 + {
60303 + /* Error: No free BD */
60304 + /* Response: Discard current frame. Return error. */
60305 + uint16_t cleanBdId = p_FmPort->im.firstBdOfFrameId;
60306 +
60307 + ASSERT_COND(p_FmPort->im.firstBdOfFrameId != p_FmPort->im.currBdId);
60308 +
60309 + /* Since firstInFrame is not NULL, one buffer at least has already been
60310 + inserted into the BD ring. Using do-while covers the situation of a
60311 + frame spanned throughout the whole Tx BD ring (p_CleanBd is incremented
60312 + prior to testing whether or not it's equal to TxBd). */
60313 + do
60314 + {
60315 + BD_STATUS_AND_LENGTH_SET(BD_GET(cleanBdId), 0);
60316 + /* Advance BD pointer */
60317 + cleanBdId = GetNextBdId(p_FmPort, cleanBdId);
60318 + } while (cleanBdId != p_FmPort->im.currBdId);
60319 +
60320 + p_FmPort->im.currBdId = cleanBdId;
60321 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60322 + }
60323 +
60324 + return ERROR_CODE(E_FULL);
60325 + }
60326 +
60327 + return E_OK;
60328 +}
60329 +
60330 +void FM_PORT_ImTxConf(t_Handle h_FmPort)
60331 +{
60332 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60333 +
60334 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
60335 + SANITY_CHECK_RETURN(p_FmPort->imEn, E_INVALID_STATE);
60336 + SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60337 +
60338 + TxConf(p_FmPort, e_TX_CONF_TYPE_CALLBACK);
60339 +}
60340 +
60341 +t_Error FM_PORT_ImRx(t_Handle h_FmPort)
60342 +{
60343 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60344 +
60345 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60346 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60347 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60348 +
60349 + return FmPortImRx(p_FmPort);
60350 +}
60351 --- /dev/null
60352 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
60353 @@ -0,0 +1,1568 @@
60354 +/*
60355 + * Copyright 2008-2012 Freescale Semiconductor Inc.
60356 + *
60357 + * Redistribution and use in source and binary forms, with or without
60358 + * modification, are permitted provided that the following conditions are met:
60359 + * * Redistributions of source code must retain the above copyright
60360 + * notice, this list of conditions and the following disclaimer.
60361 + * * Redistributions in binary form must reproduce the above copyright
60362 + * notice, this list of conditions and the following disclaimer in the
60363 + * documentation and/or other materials provided with the distribution.
60364 + * * Neither the name of Freescale Semiconductor nor the
60365 + * names of its contributors may be used to endorse or promote products
60366 + * derived from this software without specific prior written permission.
60367 + *
60368 + *
60369 + * ALTERNATIVELY, this software may be distributed under the terms of the
60370 + * GNU General Public License ("GPL") as published by the Free Software
60371 + * Foundation, either version 2 of that License or (at your option) any
60372 + * later version.
60373 + *
60374 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
60375 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60376 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60377 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
60378 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60379 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60380 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
60381 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60382 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60383 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60384 + */
60385 +
60386 +
60387 +#include "common/general.h"
60388 +
60389 +#include "fman_common.h"
60390 +#include "fsl_fman_port.h"
60391 +
60392 +
60393 +/* problem Eyal: the following should not be here*/
60394 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
60395 +
60396 +static uint32_t get_no_pcd_nia_bmi_ac_enc_frame(struct fman_port_cfg *cfg)
60397 +{
60398 + if (cfg->errata_A006675)
60399 + return NIA_ENG_FM_CTL |
60400 + NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME;
60401 + else
60402 + return NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
60403 +}
60404 +
60405 +static int init_bmi_rx(struct fman_port *port,
60406 + struct fman_port_cfg *cfg,
60407 + struct fman_port_params *params)
60408 +{
60409 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60410 + uint32_t tmp;
60411 +
60412 + /* Rx Configuration register */
60413 + tmp = 0;
60414 + if (port->im_en)
60415 + tmp |= BMI_PORT_CFG_IM;
60416 + else if (cfg->discard_override)
60417 + tmp |= BMI_PORT_CFG_FDOVR;
60418 + iowrite32be(tmp, &regs->fmbm_rcfg);
60419 +
60420 + /* DMA attributes */
60421 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60422 + if (cfg->dma_ic_stash_on)
60423 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60424 + if (cfg->dma_header_stash_on)
60425 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60426 + if (cfg->dma_sg_stash_on)
60427 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60428 + if (cfg->dma_write_optimize)
60429 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60430 + iowrite32be(tmp, &regs->fmbm_rda);
60431 +
60432 + /* Rx FIFO parameters */
60433 + tmp = (cfg->rx_pri_elevation / FMAN_PORT_BMI_FIFO_UNITS - 1) <<
60434 + BMI_RX_FIFO_PRI_ELEVATION_SHIFT;
60435 + tmp |= cfg->rx_fifo_thr / FMAN_PORT_BMI_FIFO_UNITS - 1;
60436 + iowrite32be(tmp, &regs->fmbm_rfp);
60437 +
60438 + if (cfg->excessive_threshold_register)
60439 + /* always allow access to the extra resources */
60440 + iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->fmbm_reth);
60441 +
60442 + /* Frame end data */
60443 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60444 + BMI_RX_FRAME_END_CS_IGNORE_SHIFT;
60445 + tmp |= (uint32_t)cfg->rx_cut_end_bytes <<
60446 + BMI_RX_FRAME_END_CUT_SHIFT;
60447 + if (cfg->errata_A006320)
60448 + tmp &= 0xffe0ffff;
60449 + iowrite32be(tmp, &regs->fmbm_rfed);
60450 +
60451 + /* Internal context parameters */
60452 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60453 + BMI_IC_TO_EXT_SHIFT;
60454 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60455 + BMI_IC_FROM_INT_SHIFT;
60456 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60457 + iowrite32be(tmp, &regs->fmbm_ricp);
60458 +
60459 + /* Internal buffer offset */
60460 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60461 + << BMI_INT_BUF_MARG_SHIFT;
60462 + iowrite32be(tmp, &regs->fmbm_rim);
60463 +
60464 + /* External buffer margins */
60465 + if (!port->im_en)
60466 + {
60467 + tmp = (uint32_t)cfg->ext_buf_start_margin <<
60468 + BMI_EXT_BUF_MARG_START_SHIFT;
60469 + tmp |= (uint32_t)cfg->ext_buf_end_margin;
60470 + if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather)
60471 + tmp |= BMI_SG_DISABLE;
60472 + iowrite32be(tmp, &regs->fmbm_rebm);
60473 + }
60474 +
60475 + /* Frame attributes */
60476 + tmp = BMI_CMD_RX_MR_DEF;
60477 + if (!port->im_en)
60478 + {
60479 + tmp |= BMI_CMD_ATTR_ORDER;
60480 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60481 + if (cfg->sync_req)
60482 + tmp |= BMI_CMD_ATTR_SYNC;
60483 + }
60484 + iowrite32be(tmp, &regs->fmbm_rfca);
60485 +
60486 + /* NIA */
60487 + if (port->im_en)
60488 + tmp = NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX;
60489 + else
60490 + {
60491 + tmp = (uint32_t)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
60492 + tmp |= get_no_pcd_nia_bmi_ac_enc_frame(cfg);
60493 + }
60494 + iowrite32be(tmp, &regs->fmbm_rfne);
60495 +
60496 + /* Enqueue NIA */
60497 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);
60498 +
60499 + /* Default/error queues */
60500 + if (!port->im_en)
60501 + {
60502 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_rfqid);
60503 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_refqid);
60504 + }
60505 +
60506 + /* Discard/error masks */
60507 + iowrite32be(params->discard_mask, &regs->fmbm_rfsdm);
60508 + iowrite32be(params->err_mask, &regs->fmbm_rfsem);
60509 +
60510 + /* Statistics counters */
60511 + tmp = 0;
60512 + if (cfg->stats_counters_enable)
60513 + tmp = BMI_COUNTERS_EN;
60514 + iowrite32be(tmp, &regs->fmbm_rstc);
60515 +
60516 + /* Performance counters */
60517 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60518 + tmp = 0;
60519 + if (cfg->perf_counters_enable)
60520 + tmp = BMI_COUNTERS_EN;
60521 + iowrite32be(tmp, &regs->fmbm_rpc);
60522 +
60523 + return 0;
60524 +}
60525 +
60526 +static int init_bmi_tx(struct fman_port *port,
60527 + struct fman_port_cfg *cfg,
60528 + struct fman_port_params *params)
60529 +{
60530 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60531 + uint32_t tmp;
60532 +
60533 + /* Tx Configuration register */
60534 + tmp = 0;
60535 + if (port->im_en)
60536 + tmp |= BMI_PORT_CFG_IM;
60537 + iowrite32be(tmp, &regs->fmbm_tcfg);
60538 +
60539 + /* DMA attributes */
60540 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60541 + if (cfg->dma_ic_stash_on)
60542 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60543 + if (cfg->dma_header_stash_on)
60544 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60545 + if (cfg->dma_sg_stash_on)
60546 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60547 + iowrite32be(tmp, &regs->fmbm_tda);
60548 +
60549 + /* Tx FIFO parameters */
60550 + tmp = (cfg->tx_fifo_min_level / FMAN_PORT_BMI_FIFO_UNITS) <<
60551 + BMI_TX_FIFO_MIN_FILL_SHIFT;
60552 + tmp |= ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60553 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60554 + tmp |= (uint32_t)(cfg->tx_fifo_low_comf_level /
60555 + FMAN_PORT_BMI_FIFO_UNITS - 1);
60556 + iowrite32be(tmp, &regs->fmbm_tfp);
60557 +
60558 + /* Frame end data */
60559 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60560 + BMI_FRAME_END_CS_IGNORE_SHIFT;
60561 + iowrite32be(tmp, &regs->fmbm_tfed);
60562 +
60563 + /* Internal context parameters */
60564 + if (!port->im_en)
60565 + {
60566 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60567 + BMI_IC_TO_EXT_SHIFT;
60568 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60569 + BMI_IC_FROM_INT_SHIFT;
60570 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60571 + iowrite32be(tmp, &regs->fmbm_ticp);
60572 + }
60573 + /* Frame attributes */
60574 + tmp = BMI_CMD_TX_MR_DEF;
60575 + if (port->im_en)
60576 + tmp |= BMI_CMD_MR_DEAS;
60577 + else
60578 + {
60579 + tmp |= BMI_CMD_ATTR_ORDER;
60580 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60581 + }
60582 + iowrite32be(tmp, &regs->fmbm_tfca);
60583 +
60584 + /* Dequeue NIA + enqueue NIA */
60585 + if (port->im_en)
60586 + {
60587 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfdne);
60588 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfene);
60589 + }
60590 + else
60591 + {
60592 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);
60593 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_tfene);
60594 + if (cfg->fmbm_tfne_has_features)
60595 + iowrite32be(!params->dflt_fqid ?
60596 + BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :
60597 + NIA_BMI_AC_FETCH_ALL_FRAME, &regs->fmbm_tfne);
60598 + if (!params->dflt_fqid && params->dont_release_buf)
60599 + {
60600 + iowrite32be(0x00FFFFFF, &regs->fmbm_tcfqid);
60601 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, &regs->fmbm_tfene);
60602 + if (cfg->fmbm_tfne_has_features)
60603 + iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN, &regs->fmbm_tfne);
60604 + }
60605 + }
60606 +
60607 + /* Confirmation/error queues */
60608 + if (!port->im_en)
60609 + {
60610 + if (params->dflt_fqid || !params->dont_release_buf)
60611 + iowrite32be(params->dflt_fqid & 0x00FFFFFF, &regs->fmbm_tcfqid);
60612 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_tefqid);
60613 + }
60614 + /* Statistics counters */
60615 + tmp = 0;
60616 + if (cfg->stats_counters_enable)
60617 + tmp = BMI_COUNTERS_EN;
60618 + iowrite32be(tmp, &regs->fmbm_tstc);
60619 +
60620 + /* Performance counters */
60621 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60622 + tmp = 0;
60623 + if (cfg->perf_counters_enable)
60624 + tmp = BMI_COUNTERS_EN;
60625 + iowrite32be(tmp, &regs->fmbm_tpc);
60626 +
60627 + return 0;
60628 +}
60629 +
60630 +static int init_bmi_oh(struct fman_port *port,
60631 + struct fman_port_cfg *cfg,
60632 + struct fman_port_params *params)
60633 +{
60634 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
60635 + uint32_t tmp;
60636 +
60637 + /* OP Configuration register */
60638 + tmp = 0;
60639 + if (cfg->discard_override)
60640 + tmp |= BMI_PORT_CFG_FDOVR;
60641 + iowrite32be(tmp, &regs->fmbm_ocfg);
60642 +
60643 + /* DMA attributes */
60644 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60645 + if (cfg->dma_ic_stash_on)
60646 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60647 + if (cfg->dma_header_stash_on)
60648 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60649 + if (cfg->dma_sg_stash_on)
60650 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60651 + if (cfg->dma_write_optimize)
60652 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60653 + iowrite32be(tmp, &regs->fmbm_oda);
60654 +
60655 + /* Tx FIFO parameters */
60656 + tmp = ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60657 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60658 + iowrite32be(tmp, &regs->fmbm_ofp);
60659 +
60660 + /* Internal context parameters */
60661 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60662 + BMI_IC_TO_EXT_SHIFT;
60663 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60664 + BMI_IC_FROM_INT_SHIFT;
60665 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60666 + iowrite32be(tmp, &regs->fmbm_oicp);
60667 +
60668 + /* Frame attributes */
60669 + tmp = BMI_CMD_OP_MR_DEF;
60670 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60671 + if (cfg->sync_req)
60672 + tmp |= BMI_CMD_ATTR_SYNC;
60673 + if (port->type == E_FMAN_PORT_TYPE_OP)
60674 + tmp |= BMI_CMD_ATTR_ORDER;
60675 + iowrite32be(tmp, &regs->fmbm_ofca);
60676 +
60677 + /* Internal buffer offset */
60678 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60679 + << BMI_INT_BUF_MARG_SHIFT;
60680 + iowrite32be(tmp, &regs->fmbm_oim);
60681 +
60682 + /* Dequeue NIA */
60683 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_ofdne);
60684 +
60685 + /* NIA and Enqueue NIA */
60686 + if (port->type == E_FMAN_PORT_TYPE_HC) {
60687 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC,
60688 + &regs->fmbm_ofne);
60689 + iowrite32be(NIA_ENG_QMI_ENQ, &regs->fmbm_ofene);
60690 + } else {
60691 + iowrite32be(get_no_pcd_nia_bmi_ac_enc_frame(cfg),
60692 + &regs->fmbm_ofne);
60693 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR,
60694 + &regs->fmbm_ofene);
60695 + }
60696 +
60697 + /* Default/error queues */
60698 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_ofqid);
60699 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_oefqid);
60700 +
60701 + /* Discard/error masks */
60702 + if (port->type == E_FMAN_PORT_TYPE_OP) {
60703 + iowrite32be(params->discard_mask, &regs->fmbm_ofsdm);
60704 + iowrite32be(params->err_mask, &regs->fmbm_ofsem);
60705 + }
60706 +
60707 + /* Statistics counters */
60708 + tmp = 0;
60709 + if (cfg->stats_counters_enable)
60710 + tmp = BMI_COUNTERS_EN;
60711 + iowrite32be(tmp, &regs->fmbm_ostc);
60712 +
60713 + /* Performance counters */
60714 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60715 + tmp = 0;
60716 + if (cfg->perf_counters_enable)
60717 + tmp = BMI_COUNTERS_EN;
60718 + iowrite32be(tmp, &regs->fmbm_opc);
60719 +
60720 + return 0;
60721 +}
60722 +
60723 +static int init_qmi(struct fman_port *port,
60724 + struct fman_port_cfg *cfg,
60725 + struct fman_port_params *params)
60726 +{
60727 + struct fman_port_qmi_regs *regs = port->qmi_regs;
60728 + uint32_t tmp;
60729 +
60730 + tmp = 0;
60731 + if (cfg->queue_counters_enable)
60732 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
60733 + iowrite32be(tmp, &regs->fmqm_pnc);
60734 +
60735 + /* Rx port configuration */
60736 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
60737 + (port->type == E_FMAN_PORT_TYPE_RX_10G)) {
60738 + /* Enqueue NIA */
60739 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
60740 + return 0;
60741 + }
60742 +
60743 + /* Continue with Tx and O/H port configuration */
60744 + if ((port->type == E_FMAN_PORT_TYPE_TX) ||
60745 + (port->type == E_FMAN_PORT_TYPE_TX_10G)) {
60746 + /* Enqueue NIA */
60747 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
60748 + &regs->fmqm_pnen);
60749 + /* Dequeue NIA */
60750 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->fmqm_pndn);
60751 + } else {
60752 + /* Enqueue NIA */
60753 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
60754 + /* Dequeue NIA */
60755 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_FETCH, &regs->fmqm_pndn);
60756 + }
60757 +
60758 + /* Dequeue Configuration register */
60759 + tmp = 0;
60760 + if (cfg->deq_high_pri)
60761 + tmp |= QMI_DEQ_CFG_PRI;
60762 +
60763 + switch (cfg->deq_type) {
60764 + case E_FMAN_PORT_DEQ_BY_PRI:
60765 + tmp |= QMI_DEQ_CFG_TYPE1;
60766 + break;
60767 + case E_FMAN_PORT_DEQ_ACTIVE_FQ:
60768 + tmp |= QMI_DEQ_CFG_TYPE2;
60769 + break;
60770 + case E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:
60771 + tmp |= QMI_DEQ_CFG_TYPE3;
60772 + break;
60773 + default:
60774 + return -EINVAL;
60775 + }
60776 +
60777 + if (cfg->qmi_deq_options_support) {
60778 + if ((port->type == E_FMAN_PORT_TYPE_HC) &&
60779 + (cfg->deq_prefetch_opt != E_FMAN_PORT_DEQ_NO_PREFETCH))
60780 + return -EINVAL;
60781 +
60782 + switch (cfg->deq_prefetch_opt) {
60783 + case E_FMAN_PORT_DEQ_NO_PREFETCH:
60784 + break;
60785 + case E_FMAN_PORT_DEQ_PART_PREFETCH:
60786 + tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;
60787 + break;
60788 + case E_FMAN_PORT_DEQ_FULL_PREFETCH:
60789 + tmp |= QMI_DEQ_CFG_PREFETCH_FULL;
60790 + break;
60791 + default:
60792 + return -EINVAL;
60793 + }
60794 + }
60795 + tmp |= (uint32_t)(params->deq_sp & QMI_DEQ_CFG_SP_MASK) <<
60796 + QMI_DEQ_CFG_SP_SHIFT;
60797 + tmp |= cfg->deq_byte_cnt;
60798 + iowrite32be(tmp, &regs->fmqm_pndc);
60799 +
60800 + return 0;
60801 +}
60802 +
60803 +static void get_rx_stats_reg(struct fman_port *port,
60804 + enum fman_port_stats_counters counter,
60805 + uint32_t **stats_reg)
60806 +{
60807 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60808 +
60809 + switch (counter) {
60810 + case E_FMAN_PORT_STATS_CNT_FRAME:
60811 + *stats_reg = &regs->fmbm_rfrc;
60812 + break;
60813 + case E_FMAN_PORT_STATS_CNT_DISCARD:
60814 + *stats_reg = &regs->fmbm_rfdc;
60815 + break;
60816 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
60817 + *stats_reg = &regs->fmbm_rbdc;
60818 + break;
60819 + case E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME:
60820 + *stats_reg = &regs->fmbm_rfbc;
60821 + break;
60822 + case E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME:
60823 + *stats_reg = &regs->fmbm_rlfc;
60824 + break;
60825 + case E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF:
60826 + *stats_reg = &regs->fmbm_rodc;
60827 + break;
60828 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
60829 + *stats_reg = &regs->fmbm_rffc;
60830 + break;
60831 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
60832 + *stats_reg = &regs->fmbm_rfldec;
60833 + break;
60834 + default:
60835 + *stats_reg = NULL;
60836 + }
60837 +}
60838 +
60839 +static void get_tx_stats_reg(struct fman_port *port,
60840 + enum fman_port_stats_counters counter,
60841 + uint32_t **stats_reg)
60842 +{
60843 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60844 +
60845 + switch (counter) {
60846 + case E_FMAN_PORT_STATS_CNT_FRAME:
60847 + *stats_reg = &regs->fmbm_tfrc;
60848 + break;
60849 + case E_FMAN_PORT_STATS_CNT_DISCARD:
60850 + *stats_reg = &regs->fmbm_tfdc;
60851 + break;
60852 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
60853 + *stats_reg = &regs->fmbm_tbdc;
60854 + break;
60855 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
60856 + *stats_reg = &regs->fmbm_tfledc;
60857 + break;
60858 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
60859 + *stats_reg = &regs->fmbm_tfufdc;
60860 + break;
60861 + default:
60862 + *stats_reg = NULL;
60863 + }
60864 +}
60865 +
60866 +static void get_oh_stats_reg(struct fman_port *port,
60867 + enum fman_port_stats_counters counter,
60868 + uint32_t **stats_reg)
60869 +{
60870 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
60871 +
60872 + switch (counter) {
60873 + case E_FMAN_PORT_STATS_CNT_FRAME:
60874 + *stats_reg = &regs->fmbm_ofrc;
60875 + break;
60876 + case E_FMAN_PORT_STATS_CNT_DISCARD:
60877 + *stats_reg = &regs->fmbm_ofdc;
60878 + break;
60879 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
60880 + *stats_reg = &regs->fmbm_obdc;
60881 + break;
60882 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
60883 + *stats_reg = &regs->fmbm_offc;
60884 + break;
60885 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
60886 + *stats_reg = &regs->fmbm_ofldec;
60887 + break;
60888 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
60889 + *stats_reg = &regs->fmbm_ofledc;
60890 + break;
60891 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
60892 + *stats_reg = &regs->fmbm_ofufdc;
60893 + break;
60894 + case E_FMAN_PORT_STATS_CNT_WRED_DISCARD:
60895 + *stats_reg = &regs->fmbm_ofwdc;
60896 + break;
60897 + default:
60898 + *stats_reg = NULL;
60899 + }
60900 +}
60901 +
60902 +static void get_rx_perf_reg(struct fman_port *port,
60903 + enum fman_port_perf_counters counter,
60904 + uint32_t **perf_reg)
60905 +{
60906 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60907 +
60908 + switch (counter) {
60909 + case E_FMAN_PORT_PERF_CNT_CYCLE:
60910 + *perf_reg = &regs->fmbm_rccn;
60911 + break;
60912 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
60913 + *perf_reg = &regs->fmbm_rtuc;
60914 + break;
60915 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
60916 + *perf_reg = &regs->fmbm_rrquc;
60917 + break;
60918 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
60919 + *perf_reg = &regs->fmbm_rduc;
60920 + break;
60921 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
60922 + *perf_reg = &regs->fmbm_rfuc;
60923 + break;
60924 + case E_FMAN_PORT_PERF_CNT_RX_PAUSE:
60925 + *perf_reg = &regs->fmbm_rpac;
60926 + break;
60927 + default:
60928 + *perf_reg = NULL;
60929 + }
60930 +}
60931 +
60932 +static void get_tx_perf_reg(struct fman_port *port,
60933 + enum fman_port_perf_counters counter,
60934 + uint32_t **perf_reg)
60935 +{
60936 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60937 +
60938 + switch (counter) {
60939 + case E_FMAN_PORT_PERF_CNT_CYCLE:
60940 + *perf_reg = &regs->fmbm_tccn;
60941 + break;
60942 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
60943 + *perf_reg = &regs->fmbm_ttuc;
60944 + break;
60945 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
60946 + *perf_reg = &regs->fmbm_ttcquc;
60947 + break;
60948 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
60949 + *perf_reg = &regs->fmbm_tduc;
60950 + break;
60951 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
60952 + *perf_reg = &regs->fmbm_tfuc;
60953 + break;
60954 + default:
60955 + *perf_reg = NULL;
60956 + }
60957 +}
60958 +
60959 +static void get_oh_perf_reg(struct fman_port *port,
60960 + enum fman_port_perf_counters counter,
60961 + uint32_t **perf_reg)
60962 +{
60963 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
60964 +
60965 + switch (counter) {
60966 + case E_FMAN_PORT_PERF_CNT_CYCLE:
60967 + *perf_reg = &regs->fmbm_occn;
60968 + break;
60969 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
60970 + *perf_reg = &regs->fmbm_otuc;
60971 + break;
60972 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
60973 + *perf_reg = &regs->fmbm_oduc;
60974 + break;
60975 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
60976 + *perf_reg = &regs->fmbm_ofuc;
60977 + break;
60978 + default:
60979 + *perf_reg = NULL;
60980 + }
60981 +}
60982 +
60983 +static void get_qmi_counter_reg(struct fman_port *port,
60984 + enum fman_port_qmi_counters counter,
60985 + uint32_t **queue_reg)
60986 +{
60987 + struct fman_port_qmi_regs *regs = port->qmi_regs;
60988 +
60989 + switch (counter) {
60990 + case E_FMAN_PORT_ENQ_TOTAL:
60991 + *queue_reg = &regs->fmqm_pnetfc;
60992 + break;
60993 + case E_FMAN_PORT_DEQ_TOTAL:
60994 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
60995 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
60996 + /* Counter not available for Rx ports */
60997 + *queue_reg = NULL;
60998 + else
60999 + *queue_reg = &regs->fmqm_pndtfc;
61000 + break;
61001 + case E_FMAN_PORT_DEQ_FROM_DFLT:
61002 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61003 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61004 + /* Counter not available for Rx ports */
61005 + *queue_reg = NULL;
61006 + else
61007 + *queue_reg = &regs->fmqm_pndfdc;
61008 + break;
61009 + case E_FMAN_PORT_DEQ_CONFIRM:
61010 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61011 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61012 + /* Counter not available for Rx ports */
61013 + *queue_reg = NULL;
61014 + else
61015 + *queue_reg = &regs->fmqm_pndcc;
61016 + break;
61017 + default:
61018 + *queue_reg = NULL;
61019 + }
61020 +}
61021 +
61022 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type)
61023 +{
61024 + cfg->dma_swap_data = E_FMAN_PORT_DMA_NO_SWAP;
61025 + cfg->dma_ic_stash_on = FALSE;
61026 + cfg->dma_header_stash_on = FALSE;
61027 + cfg->dma_sg_stash_on = FALSE;
61028 + cfg->dma_write_optimize = TRUE;
61029 + cfg->color = E_FMAN_PORT_COLOR_GREEN;
61030 + cfg->discard_override = FALSE;
61031 + cfg->checksum_bytes_ignore = 0;
61032 + cfg->rx_cut_end_bytes = 4;
61033 + cfg->rx_pri_elevation = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
61034 + cfg->rx_fifo_thr = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
61035 + cfg->rx_fd_bits = 0;
61036 + cfg->ic_ext_offset = 0;
61037 + cfg->ic_int_offset = 0;
61038 + cfg->ic_size = 0;
61039 + cfg->int_buf_start_margin = 0;
61040 + cfg->ext_buf_start_margin = 0;
61041 + cfg->ext_buf_end_margin = 0;
61042 + cfg->tx_fifo_min_level = 0;
61043 + cfg->tx_fifo_low_comf_level = (5 * KILOBYTE);
61044 + cfg->stats_counters_enable = TRUE;
61045 + cfg->perf_counters_enable = TRUE;
61046 + cfg->deq_type = E_FMAN_PORT_DEQ_BY_PRI;
61047 +
61048 + if (type == E_FMAN_PORT_TYPE_HC) {
61049 + cfg->sync_req = FALSE;
61050 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_NO_PREFETCH;
61051 + } else {
61052 + cfg->sync_req = TRUE;
61053 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_FULL_PREFETCH;
61054 + }
61055 +
61056 + if (type == E_FMAN_PORT_TYPE_TX_10G) {
61057 + cfg->tx_fifo_deq_pipeline_depth = 4;
61058 + cfg->deq_high_pri = TRUE;
61059 + cfg->deq_byte_cnt = 0x1400;
61060 + } else {
61061 + if ((type == E_FMAN_PORT_TYPE_HC) ||
61062 + (type == E_FMAN_PORT_TYPE_OP))
61063 + cfg->tx_fifo_deq_pipeline_depth = 2;
61064 + else
61065 + cfg->tx_fifo_deq_pipeline_depth = 1;
61066 +
61067 + cfg->deq_high_pri = FALSE;
61068 + cfg->deq_byte_cnt = 0x400;
61069 + }
61070 + cfg->no_scatter_gather = DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
61071 +}
61072 +
61073 +static uint8_t fman_port_find_bpool(struct fman_port *port, uint8_t bpid)
61074 +{
61075 + uint32_t *bp_reg, tmp;
61076 + uint8_t i, id;
61077 +
61078 + /* Find the pool */
61079 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
61080 + for (i = 0;
61081 + (i < port->ext_pools_num && (i < FMAN_PORT_MAX_EXT_POOLS_NUM));
61082 + i++) {
61083 + tmp = ioread32be(&bp_reg[i]);
61084 + id = (uint8_t)((tmp & BMI_EXT_BUF_POOL_ID_MASK) >>
61085 + BMI_EXT_BUF_POOL_ID_SHIFT);
61086 +
61087 + if (id == bpid)
61088 + break;
61089 + }
61090 +
61091 + return i;
61092 +}
61093 +
61094 +int fman_port_init(struct fman_port *port,
61095 + struct fman_port_cfg *cfg,
61096 + struct fman_port_params *params)
61097 +{
61098 + int err;
61099 +
61100 + /* Init BMI registers */
61101 + switch (port->type) {
61102 + case E_FMAN_PORT_TYPE_RX:
61103 + case E_FMAN_PORT_TYPE_RX_10G:
61104 + err = init_bmi_rx(port, cfg, params);
61105 + break;
61106 + case E_FMAN_PORT_TYPE_TX:
61107 + case E_FMAN_PORT_TYPE_TX_10G:
61108 + err = init_bmi_tx(port, cfg, params);
61109 + break;
61110 + case E_FMAN_PORT_TYPE_OP:
61111 + case E_FMAN_PORT_TYPE_HC:
61112 + err = init_bmi_oh(port, cfg, params);
61113 + break;
61114 + default:
61115 + return -EINVAL;
61116 + }
61117 +
61118 + if (err)
61119 + return err;
61120 +
61121 + /* Init QMI registers */
61122 + if (!port->im_en)
61123 + {
61124 + err = init_qmi(port, cfg, params);
61125 + return err;
61126 + }
61127 + return 0;
61128 +}
61129 +
61130 +int fman_port_enable(struct fman_port *port)
61131 +{
61132 + uint32_t *bmi_cfg_reg, tmp;
61133 + bool rx_port;
61134 +
61135 + switch (port->type) {
61136 + case E_FMAN_PORT_TYPE_RX:
61137 + case E_FMAN_PORT_TYPE_RX_10G:
61138 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
61139 + rx_port = TRUE;
61140 + break;
61141 + case E_FMAN_PORT_TYPE_TX:
61142 + case E_FMAN_PORT_TYPE_TX_10G:
61143 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61144 + rx_port = FALSE;
61145 + break;
61146 + case E_FMAN_PORT_TYPE_OP:
61147 + case E_FMAN_PORT_TYPE_HC:
61148 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61149 + rx_port = FALSE;
61150 + break;
61151 + default:
61152 + return -EINVAL;
61153 + }
61154 +
61155 + /* Enable QMI */
61156 + if (!rx_port) {
61157 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;
61158 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61159 + }
61160 +
61161 + /* Enable BMI */
61162 + tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;
61163 + iowrite32be(tmp, bmi_cfg_reg);
61164 +
61165 + return 0;
61166 +}
61167 +
61168 +int fman_port_disable(const struct fman_port *port)
61169 +{
61170 + uint32_t *bmi_cfg_reg, *bmi_status_reg, tmp;
61171 + bool rx_port, failure = FALSE;
61172 + int count;
61173 +
61174 + switch (port->type) {
61175 + case E_FMAN_PORT_TYPE_RX:
61176 + case E_FMAN_PORT_TYPE_RX_10G:
61177 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
61178 + bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;
61179 + rx_port = TRUE;
61180 + break;
61181 + case E_FMAN_PORT_TYPE_TX:
61182 + case E_FMAN_PORT_TYPE_TX_10G:
61183 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61184 + bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;
61185 + rx_port = FALSE;
61186 + break;
61187 + case E_FMAN_PORT_TYPE_OP:
61188 + case E_FMAN_PORT_TYPE_HC:
61189 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61190 + bmi_status_reg = &port->bmi_regs->oh.fmbm_ost;
61191 + rx_port = FALSE;
61192 + break;
61193 + default:
61194 + return -EINVAL;
61195 + }
61196 +
61197 + /* Disable QMI */
61198 + if (!rx_port) {
61199 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;
61200 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61201 +
61202 + /* Wait for QMI to finish FD handling */
61203 + count = 100;
61204 + do {
61205 + udelay(10);
61206 + tmp = ioread32be(&port->qmi_regs->fmqm_pns);
61207 + } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);
61208 +
61209 + if (count == 0)
61210 + {
61211 + /* Timeout */
61212 + failure = TRUE;
61213 + }
61214 + }
61215 +
61216 + /* Disable BMI */
61217 + tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;
61218 + iowrite32be(tmp, bmi_cfg_reg);
61219 +
61220 + /* Wait for graceful stop end */
61221 + count = 500;
61222 + do {
61223 + udelay(10);
61224 + tmp = ioread32be(bmi_status_reg);
61225 + } while ((tmp & BMI_PORT_STATUS_BSY) && --count);
61226 +
61227 + if (count == 0)
61228 + {
61229 + /* Timeout */
61230 + failure = TRUE;
61231 + }
61232 +
61233 + if (failure)
61234 + return -EBUSY;
61235 +
61236 + return 0;
61237 +}
61238 +
61239 +int fman_port_set_bpools(const struct fman_port *port,
61240 + const struct fman_port_bpools *bp)
61241 +{
61242 + uint32_t tmp, *bp_reg, *bp_depl_reg;
61243 + uint8_t i, max_bp_num;
61244 + bool grp_depl_used = FALSE, rx_port;
61245 +
61246 + switch (port->type) {
61247 + case E_FMAN_PORT_TYPE_RX:
61248 + case E_FMAN_PORT_TYPE_RX_10G:
61249 + max_bp_num = port->ext_pools_num;
61250 + rx_port = TRUE;
61251 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
61252 + bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;
61253 + break;
61254 + case E_FMAN_PORT_TYPE_OP:
61255 + if (port->fm_rev_maj != 4)
61256 + return -EINVAL;
61257 + max_bp_num = FMAN_PORT_OBS_EXT_POOLS_NUM;
61258 + rx_port = FALSE;
61259 + bp_reg = port->bmi_regs->oh.fmbm_oebmpi;
61260 + bp_depl_reg = &port->bmi_regs->oh.fmbm_ompd;
61261 + break;
61262 + default:
61263 + return -EINVAL;
61264 + }
61265 +
61266 + if (rx_port) {
61267 + /* Check buffers are provided in ascending order */
61268 + for (i = 0;
61269 + (i < (bp->count-1) && (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1));
61270 + i++) {
61271 + if (bp->bpool[i].size > bp->bpool[i+1].size)
61272 + return -EINVAL;
61273 + }
61274 + }
61275 +
61276 + /* Set up external buffers pools */
61277 + for (i = 0; i < bp->count; i++) {
61278 + tmp = BMI_EXT_BUF_POOL_VALID;
61279 + tmp |= ((uint32_t)bp->bpool[i].bpid <<
61280 + BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;
61281 +
61282 + if (rx_port) {
61283 + if (bp->counters_enable)
61284 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61285 +
61286 + if (bp->bpool[i].is_backup)
61287 + tmp |= BMI_EXT_BUF_POOL_BACKUP;
61288 +
61289 + tmp |= (uint32_t)bp->bpool[i].size;
61290 + }
61291 +
61292 + iowrite32be(tmp, &bp_reg[i]);
61293 + }
61294 +
61295 + /* Clear unused pools */
61296 + for (i = bp->count; i < max_bp_num; i++)
61297 + iowrite32be(0, &bp_reg[i]);
61298 +
61299 + /* Pools depletion */
61300 + tmp = 0;
61301 + for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {
61302 + if (bp->bpool[i].grp_bp_depleted) {
61303 + grp_depl_used = TRUE;
61304 + tmp |= 0x80000000 >> i;
61305 + }
61306 +
61307 + if (bp->bpool[i].single_bp_depleted)
61308 + tmp |= 0x80 >> i;
61309 +
61310 + if (bp->bpool[i].pfc_priorities_en)
61311 + tmp |= 0x0100 << i;
61312 + }
61313 +
61314 + if (grp_depl_used)
61315 + tmp |= ((uint32_t)bp->grp_bp_depleted_num - 1) <<
61316 + BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;
61317 +
61318 + iowrite32be(tmp, bp_depl_reg);
61319 + return 0;
61320 +}
61321 +
61322 +int fman_port_set_rate_limiter(struct fman_port *port,
61323 + struct fman_port_rate_limiter *rate_limiter)
61324 +{
61325 + uint32_t *rate_limit_reg, *rate_limit_scale_reg;
61326 + uint32_t granularity, tmp;
61327 + uint8_t usec_bit, factor;
61328 +
61329 + switch (port->type) {
61330 + case E_FMAN_PORT_TYPE_TX:
61331 + case E_FMAN_PORT_TYPE_TX_10G:
61332 + rate_limit_reg = &port->bmi_regs->tx.fmbm_trlmt;
61333 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61334 + granularity = BMI_RATE_LIMIT_GRAN_TX;
61335 + break;
61336 + case E_FMAN_PORT_TYPE_OP:
61337 + rate_limit_reg = &port->bmi_regs->oh.fmbm_orlmt;
61338 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61339 + granularity = BMI_RATE_LIMIT_GRAN_OP;
61340 + break;
61341 + default:
61342 + return -EINVAL;
61343 + }
61344 +
61345 + /* Factor is per 1 usec count */
61346 + factor = 1;
61347 + usec_bit = rate_limiter->count_1micro_bit;
61348 +
61349 + /* If rate limit is too small for an 1usec factor, adjust timestamp
61350 + * scale and multiply the factor */
61351 + while (rate_limiter->rate < (granularity / factor)) {
61352 + if (usec_bit == 31)
61353 + /* Can't configure rate limiter - rate is too small */
61354 + return -EINVAL;
61355 +
61356 + usec_bit++;
61357 + factor <<= 1;
61358 + }
61359 +
61360 + /* Figure out register value. The "while" above quarantees that
61361 + * (rate_limiter->rate * factor / granularity) >= 1 */
61362 + tmp = (uint32_t)(rate_limiter->rate * factor / granularity - 1);
61363 +
61364 + /* Check rate limit isn't too large */
61365 + if (tmp >= BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS)
61366 + return -EINVAL;
61367 +
61368 + /* Check burst size is in allowed range */
61369 + if ((rate_limiter->burst_size == 0) ||
61370 + (rate_limiter->burst_size >
61371 + BMI_RATE_LIMIT_MAX_BURST_SIZE))
61372 + return -EINVAL;
61373 +
61374 + tmp |= (uint32_t)(rate_limiter->burst_size - 1) <<
61375 + BMI_RATE_LIMIT_MAX_BURST_SHIFT;
61376 +
61377 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61378 + (port->fm_rev_maj == 4)) {
61379 + if (rate_limiter->high_burst_size_gran)
61380 + tmp |= BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN;
61381 + }
61382 +
61383 + iowrite32be(tmp, rate_limit_reg);
61384 +
61385 + /* Set up rate limiter scale register */
61386 + tmp = BMI_RATE_LIMIT_SCALE_EN;
61387 + tmp |= (31 - (uint32_t)usec_bit) << BMI_RATE_LIMIT_SCALE_TSBS_SHIFT;
61388 +
61389 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61390 + (port->fm_rev_maj == 4))
61391 + tmp |= rate_limiter->rate_factor;
61392 +
61393 + iowrite32be(tmp, rate_limit_scale_reg);
61394 +
61395 + return 0;
61396 +}
61397 +
61398 +int fman_port_delete_rate_limiter(struct fman_port *port)
61399 +{
61400 + uint32_t *rate_limit_scale_reg;
61401 +
61402 + switch (port->type) {
61403 + case E_FMAN_PORT_TYPE_TX:
61404 + case E_FMAN_PORT_TYPE_TX_10G:
61405 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61406 + break;
61407 + case E_FMAN_PORT_TYPE_OP:
61408 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61409 + break;
61410 + default:
61411 + return -EINVAL;
61412 + }
61413 +
61414 + iowrite32be(0, rate_limit_scale_reg);
61415 + return 0;
61416 +}
61417 +
61418 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask)
61419 +{
61420 + uint32_t *err_mask_reg;
61421 +
61422 + /* Obtain register address */
61423 + switch (port->type) {
61424 + case E_FMAN_PORT_TYPE_RX:
61425 + case E_FMAN_PORT_TYPE_RX_10G:
61426 + err_mask_reg = &port->bmi_regs->rx.fmbm_rfsem;
61427 + break;
61428 + case E_FMAN_PORT_TYPE_OP:
61429 + err_mask_reg = &port->bmi_regs->oh.fmbm_ofsem;
61430 + break;
61431 + default:
61432 + return -EINVAL;
61433 + }
61434 +
61435 + iowrite32be(err_mask, err_mask_reg);
61436 + return 0;
61437 +}
61438 +
61439 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask)
61440 +{
61441 + uint32_t *discard_mask_reg;
61442 +
61443 + /* Obtain register address */
61444 + switch (port->type) {
61445 + case E_FMAN_PORT_TYPE_RX:
61446 + case E_FMAN_PORT_TYPE_RX_10G:
61447 + discard_mask_reg = &port->bmi_regs->rx.fmbm_rfsdm;
61448 + break;
61449 + case E_FMAN_PORT_TYPE_OP:
61450 + discard_mask_reg = &port->bmi_regs->oh.fmbm_ofsdm;
61451 + break;
61452 + default:
61453 + return -EINVAL;
61454 + }
61455 +
61456 + iowrite32be(discard_mask, discard_mask_reg);
61457 + return 0;
61458 +}
61459 +
61460 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
61461 + uint8_t rx_fd_bits,
61462 + bool add)
61463 +{
61464 + uint32_t tmp;
61465 +
61466 + switch (port->type) {
61467 + case E_FMAN_PORT_TYPE_RX:
61468 + case E_FMAN_PORT_TYPE_RX_10G:
61469 + break;
61470 + default:
61471 + return -EINVAL;
61472 + }
61473 +
61474 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_rfne);
61475 +
61476 + if (add)
61477 + tmp |= (uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
61478 + else
61479 + tmp &= ~((uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT);
61480 +
61481 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_rfne);
61482 + return 0;
61483 +}
61484 +
61485 +int fman_port_set_perf_cnt_params(struct fman_port *port,
61486 + struct fman_port_perf_cnt_params *params)
61487 +{
61488 + uint32_t *pcp_reg, tmp;
61489 +
61490 + /* Obtain register address and check parameters are in range */
61491 + switch (port->type) {
61492 + case E_FMAN_PORT_TYPE_RX:
61493 + case E_FMAN_PORT_TYPE_RX_10G:
61494 + pcp_reg = &port->bmi_regs->rx.fmbm_rpcp;
61495 + if ((params->queue_val == 0) ||
61496 + (params->queue_val > MAX_PERFORMANCE_RX_QUEUE_COMP))
61497 + return -EINVAL;
61498 + break;
61499 + case E_FMAN_PORT_TYPE_TX:
61500 + case E_FMAN_PORT_TYPE_TX_10G:
61501 + pcp_reg = &port->bmi_regs->tx.fmbm_tpcp;
61502 + if ((params->queue_val == 0) ||
61503 + (params->queue_val > MAX_PERFORMANCE_TX_QUEUE_COMP))
61504 + return -EINVAL;
61505 + break;
61506 + case E_FMAN_PORT_TYPE_OP:
61507 + case E_FMAN_PORT_TYPE_HC:
61508 + pcp_reg = &port->bmi_regs->oh.fmbm_opcp;
61509 + if (params->queue_val != 0)
61510 + return -EINVAL;
61511 + break;
61512 + default:
61513 + return -EINVAL;
61514 + }
61515 +
61516 + if ((params->task_val == 0) ||
61517 + (params->task_val > MAX_PERFORMANCE_TASK_COMP))
61518 + return -EINVAL;
61519 + if ((params->dma_val == 0) ||
61520 + (params->dma_val > MAX_PERFORMANCE_DMA_COMP))
61521 + return -EINVAL;
61522 + if ((params->fifo_val == 0) ||
61523 + ((params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS) >
61524 + MAX_PERFORMANCE_FIFO_COMP))
61525 + return -EINVAL;
61526 + tmp = (uint32_t)(params->task_val - 1) <<
61527 + BMI_PERFORMANCE_TASK_COMP_SHIFT;
61528 + tmp |= (uint32_t)(params->dma_val - 1) <<
61529 + BMI_PERFORMANCE_DMA_COMP_SHIFT;
61530 + tmp |= (uint32_t)(params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS - 1);
61531 +
61532 + switch (port->type) {
61533 + case E_FMAN_PORT_TYPE_RX:
61534 + case E_FMAN_PORT_TYPE_RX_10G:
61535 + case E_FMAN_PORT_TYPE_TX:
61536 + case E_FMAN_PORT_TYPE_TX_10G:
61537 + tmp |= (uint32_t)(params->queue_val - 1) <<
61538 + BMI_PERFORMANCE_QUEUE_COMP_SHIFT;
61539 + break;
61540 + default:
61541 + break;
61542 + }
61543 +
61544 +
61545 + iowrite32be(tmp, pcp_reg);
61546 + return 0;
61547 +}
61548 +
61549 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable)
61550 +{
61551 + uint32_t *stats_reg, tmp;
61552 +
61553 + switch (port->type) {
61554 + case E_FMAN_PORT_TYPE_RX:
61555 + case E_FMAN_PORT_TYPE_RX_10G:
61556 + stats_reg = &port->bmi_regs->rx.fmbm_rstc;
61557 + break;
61558 + case E_FMAN_PORT_TYPE_TX:
61559 + case E_FMAN_PORT_TYPE_TX_10G:
61560 + stats_reg = &port->bmi_regs->tx.fmbm_tstc;
61561 + break;
61562 + case E_FMAN_PORT_TYPE_OP:
61563 + case E_FMAN_PORT_TYPE_HC:
61564 + stats_reg = &port->bmi_regs->oh.fmbm_ostc;
61565 + break;
61566 + default:
61567 + return -EINVAL;
61568 + }
61569 +
61570 + tmp = ioread32be(stats_reg);
61571 +
61572 + if (enable)
61573 + tmp |= BMI_COUNTERS_EN;
61574 + else
61575 + tmp &= ~BMI_COUNTERS_EN;
61576 +
61577 + iowrite32be(tmp, stats_reg);
61578 + return 0;
61579 +}
61580 +
61581 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable)
61582 +{
61583 + uint32_t *stats_reg, tmp;
61584 +
61585 + switch (port->type) {
61586 + case E_FMAN_PORT_TYPE_RX:
61587 + case E_FMAN_PORT_TYPE_RX_10G:
61588 + stats_reg = &port->bmi_regs->rx.fmbm_rpc;
61589 + break;
61590 + case E_FMAN_PORT_TYPE_TX:
61591 + case E_FMAN_PORT_TYPE_TX_10G:
61592 + stats_reg = &port->bmi_regs->tx.fmbm_tpc;
61593 + break;
61594 + case E_FMAN_PORT_TYPE_OP:
61595 + case E_FMAN_PORT_TYPE_HC:
61596 + stats_reg = &port->bmi_regs->oh.fmbm_opc;
61597 + break;
61598 + default:
61599 + return -EINVAL;
61600 + }
61601 +
61602 + tmp = ioread32be(stats_reg);
61603 +
61604 + if (enable)
61605 + tmp |= BMI_COUNTERS_EN;
61606 + else
61607 + tmp &= ~BMI_COUNTERS_EN;
61608 +
61609 + iowrite32be(tmp, stats_reg);
61610 + return 0;
61611 +}
61612 +
61613 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable)
61614 +{
61615 + uint32_t tmp;
61616 +
61617 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc);
61618 +
61619 + if (enable)
61620 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
61621 + else
61622 + tmp &= ~QMI_PORT_CFG_EN_COUNTERS;
61623 +
61624 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61625 + return 0;
61626 +}
61627 +
61628 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
61629 + uint8_t bpid,
61630 + bool enable)
61631 +{
61632 + uint8_t index;
61633 + uint32_t tmp;
61634 +
61635 + switch (port->type) {
61636 + case E_FMAN_PORT_TYPE_RX:
61637 + case E_FMAN_PORT_TYPE_RX_10G:
61638 + break;
61639 + default:
61640 + return -EINVAL;
61641 + }
61642 +
61643 + /* Find the pool */
61644 + index = fman_port_find_bpool(port, bpid);
61645 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61646 + /* Not found */
61647 + return -EINVAL;
61648 +
61649 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_ebmpi[index]);
61650 +
61651 + if (enable)
61652 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61653 + else
61654 + tmp &= ~BMI_EXT_BUF_POOL_EN_COUNTER;
61655 +
61656 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_ebmpi[index]);
61657 + return 0;
61658 +}
61659 +
61660 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
61661 + enum fman_port_stats_counters counter)
61662 +{
61663 + uint32_t *stats_reg, ret_val;
61664 +
61665 + switch (port->type) {
61666 + case E_FMAN_PORT_TYPE_RX:
61667 + case E_FMAN_PORT_TYPE_RX_10G:
61668 + get_rx_stats_reg(port, counter, &stats_reg);
61669 + break;
61670 + case E_FMAN_PORT_TYPE_TX:
61671 + case E_FMAN_PORT_TYPE_TX_10G:
61672 + get_tx_stats_reg(port, counter, &stats_reg);
61673 + break;
61674 + case E_FMAN_PORT_TYPE_OP:
61675 + case E_FMAN_PORT_TYPE_HC:
61676 + get_oh_stats_reg(port, counter, &stats_reg);
61677 + break;
61678 + default:
61679 + stats_reg = NULL;
61680 + }
61681 +
61682 + if (stats_reg == NULL)
61683 + return 0;
61684 +
61685 + ret_val = ioread32be(stats_reg);
61686 + return ret_val;
61687 +}
61688 +
61689 +void fman_port_set_stats_counter(struct fman_port *port,
61690 + enum fman_port_stats_counters counter,
61691 + uint32_t value)
61692 +{
61693 + uint32_t *stats_reg;
61694 +
61695 + switch (port->type) {
61696 + case E_FMAN_PORT_TYPE_RX:
61697 + case E_FMAN_PORT_TYPE_RX_10G:
61698 + get_rx_stats_reg(port, counter, &stats_reg);
61699 + break;
61700 + case E_FMAN_PORT_TYPE_TX:
61701 + case E_FMAN_PORT_TYPE_TX_10G:
61702 + get_tx_stats_reg(port, counter, &stats_reg);
61703 + break;
61704 + case E_FMAN_PORT_TYPE_OP:
61705 + case E_FMAN_PORT_TYPE_HC:
61706 + get_oh_stats_reg(port, counter, &stats_reg);
61707 + break;
61708 + default:
61709 + stats_reg = NULL;
61710 + }
61711 +
61712 + if (stats_reg == NULL)
61713 + return;
61714 +
61715 + iowrite32be(value, stats_reg);
61716 +}
61717 +
61718 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
61719 + enum fman_port_perf_counters counter)
61720 +{
61721 + uint32_t *perf_reg, ret_val;
61722 +
61723 + switch (port->type) {
61724 + case E_FMAN_PORT_TYPE_RX:
61725 + case E_FMAN_PORT_TYPE_RX_10G:
61726 + get_rx_perf_reg(port, counter, &perf_reg);
61727 + break;
61728 + case E_FMAN_PORT_TYPE_TX:
61729 + case E_FMAN_PORT_TYPE_TX_10G:
61730 + get_tx_perf_reg(port, counter, &perf_reg);
61731 + break;
61732 + case E_FMAN_PORT_TYPE_OP:
61733 + case E_FMAN_PORT_TYPE_HC:
61734 + get_oh_perf_reg(port, counter, &perf_reg);
61735 + break;
61736 + default:
61737 + perf_reg = NULL;
61738 + }
61739 +
61740 + if (perf_reg == NULL)
61741 + return 0;
61742 +
61743 + ret_val = ioread32be(perf_reg);
61744 + return ret_val;
61745 +}
61746 +
61747 +void fman_port_set_perf_counter(struct fman_port *port,
61748 + enum fman_port_perf_counters counter,
61749 + uint32_t value)
61750 +{
61751 + uint32_t *perf_reg;
61752 +
61753 + switch (port->type) {
61754 + case E_FMAN_PORT_TYPE_RX:
61755 + case E_FMAN_PORT_TYPE_RX_10G:
61756 + get_rx_perf_reg(port, counter, &perf_reg);
61757 + break;
61758 + case E_FMAN_PORT_TYPE_TX:
61759 + case E_FMAN_PORT_TYPE_TX_10G:
61760 + get_tx_perf_reg(port, counter, &perf_reg);
61761 + break;
61762 + case E_FMAN_PORT_TYPE_OP:
61763 + case E_FMAN_PORT_TYPE_HC:
61764 + get_oh_perf_reg(port, counter, &perf_reg);
61765 + break;
61766 + default:
61767 + perf_reg = NULL;
61768 + }
61769 +
61770 + if (perf_reg == NULL)
61771 + return;
61772 +
61773 + iowrite32be(value, perf_reg);
61774 +}
61775 +
61776 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
61777 + enum fman_port_qmi_counters counter)
61778 +{
61779 + uint32_t *queue_reg, ret_val;
61780 +
61781 + get_qmi_counter_reg(port, counter, &queue_reg);
61782 +
61783 + if (queue_reg == NULL)
61784 + return 0;
61785 +
61786 + ret_val = ioread32be(queue_reg);
61787 + return ret_val;
61788 +}
61789 +
61790 +void fman_port_set_qmi_counter(struct fman_port *port,
61791 + enum fman_port_qmi_counters counter,
61792 + uint32_t value)
61793 +{
61794 + uint32_t *queue_reg;
61795 +
61796 + get_qmi_counter_reg(port, counter, &queue_reg);
61797 +
61798 + if (queue_reg == NULL)
61799 + return;
61800 +
61801 + iowrite32be(value, queue_reg);
61802 +}
61803 +
61804 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid)
61805 +{
61806 + uint8_t index;
61807 + uint32_t ret_val;
61808 +
61809 + switch (port->type) {
61810 + case E_FMAN_PORT_TYPE_RX:
61811 + case E_FMAN_PORT_TYPE_RX_10G:
61812 + break;
61813 + default:
61814 + return 0;
61815 + }
61816 +
61817 + /* Find the pool */
61818 + index = fman_port_find_bpool(port, bpid);
61819 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61820 + /* Not found */
61821 + return 0;
61822 +
61823 + ret_val = ioread32be(&port->bmi_regs->rx.fmbm_acnt[index]);
61824 + return ret_val;
61825 +}
61826 +
61827 +void fman_port_set_bpool_counter(struct fman_port *port,
61828 + uint8_t bpid,
61829 + uint32_t value)
61830 +{
61831 + uint8_t index;
61832 +
61833 + switch (port->type) {
61834 + case E_FMAN_PORT_TYPE_RX:
61835 + case E_FMAN_PORT_TYPE_RX_10G:
61836 + break;
61837 + default:
61838 + return;
61839 + }
61840 +
61841 + /* Find the pool */
61842 + index = fman_port_find_bpool(port, bpid);
61843 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61844 + /* Not found */
61845 + return;
61846 +
61847 + iowrite32be(value, &port->bmi_regs->rx.fmbm_acnt[index]);
61848 +}
61849 +
61850 +int fman_port_add_congestion_grps(struct fman_port *port,
61851 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
61852 +{
61853 + int i;
61854 + uint32_t tmp, *grp_map_reg;
61855 + uint8_t max_grp_map_num;
61856 +
61857 + switch (port->type) {
61858 + case E_FMAN_PORT_TYPE_RX:
61859 + case E_FMAN_PORT_TYPE_RX_10G:
61860 + if (port->fm_rev_maj == 4)
61861 + max_grp_map_num = 1;
61862 + else
61863 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
61864 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
61865 + break;
61866 + case E_FMAN_PORT_TYPE_OP:
61867 + max_grp_map_num = 1;
61868 + if (port->fm_rev_maj != 4)
61869 + return -EINVAL;
61870 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
61871 + break;
61872 + default:
61873 + return -EINVAL;
61874 + }
61875 +
61876 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
61877 + if (grps_map[i] == 0)
61878 + continue;
61879 + tmp = ioread32be(&grp_map_reg[i]);
61880 + tmp |= grps_map[i];
61881 + iowrite32be(tmp, &grp_map_reg[i]);
61882 + }
61883 +
61884 + return 0;
61885 +}
61886 +
61887 +int fman_port_remove_congestion_grps(struct fman_port *port,
61888 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
61889 +{
61890 + int i;
61891 + uint32_t tmp, *grp_map_reg;
61892 + uint8_t max_grp_map_num;
61893 +
61894 + switch (port->type) {
61895 + case E_FMAN_PORT_TYPE_RX:
61896 + case E_FMAN_PORT_TYPE_RX_10G:
61897 + if (port->fm_rev_maj == 4)
61898 + max_grp_map_num = 1;
61899 + else
61900 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
61901 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
61902 + break;
61903 + case E_FMAN_PORT_TYPE_OP:
61904 + max_grp_map_num = 1;
61905 + if (port->fm_rev_maj != 4)
61906 + return -EINVAL;
61907 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
61908 + break;
61909 + default:
61910 + return -EINVAL;
61911 + }
61912 +
61913 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
61914 + if (grps_map[i] == 0)
61915 + continue;
61916 + tmp = ioread32be(&grp_map_reg[i]);
61917 + tmp &= ~grps_map[i];
61918 + iowrite32be(tmp, &grp_map_reg[i]);
61919 + }
61920 + return 0;
61921 +}
61922 --- /dev/null
61923 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
61924 @@ -0,0 +1,15 @@
61925 +#
61926 +# Makefile for the Freescale Ethernet controllers
61927 +#
61928 +ccflags-y += -DVERSION=\"\"
61929 +#
61930 +#Include netcomm SW specific definitions
61931 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
61932 +
61933 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
61934 +
61935 +ccflags-y += -I$(NCSW_FM_INC)
61936 +
61937 +obj-y += fsl-ncsw-RTC.o
61938 +
61939 +fsl-ncsw-RTC-objs := fm_rtc.o fman_rtc.o
61940 --- /dev/null
61941 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
61942 @@ -0,0 +1,692 @@
61943 +/*
61944 + * Copyright 2008-2012 Freescale Semiconductor Inc.
61945 + *
61946 + * Redistribution and use in source and binary forms, with or without
61947 + * modification, are permitted provided that the following conditions are met:
61948 + * * Redistributions of source code must retain the above copyright
61949 + * notice, this list of conditions and the following disclaimer.
61950 + * * Redistributions in binary form must reproduce the above copyright
61951 + * notice, this list of conditions and the following disclaimer in the
61952 + * documentation and/or other materials provided with the distribution.
61953 + * * Neither the name of Freescale Semiconductor nor the
61954 + * names of its contributors may be used to endorse or promote products
61955 + * derived from this software without specific prior written permission.
61956 + *
61957 + *
61958 + * ALTERNATIVELY, this software may be distributed under the terms of the
61959 + * GNU General Public License ("GPL") as published by the Free Software
61960 + * Foundation, either version 2 of that License or (at your option) any
61961 + * later version.
61962 + *
61963 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
61964 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
61965 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
61966 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
61967 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61968 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61969 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61970 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
61971 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61972 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61973 + */
61974 +
61975 +
61976 +/******************************************************************************
61977 + @File fm_rtc.c
61978 +
61979 + @Description FM RTC driver implementation.
61980 +
61981 + @Cautions None
61982 +*//***************************************************************************/
61983 +#include <linux/math64.h>
61984 +#include "error_ext.h"
61985 +#include "debug_ext.h"
61986 +#include "string_ext.h"
61987 +#include "part_ext.h"
61988 +#include "xx_ext.h"
61989 +#include "ncsw_ext.h"
61990 +
61991 +#include "fm_rtc.h"
61992 +#include "fm_common.h"
61993 +
61994 +
61995 +
61996 +/*****************************************************************************/
61997 +static t_Error CheckInitParameters(t_FmRtc *p_Rtc)
61998 +{
61999 + struct rtc_cfg *p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
62000 + int i;
62001 +
62002 + if ((p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL) &&
62003 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) &&
62004 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR))
62005 + RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined"));
62006 +
62007 + if (p_Rtc->outputClockDivisor == 0)
62008 + {
62009 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
62010 + ("Divisor for output clock (should be positive)"));
62011 + }
62012 +
62013 + for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
62014 + {
62015 + if ((p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) &&
62016 + (p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH))
62017 + {
62018 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i));
62019 + }
62020 + }
62021 + for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
62022 + {
62023 + if ((p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) &&
62024 + (p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_RISING_EDGE))
62025 + {
62026 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i));
62027 + }
62028 + }
62029 +
62030 + return E_OK;
62031 +}
62032 +
62033 +/*****************************************************************************/
62034 +static void RtcExceptions(t_Handle h_FmRtc)
62035 +{
62036 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62037 + struct rtc_regs *p_MemMap;
62038 + register uint32_t events;
62039 +
62040 + ASSERT_COND(p_Rtc);
62041 + p_MemMap = p_Rtc->p_MemMap;
62042 +
62043 + events = fman_rtc_check_and_clear_event(p_MemMap);
62044 + if (events & FMAN_RTC_TMR_TEVENT_ALM1)
62045 + {
62046 + if (p_Rtc->alarmParams[0].clearOnExpiration)
62047 + {
62048 + fman_rtc_set_timer_alarm_l(p_MemMap, 0, 0);
62049 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM1);
62050 + }
62051 + ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback);
62052 + p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0);
62053 + }
62054 + if (events & FMAN_RTC_TMR_TEVENT_ALM2)
62055 + {
62056 + if (p_Rtc->alarmParams[1].clearOnExpiration)
62057 + {
62058 + fman_rtc_set_timer_alarm_l(p_MemMap, 1, 0);
62059 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM2);
62060 + }
62061 + ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback);
62062 + p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1);
62063 + }
62064 + if (events & FMAN_RTC_TMR_TEVENT_PP1)
62065 + {
62066 + ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback);
62067 + p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0);
62068 + }
62069 + if (events & FMAN_RTC_TMR_TEVENT_PP2)
62070 + {
62071 + ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback);
62072 + p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1);
62073 + }
62074 + if (events & FMAN_RTC_TMR_TEVENT_ETS1)
62075 + {
62076 + ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback);
62077 + p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0);
62078 + }
62079 + if (events & FMAN_RTC_TMR_TEVENT_ETS2)
62080 + {
62081 + ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback);
62082 + p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1);
62083 + }
62084 +}
62085 +
62086 +
62087 +/*****************************************************************************/
62088 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam)
62089 +{
62090 + t_FmRtc *p_Rtc;
62091 +
62092 + SANITY_CHECK_RETURN_VALUE(p_FmRtcParam, E_NULL_POINTER, NULL);
62093 +
62094 + /* Allocate memory for the FM RTC driver parameters */
62095 + p_Rtc = (t_FmRtc *)XX_Malloc(sizeof(t_FmRtc));
62096 + if (!p_Rtc)
62097 + {
62098 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver structure"));
62099 + return NULL;
62100 + }
62101 +
62102 + memset(p_Rtc, 0, sizeof(t_FmRtc));
62103 +
62104 + /* Allocate memory for the FM RTC driver parameters */
62105 + p_Rtc->p_RtcDriverParam = (struct rtc_cfg *)XX_Malloc(sizeof(struct rtc_cfg));
62106 + if (!p_Rtc->p_RtcDriverParam)
62107 + {
62108 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters"));
62109 + XX_Free(p_Rtc);
62110 + return NULL;
62111 + }
62112 +
62113 + memset(p_Rtc->p_RtcDriverParam, 0, sizeof(struct rtc_cfg));
62114 +
62115 + /* Store RTC configuration parameters */
62116 + p_Rtc->h_Fm = p_FmRtcParam->h_Fm;
62117 +
62118 + /* Set default RTC configuration parameters */
62119 + fman_rtc_defconfig(p_Rtc->p_RtcDriverParam);
62120 +
62121 + p_Rtc->outputClockDivisor = DEFAULT_OUTPUT_CLOCK_DIVISOR;
62122 + p_Rtc->p_RtcDriverParam->bypass = DEFAULT_BYPASS;
62123 + p_Rtc->clockPeriodNanoSec = DEFAULT_CLOCK_PERIOD; /* 1 usec */
62124 +
62125 +
62126 + /* Store RTC parameters in the RTC control structure */
62127 + p_Rtc->p_MemMap = (struct rtc_regs *)UINT_TO_PTR(p_FmRtcParam->baseAddress);
62128 + p_Rtc->h_App = p_FmRtcParam->h_App;
62129 +
62130 + return p_Rtc;
62131 +}
62132 +
62133 +/*****************************************************************************/
62134 +t_Error FM_RTC_Init(t_Handle h_FmRtc)
62135 +{
62136 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62137 + struct rtc_cfg *p_RtcDriverParam;
62138 + struct rtc_regs *p_MemMap;
62139 + uint32_t freqCompensation = 0;
62140 + uint64_t tmpDouble;
62141 + bool init_freq_comp = FALSE;
62142 +
62143 + p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
62144 + p_MemMap = p_Rtc->p_MemMap;
62145 +
62146 + if (CheckInitParameters(p_Rtc)!=E_OK)
62147 + RETURN_ERROR(MAJOR, E_CONFLICT,
62148 + ("Init Parameters are not Valid"));
62149 +
62150 + /* TODO check that no timestamping MACs are working in this stage. */
62151 +
62152 + /* find source clock frequency in Mhz */
62153 + if (p_Rtc->p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM)
62154 + p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->ext_src_clk_freq;
62155 + else
62156 + p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetMacClockFreq(p_Rtc->h_Fm));
62157 +
62158 + /* if timer in Master mode Initialize TMR_CTRL */
62159 + /* We want the counter (TMR_CNT) to count in nano-seconds */
62160 + if (!p_RtcDriverParam->timer_slave_mode && p_Rtc->p_RtcDriverParam->bypass)
62161 + p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz);
62162 + else
62163 + {
62164 + /* Initialize TMR_ADD with the initial frequency compensation value:
62165 + freqCompensation = (2^32 / frequency ratio) */
62166 + /* frequency ratio = sorce clock/rtc clock =
62167 + * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */
62168 + init_freq_comp = TRUE;
62169 + freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000,
62170 + p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz);
62171 + }
62172 +
62173 + /* check the legality of the relation between source and destination clocks */
62174 + /* should be larger than 1.0001 */
62175 + tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz;
62176 + if ((tmpDouble) <= 10001)
62177 + RETURN_ERROR(MAJOR, E_CONFLICT,
62178 + ("Invalid relation between source and destination clocks. Should be larger than 1.0001"));
62179 +
62180 + fman_rtc_init(p_RtcDriverParam,
62181 + p_MemMap,
62182 + FM_RTC_NUM_OF_ALARMS,
62183 + FM_RTC_NUM_OF_PERIODIC_PULSES,
62184 + FM_RTC_NUM_OF_EXT_TRIGGERS,
62185 + init_freq_comp,
62186 + freqCompensation,
62187 + p_Rtc->outputClockDivisor);
62188 +
62189 + /* Register the FM RTC interrupt */
62190 + FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc);
62191 +
62192 + /* Free parameters structures */
62193 + XX_Free(p_Rtc->p_RtcDriverParam);
62194 + p_Rtc->p_RtcDriverParam = NULL;
62195 +
62196 + return E_OK;
62197 +}
62198 +
62199 +/*****************************************************************************/
62200 +t_Error FM_RTC_Free(t_Handle h_FmRtc)
62201 +{
62202 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62203 +
62204 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62205 +
62206 + if (p_Rtc->p_RtcDriverParam)
62207 + {
62208 + XX_Free(p_Rtc->p_RtcDriverParam);
62209 + }
62210 + else
62211 + {
62212 + FM_RTC_Disable(h_FmRtc);
62213 + }
62214 +
62215 + /* Unregister FM RTC interrupt */
62216 + FmUnregisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL);
62217 + XX_Free(p_Rtc);
62218 +
62219 + return E_OK;
62220 +}
62221 +
62222 +/*****************************************************************************/
62223 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
62224 + e_FmSrcClk srcClk,
62225 + uint32_t freqInMhz)
62226 +{
62227 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62228 +
62229 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62230 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62231 +
62232 + p_Rtc->p_RtcDriverParam->src_clk = (enum fman_src_clock)srcClk;
62233 + if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM)
62234 + p_Rtc->p_RtcDriverParam->ext_src_clk_freq = freqInMhz;
62235 +
62236 + return E_OK;
62237 +}
62238 +
62239 +/*****************************************************************************/
62240 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period)
62241 +{
62242 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62243 +
62244 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62245 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62246 +
62247 + p_Rtc->clockPeriodNanoSec = period;
62248 +
62249 + return E_OK;
62250 +}
62251 +
62252 +/*****************************************************************************/
62253 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled)
62254 +{
62255 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62256 +
62257 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62258 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62259 +
62260 + p_Rtc->p_RtcDriverParam->bypass = enabled;
62261 +
62262 + return E_OK;
62263 +}
62264 +
62265 +/*****************************************************************************/
62266 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted)
62267 +{
62268 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62269 +
62270 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62271 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62272 +
62273 + p_Rtc->p_RtcDriverParam->invert_input_clk_phase = inverted;
62274 +
62275 + return E_OK;
62276 +}
62277 +
62278 +/*****************************************************************************/
62279 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted)
62280 +{
62281 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62282 +
62283 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62284 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62285 +
62286 + p_Rtc->p_RtcDriverParam->invert_output_clk_phase = inverted;
62287 +
62288 + return E_OK;
62289 +}
62290 +
62291 +/*****************************************************************************/
62292 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor)
62293 +{
62294 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62295 +
62296 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62297 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62298 +
62299 + p_Rtc->outputClockDivisor = divisor;
62300 +
62301 + return E_OK;
62302 +}
62303 +
62304 +/*****************************************************************************/
62305 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable)
62306 +{
62307 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62308 +
62309 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62310 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62311 +
62312 + p_Rtc->p_RtcDriverParam->pulse_realign = enable;
62313 +
62314 + return E_OK;
62315 +}
62316 +
62317 +/*****************************************************************************/
62318 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
62319 + uint8_t alarmId,
62320 + e_FmRtcAlarmPolarity alarmPolarity)
62321 +{
62322 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62323 +
62324 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62325 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62326 +
62327 + if (alarmId >= FM_RTC_NUM_OF_ALARMS)
62328 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62329 +
62330 + p_Rtc->p_RtcDriverParam->alarm_polarity[alarmId] =
62331 + (enum fman_rtc_alarm_polarity)alarmPolarity;
62332 +
62333 + return E_OK;
62334 +}
62335 +
62336 +/*****************************************************************************/
62337 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
62338 + uint8_t triggerId,
62339 + e_FmRtcTriggerPolarity triggerPolarity)
62340 +{
62341 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62342 +
62343 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62344 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62345 +
62346 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62347 + {
62348 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62349 + }
62350 +
62351 + p_Rtc->p_RtcDriverParam->trigger_polarity[triggerId] =
62352 + (enum fman_rtc_trigger_polarity)triggerPolarity;
62353 +
62354 + return E_OK;
62355 +}
62356 +
62357 +/*****************************************************************************/
62358 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock)
62359 +{
62360 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62361 +
62362 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62363 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62364 +
62365 + fman_rtc_enable(p_Rtc->p_MemMap, resetClock);
62366 + return E_OK;
62367 +}
62368 +
62369 +/*****************************************************************************/
62370 +t_Error FM_RTC_Disable(t_Handle h_FmRtc)
62371 +{
62372 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62373 +
62374 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62375 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62376 +
62377 + /* TODO A check must be added here, that no timestamping MAC's
62378 + * are working in this stage. */
62379 + fman_rtc_disable(p_Rtc->p_MemMap);
62380 +
62381 + return E_OK;
62382 +}
62383 +
62384 +/*****************************************************************************/
62385 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset)
62386 +{
62387 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62388 +
62389 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62390 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62391 +
62392 + fman_rtc_set_timer_offset(p_Rtc->p_MemMap, offset);
62393 + return E_OK;
62394 +}
62395 +
62396 +/*****************************************************************************/
62397 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams)
62398 +{
62399 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62400 + uint64_t tmpAlarm;
62401 + bool enable = FALSE;
62402 +
62403 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62404 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62405 +
62406 + if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS)
62407 + {
62408 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62409 + }
62410 +
62411 + if (p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec)
62412 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62413 + ("Alarm time must be equal or larger than RTC period - %d nanoseconds",
62414 + p_Rtc->clockPeriodNanoSec));
62415 + tmpAlarm = p_FmRtcAlarmParams->alarmTime;
62416 + if (do_div(tmpAlarm, p_Rtc->clockPeriodNanoSec))
62417 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62418 + ("Alarm time must be a multiple of RTC period - %d nanoseconds",
62419 + p_Rtc->clockPeriodNanoSec));
62420 +
62421 + if (p_FmRtcAlarmParams->f_AlarmCallback)
62422 + {
62423 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback;
62424 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration;
62425 + enable = TRUE;
62426 + }
62427 +
62428 + fman_rtc_set_alarm(p_Rtc->p_MemMap, p_FmRtcAlarmParams->alarmId, (unsigned long)tmpAlarm, enable);
62429 +
62430 + return E_OK;
62431 +}
62432 +
62433 +/*****************************************************************************/
62434 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams)
62435 +{
62436 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62437 + bool enable = FALSE;
62438 + uint64_t tmpFiper;
62439 +
62440 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62441 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62442 +
62443 + if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62444 + {
62445 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62446 + }
62447 + if (fman_rtc_is_enabled(p_Rtc->p_MemMap))
62448 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled."));
62449 + if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec)
62450 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62451 + ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds",
62452 + p_Rtc->clockPeriodNanoSec));
62453 + tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod;
62454 + if (do_div(tmpFiper, p_Rtc->clockPeriodNanoSec))
62455 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62456 + ("Periodic pulse must be a multiple of RTC period - %d nanoseconds",
62457 + p_Rtc->clockPeriodNanoSec));
62458 + if (tmpFiper & 0xffffffff00000000LL)
62459 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62460 + ("Periodic pulse/RTC Period must be smaller than 4294967296",
62461 + p_Rtc->clockPeriodNanoSec));
62462 +
62463 + if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback)
62464 + {
62465 + p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback =
62466 + p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback;
62467 + enable = TRUE;
62468 + }
62469 + fman_rtc_set_periodic_pulse(p_Rtc->p_MemMap, p_FmRtcPeriodicPulseParams->periodicPulseId, (uint32_t)tmpFiper, enable);
62470 + return E_OK;
62471 +}
62472 +
62473 +/*****************************************************************************/
62474 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId)
62475 +{
62476 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62477 +
62478 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62479 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62480 +
62481 + if (periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62482 + {
62483 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62484 + }
62485 +
62486 + p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL;
62487 + fman_rtc_clear_periodic_pulse(p_Rtc->p_MemMap, periodicPulseId);
62488 +
62489 + return E_OK;
62490 +}
62491 +
62492 +/*****************************************************************************/
62493 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams)
62494 +{
62495 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62496 + bool enable = FALSE;
62497 +
62498 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62499 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62500 +
62501 + if (p_FmRtcExternalTriggerParams->externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62502 + {
62503 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62504 + }
62505 +
62506 + if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback)
62507 + {
62508 + p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback;
62509 + enable = TRUE;
62510 + }
62511 +
62512 + fman_rtc_set_ext_trigger(p_Rtc->p_MemMap, p_FmRtcExternalTriggerParams->externalTriggerId, enable, p_FmRtcExternalTriggerParams->usePulseAsInput);
62513 + return E_OK;
62514 +}
62515 +
62516 +/*****************************************************************************/
62517 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId)
62518 +{
62519 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62520 +
62521 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62522 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62523 +
62524 + if (externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62525 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62526 +
62527 + p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL;
62528 +
62529 + fman_rtc_clear_external_trigger(p_Rtc->p_MemMap, externalTriggerId);
62530 +
62531 + return E_OK;
62532 +}
62533 +
62534 +/*****************************************************************************/
62535 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
62536 + uint8_t triggerId,
62537 + uint64_t *p_TimeStamp)
62538 +{
62539 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62540 +
62541 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62542 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62543 +
62544 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62545 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62546 +
62547 + *p_TimeStamp = fman_rtc_get_trigger_stamp(p_Rtc->p_MemMap, triggerId)*p_Rtc->clockPeriodNanoSec;
62548 +
62549 + return E_OK;
62550 +}
62551 +
62552 +/*****************************************************************************/
62553 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts)
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_Ts = fman_rtc_get_timer(p_Rtc->p_MemMap)*p_Rtc->clockPeriodNanoSec;
62561 +
62562 + return E_OK;
62563 +}
62564 +
62565 +/*****************************************************************************/
62566 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts)
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 + do_div(ts, p_Rtc->clockPeriodNanoSec);
62574 + fman_rtc_set_timer(p_Rtc->p_MemMap, (int64_t)ts);
62575 +
62576 + return E_OK;
62577 +}
62578 +
62579 +/*****************************************************************************/
62580 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation)
62581 +{
62582 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62583 +
62584 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62585 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62586 +
62587 + *p_Compensation = fman_rtc_get_frequency_compensation(p_Rtc->p_MemMap);
62588 +
62589 + return E_OK;
62590 +}
62591 +
62592 +/*****************************************************************************/
62593 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation)
62594 +{
62595 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62596 +
62597 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62598 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62599 +
62600 + /* set the new freqCompensation */
62601 + fman_rtc_set_frequency_compensation(p_Rtc->p_MemMap, freqCompensation);
62602 +
62603 + return E_OK;
62604 +}
62605 +
62606 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
62607 +/*****************************************************************************/
62608 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events)
62609 +{
62610 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62611 +
62612 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62613 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62614 +
62615 + /* enable interrupt */
62616 + fman_rtc_enable_interupt(p_Rtc->p_MemMap, events);
62617 +
62618 + return E_OK;
62619 +}
62620 +
62621 +/*****************************************************************************/
62622 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events)
62623 +{
62624 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62625 +
62626 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62627 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62628 +
62629 + /* disable interrupt */
62630 + fman_rtc_disable_interupt(p_Rtc->p_MemMap, events);
62631 +
62632 + return E_OK;
62633 +}
62634 +#endif
62635 --- /dev/null
62636 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
62637 @@ -0,0 +1,96 @@
62638 +/*
62639 + * Copyright 2008-2012 Freescale Semiconductor Inc.
62640 + *
62641 + * Redistribution and use in source and binary forms, with or without
62642 + * modification, are permitted provided that the following conditions are met:
62643 + * * Redistributions of source code must retain the above copyright
62644 + * notice, this list of conditions and the following disclaimer.
62645 + * * Redistributions in binary form must reproduce the above copyright
62646 + * notice, this list of conditions and the following disclaimer in the
62647 + * documentation and/or other materials provided with the distribution.
62648 + * * Neither the name of Freescale Semiconductor nor the
62649 + * names of its contributors may be used to endorse or promote products
62650 + * derived from this software without specific prior written permission.
62651 + *
62652 + *
62653 + * ALTERNATIVELY, this software may be distributed under the terms of the
62654 + * GNU General Public License ("GPL") as published by the Free Software
62655 + * Foundation, either version 2 of that License or (at your option) any
62656 + * later version.
62657 + *
62658 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62659 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62660 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62661 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62662 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62663 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62664 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62665 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62666 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62667 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62668 + */
62669 +
62670 +
62671 +/******************************************************************************
62672 + @File fm_rtc.h
62673 +
62674 + @Description Memory map and internal definitions for FM RTC IEEE1588 Timer driver.
62675 +
62676 + @Cautions None
62677 +*//***************************************************************************/
62678 +
62679 +#ifndef __FM_RTC_H__
62680 +#define __FM_RTC_H__
62681 +
62682 +#include "std_ext.h"
62683 +#include "fm_rtc_ext.h"
62684 +
62685 +
62686 +#define __ERR_MODULE__ MODULE_FM_RTC
62687 +
62688 +/* General definitions */
62689 +
62690 +#define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32))
62691 +#define DEFAULT_OUTPUT_CLOCK_DIVISOR 0x00000002
62692 +#define DEFAULT_BYPASS FALSE
62693 +#define DEFAULT_CLOCK_PERIOD 1000
62694 +
62695 +
62696 +
62697 +typedef struct t_FmRtcAlarm
62698 +{
62699 + t_FmRtcExceptionsCallback *f_AlarmCallback;
62700 + bool clearOnExpiration;
62701 +} t_FmRtcAlarm;
62702 +
62703 +typedef struct t_FmRtcPeriodicPulse
62704 +{
62705 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback;
62706 +} t_FmRtcPeriodicPulse;
62707 +
62708 +typedef struct t_FmRtcExternalTrigger
62709 +{
62710 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback;
62711 +} t_FmRtcExternalTrigger;
62712 +
62713 +
62714 +/**************************************************************************//**
62715 + @Description RTC FM driver control structure.
62716 +*//***************************************************************************/
62717 +typedef struct t_FmRtc
62718 +{
62719 + t_Part *p_Part; /**< Pointer to the integration device */
62720 + t_Handle h_Fm;
62721 + t_Handle h_App; /**< Application handle */
62722 + struct rtc_regs *p_MemMap;
62723 + uint32_t clockPeriodNanoSec; /**< RTC clock period in nano-seconds (for FS mode) */
62724 + uint32_t srcClkFreqMhz;
62725 + uint16_t outputClockDivisor; /**< Output clock divisor (for FS mode) */
62726 + t_FmRtcAlarm alarmParams[FM_RTC_NUM_OF_ALARMS];
62727 + t_FmRtcPeriodicPulse periodicPulseParams[FM_RTC_NUM_OF_PERIODIC_PULSES];
62728 + t_FmRtcExternalTrigger externalTriggerParams[FM_RTC_NUM_OF_EXT_TRIGGERS];
62729 + struct rtc_cfg *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */
62730 +} t_FmRtc;
62731 +
62732 +
62733 +#endif /* __FM_RTC_H__ */
62734 --- /dev/null
62735 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
62736 @@ -0,0 +1,334 @@
62737 +/*
62738 + * Copyright 2008-2013 Freescale Semiconductor Inc.
62739 + *
62740 + * Redistribution and use in source and binary forms, with or without
62741 + * modification, are permitted provided that the following conditions are met:
62742 + * * Redistributions of source code must retain the above copyright
62743 + * notice, this list of conditions and the following disclaimer.
62744 + * * Redistributions in binary form must reproduce the above copyright
62745 + * notice, this list of conditions and the following disclaimer in the
62746 + * documentation and/or other materials provided with the distribution.
62747 + * * Neither the name of Freescale Semiconductor nor the
62748 + * names of its contributors may be used to endorse or promote products
62749 + * derived from this software without specific prior written permission.
62750 + *
62751 + *
62752 + * ALTERNATIVELY, this software may be distributed under the terms of the
62753 + * GNU General Public License ("GPL") as published by the Free Software
62754 + * Foundation, either version 2 of that License or (at your option) any
62755 + * later version.
62756 + *
62757 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62758 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62759 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62760 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62761 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62762 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62763 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62764 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62765 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62766 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62767 + */
62768 +
62769 +#include "fsl_fman_rtc.h"
62770 +
62771 +void fman_rtc_defconfig(struct rtc_cfg *cfg)
62772 +{
62773 + int i;
62774 + cfg->src_clk = DEFAULT_SRC_CLOCK;
62775 + cfg->invert_input_clk_phase = DEFAULT_INVERT_INPUT_CLK_PHASE;
62776 + cfg->invert_output_clk_phase = DEFAULT_INVERT_OUTPUT_CLK_PHASE;
62777 + cfg->pulse_realign = DEFAULT_PULSE_REALIGN;
62778 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_ALARMS; i++)
62779 + cfg->alarm_polarity[i] = DEFAULT_ALARM_POLARITY;
62780 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS; i++)
62781 + cfg->trigger_polarity[i] = DEFAULT_TRIGGER_POLARITY;
62782 +}
62783 +
62784 +uint32_t fman_rtc_get_events(struct rtc_regs *regs)
62785 +{
62786 + return ioread32be(&regs->tmr_tevent);
62787 +}
62788 +
62789 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask)
62790 +{
62791 + return ioread32be(&regs->tmr_tevent) & ev_mask;
62792 +}
62793 +
62794 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs)
62795 +{
62796 + return ioread32be(&regs->tmr_temask);
62797 +}
62798 +
62799 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask)
62800 +{
62801 + iowrite32be(mask, &regs->tmr_temask);
62802 +}
62803 +
62804 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events)
62805 +{
62806 + iowrite32be(events, &regs->tmr_tevent);
62807 +}
62808 +
62809 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs)
62810 +{
62811 + uint32_t event;
62812 +
62813 + event = ioread32be(&regs->tmr_tevent);
62814 + event &= ioread32be(&regs->tmr_temask);
62815 +
62816 + if (event)
62817 + iowrite32be(event, &regs->tmr_tevent);
62818 + return event;
62819 +}
62820 +
62821 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs)
62822 +{
62823 + return ioread32be(&regs->tmr_add);
62824 +}
62825 +
62826 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val)
62827 +{
62828 + iowrite32be(val, &regs->tmr_add);
62829 +}
62830 +
62831 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t events)
62832 +{
62833 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) | events);
62834 +}
62835 +
62836 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t events)
62837 +{
62838 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) & ~events);
62839 +}
62840 +
62841 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, uint32_t val)
62842 +{
62843 + iowrite32be(val, &regs->tmr_alarm[index].tmr_alarm_l);
62844 +}
62845 +
62846 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val)
62847 +{
62848 + iowrite32be(val, &regs->tmr_fiper[index]);
62849 +}
62850 +
62851 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val)
62852 +{
62853 + iowrite32be((uint32_t)val, &regs->tmr_alarm[index].tmr_alarm_l);
62854 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_alarm[index].tmr_alarm_h);
62855 +}
62856 +
62857 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val)
62858 +{
62859 + iowrite32be((uint32_t)val, &regs->tmr_off_l);
62860 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_off_h);
62861 +}
62862 +
62863 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id)
62864 +{
62865 + uint64_t time;
62866 + /* TMR_CNT_L must be read first to get an accurate value */
62867 + time = (uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_l);
62868 + time |= ((uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_h)
62869 + << 32);
62870 +
62871 + return time;
62872 +}
62873 +
62874 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs)
62875 +{
62876 + return ioread32be(&regs->tmr_ctrl);
62877 +}
62878 +
62879 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val)
62880 +{
62881 + iowrite32be(val, &regs->tmr_ctrl);
62882 +}
62883 +
62884 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs)
62885 +{
62886 + fman_rtc_set_timer_ctrl(regs, FMAN_RTC_TMR_CTRL_TMSR);
62887 + udelay(10);
62888 + fman_rtc_set_timer_ctrl(regs, 0);
62889 +}
62890 +
62891 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
62892 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
62893 + uint32_t freq_compensation, uint32_t output_clock_divisor)
62894 +{
62895 + uint32_t tmr_ctrl;
62896 + int i;
62897 +
62898 + fman_rtc_timers_soft_reset(regs);
62899 +
62900 + /* Set the source clock */
62901 + switch (cfg->src_clk) {
62902 + case E_FMAN_RTC_SOURCE_CLOCK_SYSTEM:
62903 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK;
62904 + break;
62905 + case E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR:
62906 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK;
62907 + break;
62908 + default:
62909 + /* Use a clock from the External TMR reference clock.*/
62910 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK;
62911 + break;
62912 + }
62913 +
62914 + /* whatever period the user picked, the timestamp will advance in '1'
62915 + * every time the period passed. */
62916 + tmr_ctrl |= ((1 << FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT) &
62917 + FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK);
62918 +
62919 + if (cfg->invert_input_clk_phase)
62920 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_CIPH;
62921 + if (cfg->invert_output_clk_phase)
62922 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_COPH;
62923 +
62924 + for (i = 0; i < num_alarms; i++) {
62925 + if (cfg->alarm_polarity[i] ==
62926 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW)
62927 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ALMP1 >> i);
62928 + }
62929 +
62930 + for (i = 0; i < num_ext_triggers; i++)
62931 + if (cfg->trigger_polarity[i] ==
62932 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE)
62933 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ETEP1 << i);
62934 +
62935 + if (!cfg->timer_slave_mode && cfg->bypass)
62936 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_BYP;
62937 +
62938 + fman_rtc_set_timer_ctrl(regs, tmr_ctrl);
62939 + if (init_freq_comp)
62940 + fman_rtc_set_frequency_compensation(regs, freq_compensation);
62941 +
62942 + /* Clear TMR_ALARM registers */
62943 + for (i = 0; i < num_alarms; i++)
62944 + fman_rtc_set_timer_alarm(regs, i, 0xFFFFFFFFFFFFFFFFLL);
62945 +
62946 + /* Clear TMR_TEVENT */
62947 + fman_rtc_ack_event(regs, FMAN_RTC_TMR_TEVENT_ALL);
62948 +
62949 + /* Initialize TMR_TEMASK */
62950 + fman_rtc_set_interrupt_mask(regs, 0);
62951 +
62952 + /* Clear TMR_FIPER registers */
62953 + for (i = 0; i < num_fipers; i++)
62954 + fman_rtc_set_timer_fiper(regs, i, 0xFFFFFFFF);
62955 +
62956 + /* Initialize TMR_PRSC */
62957 + iowrite32be(output_clock_divisor, &regs->tmr_prsc);
62958 +
62959 + /* Clear TMR_OFF */
62960 + fman_rtc_set_timer_offset(regs, 0);
62961 +}
62962 +
62963 +bool fman_rtc_is_enabled(struct rtc_regs *regs)
62964 +{
62965 + return (bool)(fman_rtc_get_timer_ctrl(regs) & FMAN_RTC_TMR_CTRL_TE);
62966 +}
62967 +
62968 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock)
62969 +{
62970 + uint32_t tmr_ctrl = fman_rtc_get_timer_ctrl(regs);
62971 +
62972 + /* TODO check that no timestamping MACs are working in this stage. */
62973 + if (reset_clock) {
62974 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TMSR));
62975 +
62976 + udelay(10);
62977 + /* Clear TMR_OFF */
62978 + fman_rtc_set_timer_offset(regs, 0);
62979 + }
62980 +
62981 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TE));
62982 +}
62983 +
62984 +void fman_rtc_disable(struct rtc_regs *regs)
62985 +{
62986 + fman_rtc_set_timer_ctrl(regs, (fman_rtc_get_timer_ctrl(regs)
62987 + & ~(FMAN_RTC_TMR_CTRL_TE)));
62988 +}
62989 +
62990 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id)
62991 +{
62992 + uint32_t tmp_reg;
62993 + if (id == 0)
62994 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP1;
62995 + else
62996 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP2;
62997 + fman_rtc_disable_interupt(regs, tmp_reg);
62998 +
62999 + tmp_reg = fman_rtc_get_timer_ctrl(regs);
63000 + if (tmp_reg & FMAN_RTC_TMR_CTRL_FS)
63001 + fman_rtc_set_timer_ctrl(regs, tmp_reg & ~FMAN_RTC_TMR_CTRL_FS);
63002 +
63003 + fman_rtc_set_timer_fiper(regs, id, 0xFFFFFFFF);
63004 +}
63005 +
63006 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id)
63007 +{
63008 + uint32_t tmpReg, tmp_ctrl;
63009 +
63010 + if (id == 0)
63011 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
63012 + else
63013 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
63014 + fman_rtc_disable_interupt(regs, tmpReg);
63015 +
63016 + if (id == 0)
63017 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
63018 + else
63019 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
63020 + tmp_ctrl = fman_rtc_get_timer_ctrl(regs);
63021 + if (tmp_ctrl & tmpReg)
63022 + fman_rtc_set_timer_ctrl(regs, tmp_ctrl & ~tmpReg);
63023 +}
63024 +
63025 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable)
63026 +{
63027 + uint32_t tmpReg;
63028 + fman_rtc_set_timer_alarm(regs, id, val);
63029 + if (enable) {
63030 + if (id == 0)
63031 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM1;
63032 + else
63033 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM2;
63034 + fman_rtc_enable_interupt(regs, tmpReg);
63035 + }
63036 +}
63037 +
63038 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
63039 + bool enable)
63040 +{
63041 + uint32_t tmpReg;
63042 + fman_rtc_set_timer_fiper(regs, id, val);
63043 + if (enable) {
63044 + if (id == 0)
63045 + tmpReg = FMAN_RTC_TMR_TEVENT_PP1;
63046 + else
63047 + tmpReg = FMAN_RTC_TMR_TEVENT_PP2;
63048 + fman_rtc_enable_interupt(regs, tmpReg);
63049 + }
63050 +}
63051 +
63052 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
63053 + bool use_pulse_as_input)
63054 +{
63055 + uint32_t tmpReg;
63056 + if (enable) {
63057 + if (id == 0)
63058 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
63059 + else
63060 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
63061 + fman_rtc_enable_interupt(regs, tmpReg);
63062 + }
63063 + if (use_pulse_as_input) {
63064 + if (id == 0)
63065 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
63066 + else
63067 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
63068 + fman_rtc_set_timer_ctrl(regs, fman_rtc_get_timer_ctrl(regs) | tmpReg);
63069 + }
63070 +}
63071 --- /dev/null
63072 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
63073 @@ -0,0 +1,15 @@
63074 +#
63075 +# Makefile for the Freescale Ethernet controllers
63076 +#
63077 +ccflags-y += -DVERSION=\"\"
63078 +#
63079 +#Include netcomm SW specific definitions
63080 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
63081 +
63082 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
63083 +
63084 +ccflags-y += -I$(NCSW_FM_INC)
63085 +
63086 +obj-y += fsl-ncsw-sp.o
63087 +
63088 +fsl-ncsw-sp-objs := fm_sp.o fman_sp.o
63089 --- /dev/null
63090 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
63091 @@ -0,0 +1,757 @@
63092 +/*
63093 + * Copyright 2008-2012 Freescale Semiconductor Inc.
63094 + *
63095 + * Redistribution and use in source and binary forms, with or without
63096 + * modification, are permitted provided that the following conditions are met:
63097 + * * Redistributions of source code must retain the above copyright
63098 + * notice, this list of conditions and the following disclaimer.
63099 + * * Redistributions in binary form must reproduce the above copyright
63100 + * notice, this list of conditions and the following disclaimer in the
63101 + * documentation and/or other materials provided with the distribution.
63102 + * * Neither the name of Freescale Semiconductor nor the
63103 + * names of its contributors may be used to endorse or promote products
63104 + * derived from this software without specific prior written permission.
63105 + *
63106 + *
63107 + * ALTERNATIVELY, this software may be distributed under the terms of the
63108 + * GNU General Public License ("GPL") as published by the Free Software
63109 + * Foundation, either version 2 of that License or (at your option) any
63110 + * later version.
63111 + *
63112 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63113 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63114 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63115 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63116 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63117 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63118 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63119 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63120 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63121 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63122 + */
63123 +
63124 +
63125 +/******************************************************************************
63126 + @File fm_sp.c
63127 +
63128 + @Description FM PCD Storage profile ...
63129 +*//***************************************************************************/
63130 +
63131 +#include "std_ext.h"
63132 +#include "error_ext.h"
63133 +#include "string_ext.h"
63134 +#include "debug_ext.h"
63135 +#include "net_ext.h"
63136 +
63137 +#include "fm_vsp_ext.h"
63138 +#include "fm_sp.h"
63139 +#include "fm_common.h"
63140 +#include "fsl_fman_sp.h"
63141 +
63142 +
63143 +#if (DPAA_VERSION >= 11)
63144 +static t_Error CheckParamsGeneratedInternally(t_FmVspEntry *p_FmVspEntry)
63145 +{
63146 + t_Error err = E_OK;
63147 +
63148 + if ((err = FmSpCheckIntContextParams(&p_FmVspEntry->intContext))!= E_OK)
63149 + RETURN_ERROR(MAJOR, err, NO_MSG);
63150 + if ((err = FmSpCheckBufMargins(&p_FmVspEntry->bufMargins)) != E_OK)
63151 + RETURN_ERROR(MAJOR, err, NO_MSG);
63152 + return err;
63153 +
63154 +}
63155 +
63156 +static t_Error CheckParams(t_FmVspEntry *p_FmVspEntry)
63157 +{
63158 + t_Error err = E_OK;
63159 +
63160 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63161 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63162 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->h_Fm, E_INVALID_HANDLE);
63163 +
63164 + if ((err = FmSpCheckBufPoolsParams(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools,
63165 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools,
63166 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)) != E_OK)
63167 +
63168 + RETURN_ERROR(MAJOR, err, NO_MSG);
63169 +
63170 + if (p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset & ~FM_LIODN_OFFSET_MASK)
63171 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
63172 +
63173 + err = FmVSPCheckRelativeProfile(p_FmVspEntry->h_Fm,
63174 + p_FmVspEntry->portType,
63175 + p_FmVspEntry->portId,
63176 + p_FmVspEntry->relativeProfileId);
63177 +
63178 + return err;
63179 +}
63180 +#endif /* (DPAA_VERSION >= 11) */
63181 +
63182 +
63183 +/*****************************************************************************/
63184 +/* Inter-module API routines */
63185 +/*****************************************************************************/
63186 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools,
63187 + uint8_t *orderedArray,
63188 + uint16_t *sizesArray)
63189 +{
63190 + uint16_t bufSize = 0;
63191 + int i=0, j=0, k=0;
63192 +
63193 + /* First we copy the external buffers pools information to an ordered local array */
63194 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63195 + {
63196 + /* get pool size */
63197 + bufSize = p_FmExtPools->extBufPool[i].size;
63198 +
63199 + /* keep sizes in an array according to poolId for direct access */
63200 + sizesArray[p_FmExtPools->extBufPool[i].id] = bufSize;
63201 +
63202 + /* save poolId in an ordered array according to size */
63203 + for (j=0;j<=i;j++)
63204 + {
63205 + /* this is the next free place in the array */
63206 + if (j==i)
63207 + orderedArray[i] = p_FmExtPools->extBufPool[i].id;
63208 + else
63209 + {
63210 + /* find the right place for this poolId */
63211 + if (bufSize < sizesArray[orderedArray[j]])
63212 + {
63213 + /* move the poolIds one place ahead to make room for this poolId */
63214 + for (k=i;k>j;k--)
63215 + orderedArray[k] = orderedArray[k-1];
63216 +
63217 + /* now k==j, this is the place for the new size */
63218 + orderedArray[k] = p_FmExtPools->extBufPool[i].id;
63219 + break;
63220 + }
63221 + }
63222 + }
63223 + }
63224 +}
63225 +
63226 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
63227 + t_FmBackupBmPools *p_FmBackupBmPools,
63228 + t_FmBufPoolDepletion *p_FmBufPoolDepletion)
63229 +{
63230 +
63231 + int i = 0, j = 0;
63232 + bool found;
63233 + uint8_t count = 0;
63234 +
63235 + if (p_FmExtPools)
63236 + {
63237 + if (p_FmExtPools->numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS)
63238 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS));
63239 +
63240 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63241 + {
63242 + if (p_FmExtPools->extBufPool[i].id >= BM_MAX_NUM_OF_POOLS)
63243 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS));
63244 + if (!p_FmExtPools->extBufPool[i].size)
63245 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i));
63246 + }
63247 + }
63248 + if (!p_FmExtPools && (p_FmBackupBmPools || p_FmBufPoolDepletion))
63249 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("backupBmPools ot bufPoolDepletion can not be defined without external pools"));
63250 +
63251 + /* backup BM pools indication is valid only for some chip derivatives
63252 + (limited by the config routine) */
63253 + if (p_FmBackupBmPools)
63254 + {
63255 + if (p_FmBackupBmPools->numOfBackupPools >= p_FmExtPools->numOfPoolsUsed)
63256 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed"));
63257 + found = FALSE;
63258 + for (i = 0;i<p_FmBackupBmPools->numOfBackupPools;i++)
63259 + {
63260 +
63261 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63262 + {
63263 + if (p_FmBackupBmPools->poolIds[i] == p_FmExtPools->extBufPool[j].id)
63264 + {
63265 + found = TRUE;
63266 + break;
63267 + }
63268 + }
63269 + if (!found)
63270 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id"));
63271 + else
63272 + found = FALSE;
63273 + }
63274 + }
63275 +
63276 + /* up to extBufPools.numOfPoolsUsed pools may be defined */
63277 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->poolsGrpModeEnable)
63278 + {
63279 + if ((p_FmBufPoolDepletion->numOfPools > p_FmExtPools->numOfPoolsUsed))
63280 + 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));
63281 +
63282 + if (!p_FmBufPoolDepletion->numOfPools)
63283 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when poolsGrpModeEnable=TRUE"));
63284 +
63285 + found = FALSE;
63286 + count = 0;
63287 + /* for each pool that is in poolsToConsider, check if it is defined
63288 + in extBufPool */
63289 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63290 + {
63291 + if (p_FmBufPoolDepletion->poolsToConsider[i])
63292 + {
63293 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63294 + {
63295 + if (i == p_FmExtPools->extBufPool[j].id)
63296 + {
63297 + found = TRUE;
63298 + count++;
63299 + break;
63300 + }
63301 + }
63302 + if (!found)
63303 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63304 + else
63305 + found = FALSE;
63306 + }
63307 + }
63308 + /* check that the number of pools that we have checked is equal to the number announced by the user */
63309 + if (count != p_FmBufPoolDepletion->numOfPools)
63310 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined."));
63311 + }
63312 +
63313 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->singlePoolModeEnable)
63314 + {
63315 + /* calculate vector for number of pools depletion */
63316 + found = FALSE;
63317 + count = 0;
63318 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63319 + {
63320 + if (p_FmBufPoolDepletion->poolsToConsiderForSingleMode[i])
63321 + {
63322 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63323 + {
63324 + if (i == p_FmExtPools->extBufPool[j].id)
63325 + {
63326 + found = TRUE;
63327 + count++;
63328 + break;
63329 + }
63330 + }
63331 + if (!found)
63332 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63333 + else
63334 + found = FALSE;
63335 + }
63336 + }
63337 + if (!count)
63338 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion."));
63339 + }
63340 +
63341 + return E_OK;
63342 +}
63343 +
63344 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy)
63345 +{
63346 + /* Check that divisible by 16 and not larger than 240 */
63347 + if (p_FmSpIntContextDataCopy->intContextOffset >MAX_INT_OFFSET)
63348 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET));
63349 + if (p_FmSpIntContextDataCopy->intContextOffset % OFFSET_UNITS)
63350 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS));
63351 +
63352 + /* check that ic size+ic internal offset, does not exceed ic block size */
63353 + if (p_FmSpIntContextDataCopy->size + p_FmSpIntContextDataCopy->intContextOffset > MAX_IC_SIZE)
63354 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE));
63355 + /* Check that divisible by 16 and not larger than 256 */
63356 + if (p_FmSpIntContextDataCopy->size % OFFSET_UNITS)
63357 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS));
63358 +
63359 + /* Check that divisible by 16 and not larger than 4K */
63360 + if (p_FmSpIntContextDataCopy->extBufOffset > MAX_EXT_OFFSET)
63361 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET));
63362 + if (p_FmSpIntContextDataCopy->extBufOffset % OFFSET_UNITS)
63363 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS));
63364 +
63365 + return E_OK;
63366 +}
63367 +
63368 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins)
63369 +{
63370 + /* Check the margin definition */
63371 + if (p_FmSpBufMargins->startMargins > MAX_EXT_BUFFER_OFFSET)
63372 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63373 + if (p_FmSpBufMargins->endMargins > MAX_EXT_BUFFER_OFFSET)
63374 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63375 +
63376 + return E_OK;
63377 +}
63378 +
63379 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy,
63380 + t_FmBufferPrefixContent *p_BufferPrefixContent,
63381 + t_FmSpBufMargins *p_FmSpBufMargins,
63382 + t_FmSpBufferOffsets *p_FmSpBufferOffsets,
63383 + uint8_t *internalBufferOffset)
63384 +{
63385 + uint32_t tmp;
63386 +
63387 + SANITY_CHECK_RETURN_ERROR(p_FmSpIntContextDataCopy, E_INVALID_VALUE);
63388 + ASSERT_COND(p_FmSpIntContextDataCopy);
63389 + ASSERT_COND(p_BufferPrefixContent);
63390 + ASSERT_COND(p_FmSpBufMargins);
63391 + ASSERT_COND(p_FmSpBufferOffsets);
63392 +
63393 + /* Align start of internal context data to 16 byte */
63394 + p_FmSpIntContextDataCopy->extBufOffset =
63395 + (uint16_t)((p_BufferPrefixContent->privDataSize & (OFFSET_UNITS-1)) ?
63396 + ((p_BufferPrefixContent->privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) :
63397 + p_BufferPrefixContent->privDataSize);
63398 +
63399 + /* Translate margin and intContext params to FM parameters */
63400 + /* Initialize with illegal value. Later we'll set legal values. */
63401 + p_FmSpBufferOffsets->prsResultOffset = (uint32_t)ILLEGAL_BASE;
63402 + p_FmSpBufferOffsets->timeStampOffset = (uint32_t)ILLEGAL_BASE;
63403 + p_FmSpBufferOffsets->hashResultOffset= (uint32_t)ILLEGAL_BASE;
63404 + p_FmSpBufferOffsets->pcdInfoOffset = (uint32_t)ILLEGAL_BASE;
63405 +
63406 + /* Internally the driver supports 4 options
63407 + 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll
63408 + relate to it as 1).
63409 + 2. All IC context (from AD) not including debug.*/
63410 +
63411 + /* This 'if' covers option 2. We copy from beginning of context. */
63412 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63413 + {
63414 + p_FmSpIntContextDataCopy->size = 128; /* must be aligned to 16 */
63415 + /* Start copying data after 16 bytes (FD) from the beginning of the internal context */
63416 + p_FmSpIntContextDataCopy->intContextOffset = 16;
63417 +
63418 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63419 + p_FmSpBufferOffsets->pcdInfoOffset = p_FmSpIntContextDataCopy->extBufOffset;
63420 + if (p_BufferPrefixContent->passPrsResult)
63421 + p_FmSpBufferOffsets->prsResultOffset =
63422 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 16);
63423 + if (p_BufferPrefixContent->passTimeStamp)
63424 + p_FmSpBufferOffsets->timeStampOffset =
63425 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 48);
63426 + if (p_BufferPrefixContent->passHashResult)
63427 + p_FmSpBufferOffsets->hashResultOffset =
63428 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 56);
63429 + }
63430 + else
63431 + {
63432 + /* This case covers the options under 1 */
63433 + /* Copy size must be in 16-byte granularity. */
63434 + p_FmSpIntContextDataCopy->size =
63435 + (uint16_t)((p_BufferPrefixContent->passPrsResult ? 32 : 0) +
63436 + ((p_BufferPrefixContent->passTimeStamp ||
63437 + p_BufferPrefixContent->passHashResult) ? 16 : 0));
63438 +
63439 + /* Align start of internal context data to 16 byte */
63440 + p_FmSpIntContextDataCopy->intContextOffset =
63441 + (uint8_t)(p_BufferPrefixContent->passPrsResult ? 32 :
63442 + ((p_BufferPrefixContent->passTimeStamp ||
63443 + p_BufferPrefixContent->passHashResult) ? 64 : 0));
63444 +
63445 + if (p_BufferPrefixContent->passPrsResult)
63446 + p_FmSpBufferOffsets->prsResultOffset = p_FmSpIntContextDataCopy->extBufOffset;
63447 + if (p_BufferPrefixContent->passTimeStamp)
63448 + p_FmSpBufferOffsets->timeStampOffset = p_BufferPrefixContent->passPrsResult ?
63449 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult)) :
63450 + p_FmSpIntContextDataCopy->extBufOffset;
63451 + if (p_BufferPrefixContent->passHashResult)
63452 + /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */
63453 + p_FmSpBufferOffsets->hashResultOffset = p_BufferPrefixContent->passPrsResult ?
63454 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult) + 8) :
63455 + p_FmSpIntContextDataCopy->extBufOffset + 8;
63456 + }
63457 +
63458 + if (p_FmSpIntContextDataCopy->size)
63459 + p_FmSpBufMargins->startMargins =
63460 + (uint16_t)(p_FmSpIntContextDataCopy->extBufOffset +
63461 + p_FmSpIntContextDataCopy->size);
63462 + else
63463 + /* No Internal Context passing, STartMargin is immediately after privateInfo */
63464 + p_FmSpBufMargins->startMargins = p_BufferPrefixContent->privDataSize;
63465 +
63466 + /* save extra space for manip in both external and internal buffers */
63467 + if (p_BufferPrefixContent->manipExtraSpace)
63468 + {
63469 + uint8_t extraSpace;
63470 +#ifdef FM_CAPWAP_SUPPORT
63471 + if ((p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE) >= 256)
63472 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
63473 + ("p_BufferPrefixContent->manipExtraSpace should be less than %d",
63474 + 256-CAPWAP_FRAG_EXTRA_SPACE));
63475 + extraSpace = (uint8_t)(p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE);
63476 +#else
63477 + extraSpace = p_BufferPrefixContent->manipExtraSpace;
63478 +#endif /* FM_CAPWAP_SUPPORT */
63479 + p_FmSpBufferOffsets->manipOffset = p_FmSpBufMargins->startMargins;
63480 + p_FmSpBufMargins->startMargins += extraSpace;
63481 + *internalBufferOffset = extraSpace;
63482 + }
63483 +
63484 + /* align data start */
63485 + tmp = (uint32_t)(p_FmSpBufMargins->startMargins % p_BufferPrefixContent->dataAlign);
63486 + if (tmp)
63487 + p_FmSpBufMargins->startMargins += (p_BufferPrefixContent->dataAlign-tmp);
63488 + p_FmSpBufferOffsets->dataOffset = p_FmSpBufMargins->startMargins;
63489 +
63490 + return E_OK;
63491 +}
63492 +/*********************** End of inter-module routines ************************/
63493 +
63494 +
63495 +#if (DPAA_VERSION >= 11)
63496 +/*****************************************************************************/
63497 +/* API routines */
63498 +/*****************************************************************************/
63499 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams)
63500 +{
63501 + t_FmVspEntry *p_FmVspEntry = NULL;
63502 + struct fm_storage_profile_params fm_vsp_params;
63503 +
63504 + p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry));
63505 + if (!p_FmVspEntry)
63506 + {
63507 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63508 + return NULL;
63509 + }
63510 + memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry));
63511 +
63512 + p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams));
63513 + if (!p_FmVspEntry->p_FmVspEntryDriverParams)
63514 + {
63515 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63516 + XX_Free(p_FmVspEntry);
63517 + return NULL;
63518 + }
63519 + memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams));
63520 + fman_vsp_defconfig(&fm_vsp_params);
63521 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr;
63522 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr;
63523 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr;
63524 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data;
63525 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize;
63526 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather;
63527 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize;
63528 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult;
63529 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63530 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo
63531 + = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63532 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63533 + p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset;
63534 +
63535 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools));
63536 + p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm;
63537 + p_FmVspEntry->portType = p_FmVspParams->portParams.portType;
63538 + p_FmVspEntry->portId = p_FmVspParams->portParams.portId;
63539 +
63540 + p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId;
63541 +
63542 + return p_FmVspEntry;
63543 +}
63544 +
63545 +t_Error FM_VSP_Init(t_Handle h_FmVsp)
63546 +{
63547 +
63548 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63549 + struct fm_storage_profile_params fm_vsp_params;
63550 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
63551 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
63552 + t_Error err;
63553 + uint16_t absoluteProfileId = 0;
63554 + int i = 0;
63555 +
63556 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63557 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams,E_INVALID_HANDLE);
63558 +
63559 + CHECK_INIT_PARAMETERS(p_FmVspEntry, CheckParams);
63560 +
63561 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
63562 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
63563 +
63564 + err = FmSpBuildBufferStructure(&p_FmVspEntry->intContext,
63565 + &p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent,
63566 + &p_FmVspEntry->bufMargins,
63567 + &p_FmVspEntry->bufferOffsets,
63568 + &p_FmVspEntry->internalBufferOffset);
63569 + if (err != E_OK)
63570 + RETURN_ERROR(MAJOR, err, NO_MSG);
63571 +
63572 +
63573 + err = CheckParamsGeneratedInternally(p_FmVspEntry);
63574 + if (err != E_OK)
63575 + RETURN_ERROR(MAJOR, err, NO_MSG);
63576 +
63577 +
63578 + p_FmVspEntry->p_FmSpRegsBase =
63579 + (struct fm_pcd_storage_profile_regs *)FmGetVSPBaseAddr(p_FmVspEntry->h_Fm);
63580 + if (!p_FmVspEntry->p_FmSpRegsBase)
63581 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("impossible to initialize SpRegsBase"));
63582 +
63583 + /* order external buffer pools in ascending order of buffer pools sizes */
63584 + FmSpSetBufPoolsInAscOrderOfBufSizes(&(p_FmVspEntry->p_FmVspEntryDriverParams)->extBufPools,
63585 + orderedArray,
63586 + sizesArray);
63587 +
63588 + p_FmVspEntry->extBufPools.numOfPoolsUsed =
63589 + p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools.numOfPoolsUsed;
63590 + for (i = 0; i < p_FmVspEntry->extBufPools.numOfPoolsUsed; i++)
63591 + {
63592 + p_FmVspEntry->extBufPools.extBufPool[i].id = orderedArray[i];
63593 + p_FmVspEntry->extBufPools.extBufPool[i].size = sizesArray[orderedArray[i]];
63594 + }
63595 +
63596 + /* on user responsibility to fill it according requirement */
63597 + memset(&fm_vsp_params, 0, sizeof(struct fm_storage_profile_params));
63598 + fm_vsp_params.dma_swap_data = p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData;
63599 + fm_vsp_params.int_context_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr;
63600 + fm_vsp_params.header_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr;
63601 + fm_vsp_params.scatter_gather_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr;
63602 + fm_vsp_params.dma_write_optimize = p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize;
63603 + fm_vsp_params.liodn_offset = p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset;
63604 + fm_vsp_params.no_scather_gather = p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather;
63605 +
63606 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
63607 + {
63608 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = TRUE;
63609 + fm_vsp_params.buf_pool_depletion.pools_grp_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsGrpModeEnable;
63610 + fm_vsp_params.buf_pool_depletion.num_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->numOfPools;
63611 + fm_vsp_params.buf_pool_depletion.pools_to_consider = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsider;
63612 + fm_vsp_params.buf_pool_depletion.single_pool_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->singlePoolModeEnable;
63613 + fm_vsp_params.buf_pool_depletion.pools_to_consider_for_single_mode = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsiderForSingleMode;
63614 + fm_vsp_params.buf_pool_depletion.has_pfc_priorities = TRUE;
63615 + fm_vsp_params.buf_pool_depletion.pfc_priorities_en = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->pfcPrioritiesEn;
63616 + }
63617 + else
63618 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = FALSE;
63619 +
63620 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
63621 + {
63622 + fm_vsp_params.backup_pools.num_backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->numOfBackupPools;
63623 + fm_vsp_params.backup_pools.pool_ids = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->poolIds;
63624 + }
63625 + else
63626 + fm_vsp_params.backup_pools.num_backup_pools = 0;
63627 +
63628 + fm_vsp_params.fm_ext_pools.num_pools_used = p_FmVspEntry->extBufPools.numOfPoolsUsed;
63629 + fm_vsp_params.fm_ext_pools.ext_buf_pool = (struct fman_ext_pool_params*)&p_FmVspEntry->extBufPools.extBufPool;
63630 + fm_vsp_params.buf_margins = (struct fman_sp_buf_margins*)&p_FmVspEntry->bufMargins;
63631 + fm_vsp_params.int_context = (struct fman_sp_int_context_data_copy*)&p_FmVspEntry->intContext;
63632 +
63633 + /* no check on err - it was checked earlier */
63634 + FmVSPGetAbsoluteProfileId(p_FmVspEntry->h_Fm,
63635 + p_FmVspEntry->portType,
63636 + p_FmVspEntry->portId,
63637 + p_FmVspEntry->relativeProfileId,
63638 + &absoluteProfileId);
63639 +
63640 + ASSERT_COND(p_FmVspEntry->p_FmSpRegsBase);
63641 + ASSERT_COND(fm_vsp_params.int_context);
63642 + ASSERT_COND(fm_vsp_params.buf_margins);
63643 + ASSERT_COND((absoluteProfileId <= FM_VSP_MAX_NUM_OF_ENTRIES));
63644 +
63645 + /* Set all registers related to VSP */
63646 + 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);
63647 +
63648 + p_FmVspEntry->absoluteSpId = absoluteProfileId;
63649 +
63650 + if (p_FmVspEntry->p_FmVspEntryDriverParams)
63651 + XX_Free(p_FmVspEntry->p_FmVspEntryDriverParams);
63652 + p_FmVspEntry->p_FmVspEntryDriverParams = NULL;
63653 +
63654 + return E_OK;
63655 +}
63656 +
63657 +t_Error FM_VSP_Free(t_Handle h_FmVsp)
63658 +{
63659 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63660 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63661 + XX_Free(p_FmVspEntry);
63662 + return E_OK;
63663 +}
63664 +
63665 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
63666 +{
63667 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63668 +
63669 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63670 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63671 +
63672 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
63673 + /* if dataAlign was not initialized by user, we return to driver's default */
63674 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign)
63675 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63676 +
63677 + return E_OK;
63678 +}
63679 +
63680 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData)
63681 +{
63682 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63683 +
63684 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63685 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63686 +
63687 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = swapData;
63688 +
63689 + return E_OK;
63690 +}
63691 +
63692 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, e_FmDmaCacheOption intContextCacheAttr)
63693 +{
63694 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63695 +
63696 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63697 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63698 +
63699 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = intContextCacheAttr;
63700 +
63701 + return E_OK;
63702 +}
63703 +
63704 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr)
63705 +{
63706 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63707 +
63708 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63709 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63710 +
63711 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = headerCacheAttr;
63712 +
63713 + return E_OK;
63714 +}
63715 +
63716 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, e_FmDmaCacheOption scatterGatherCacheAttr)
63717 +{
63718 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63719 +
63720 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63721 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63722 +
63723 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = scatterGatherCacheAttr;
63724 +
63725 + return E_OK;
63726 +}
63727 +
63728 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize)
63729 +{
63730 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63731 +
63732 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63733 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63734 +
63735 +
63736 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = optimize;
63737 +
63738 + return E_OK;
63739 +}
63740 +
63741 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather)
63742 +{
63743 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63744 +
63745 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63746 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63747 +
63748 +
63749 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = noScatherGather;
63750 +
63751 + return E_OK;
63752 +}
63753 +
63754 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion)
63755 +{
63756 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63757 +
63758 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63759 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63760 + SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE);
63761 +
63762 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion));
63763 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
63764 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed"));
63765 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion));
63766 +
63767 + return E_OK;
63768 +}
63769 +
63770 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools)
63771 +{
63772 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63773 +
63774 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63775 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63776 + SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE);
63777 +
63778 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
63779 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
63780 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
63781 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools));
63782 +
63783 + return E_OK;
63784 +}
63785 +
63786 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp)
63787 +{
63788 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63789 +
63790 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, 0);
63791 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, 0);
63792 +
63793 + return p_FmVspEntry->bufferOffsets.dataOffset;
63794 +}
63795 +
63796 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data)
63797 +{
63798 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63799 +
63800 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63801 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63802 +
63803 + if (p_FmVspEntry->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
63804 + return NULL;
63805 +
63806 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.pcdInfoOffset);
63807 +}
63808 +
63809 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data)
63810 +{
63811 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63812 +
63813 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63814 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63815 +
63816 + if (p_FmVspEntry->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
63817 + return NULL;
63818 +
63819 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.prsResultOffset);
63820 +}
63821 +
63822 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data)
63823 +{
63824 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63825 +
63826 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63827 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63828 +
63829 + if (p_FmVspEntry->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
63830 + return NULL;
63831 +
63832 + return (uint64_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.timeStampOffset);
63833 +}
63834 +
63835 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data)
63836 +{
63837 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63838 +
63839 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63840 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63841 +
63842 + if (p_FmVspEntry->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
63843 + return NULL;
63844 +
63845 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.hashResultOffset);
63846 +}
63847 +
63848 +#endif /* (DPAA_VERSION >= 11) */
63849 --- /dev/null
63850 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
63851 @@ -0,0 +1,85 @@
63852 +/*
63853 + * Copyright 2008-2012 Freescale Semiconductor Inc.
63854 + *
63855 + * Redistribution and use in source and binary forms, with or without
63856 + * modification, are permitted provided that the following conditions are met:
63857 + * * Redistributions of source code must retain the above copyright
63858 + * notice, this list of conditions and the following disclaimer.
63859 + * * Redistributions in binary form must reproduce the above copyright
63860 + * notice, this list of conditions and the following disclaimer in the
63861 + * documentation and/or other materials provided with the distribution.
63862 + * * Neither the name of Freescale Semiconductor nor the
63863 + * names of its contributors may be used to endorse or promote products
63864 + * derived from this software without specific prior written permission.
63865 + *
63866 + *
63867 + * ALTERNATIVELY, this software may be distributed under the terms of the
63868 + * GNU General Public License ("GPL") as published by the Free Software
63869 + * Foundation, either version 2 of that License or (at your option) any
63870 + * later version.
63871 + *
63872 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63873 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63874 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63875 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63876 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63877 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63878 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63879 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63880 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63881 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63882 + */
63883 +
63884 +
63885 +/******************************************************************************
63886 + @File fm_sp.h
63887 +
63888 + @Description FM SP ...
63889 +*//***************************************************************************/
63890 +#ifndef __FM_SP_H
63891 +#define __FM_SP_H
63892 +
63893 +#include "std_ext.h"
63894 +#include "error_ext.h"
63895 +#include "list_ext.h"
63896 +
63897 +#include "fm_sp_common.h"
63898 +#include "fm_common.h"
63899 +
63900 +
63901 +#define __ERR_MODULE__ MODULE_FM_SP
63902 +
63903 +typedef struct {
63904 + t_FmBufferPrefixContent bufferPrefixContent;
63905 + e_FmDmaSwapOption dmaSwapData;
63906 + e_FmDmaCacheOption dmaIntContextCacheAttr;
63907 + e_FmDmaCacheOption dmaHeaderCacheAttr;
63908 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
63909 + bool dmaWriteOptimize;
63910 + uint16_t liodnOffset;
63911 + bool noScatherGather;
63912 + t_FmBufPoolDepletion *p_BufPoolDepletion;
63913 + t_FmBackupBmPools *p_BackupBmPools;
63914 + t_FmExtPools extBufPools;
63915 +} t_FmVspEntryDriverParams;
63916 +
63917 +typedef struct {
63918 + bool valid;
63919 + volatile bool lock;
63920 + uint8_t pointedOwners;
63921 + uint16_t absoluteSpId;
63922 + uint8_t internalBufferOffset;
63923 + t_FmSpBufMargins bufMargins;
63924 + t_FmSpIntContextDataCopy intContext;
63925 + t_FmSpBufferOffsets bufferOffsets;
63926 + t_Handle h_Fm;
63927 + e_FmPortType portType; /**< Port type */
63928 + uint8_t portId; /**< Port Id - relative to type */
63929 + uint8_t relativeProfileId;
63930 + struct fm_pcd_storage_profile_regs *p_FmSpRegsBase;
63931 + t_FmExtPools extBufPools;
63932 + t_FmVspEntryDriverParams *p_FmVspEntryDriverParams;
63933 +} t_FmVspEntry;
63934 +
63935 +
63936 +#endif /* __FM_SP_H */
63937 --- /dev/null
63938 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
63939 @@ -0,0 +1,197 @@
63940 +/*
63941 + * Copyright 2013 Freescale Semiconductor Inc.
63942 + *
63943 + * Redistribution and use in source and binary forms, with or without
63944 + * modification, are permitted provided that the following conditions are met:
63945 + * * Redistributions of source code must retain the above copyright
63946 + * notice, this list of conditions and the following disclaimer.
63947 + * * Redistributions in binary form must reproduce the above copyright
63948 + * notice, this list of conditions and the following disclaimer in the
63949 + * documentation and/or other materials provided with the distribution.
63950 + * * Neither the name of Freescale Semiconductor nor the
63951 + * names of its contributors may be used to endorse or promote products
63952 + * derived from this software without specific prior written permission.
63953 + *
63954 + *
63955 + * ALTERNATIVELY, this software may be distributed under the terms of the
63956 + * GNU General Public License ("GPL") as published by the Free Software
63957 + * Foundation, either version 2 of that License or (at your option) any
63958 + * later version.
63959 + *
63960 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63961 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63962 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63963 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63964 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63965 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63966 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63967 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63968 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63969 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63970 + */
63971 +
63972 +#include "fsl_fman_sp.h"
63973 +
63974 +
63975 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
63976 + uint16_t index)
63977 +{
63978 + struct fm_pcd_storage_profile_regs *sp_regs;
63979 + sp_regs = &regs[index];
63980 + return ioread32be(&sp_regs->fm_sp_acnt);
63981 +}
63982 +
63983 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
63984 + uint16_t index, uint32_t value)
63985 +{
63986 + struct fm_pcd_storage_profile_regs *sp_regs;
63987 + sp_regs = &regs[index];
63988 + iowrite32be(value, &sp_regs->fm_sp_acnt);
63989 +}
63990 +
63991 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg)
63992 +{
63993 + cfg->dma_swap_data =
63994 + DEFAULT_FMAN_SP_DMA_SWAP_DATA;
63995 + cfg->int_context_cache_attr =
63996 + DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR;
63997 + cfg->header_cache_attr =
63998 + DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR;
63999 + cfg->scatter_gather_cache_attr =
64000 + DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR;
64001 + cfg->dma_write_optimize =
64002 + DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE;
64003 + cfg->no_scather_gather =
64004 + DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
64005 +}
64006 +
64007 +static inline uint32_t calc_vec_dep(int max_pools, bool *pools,
64008 + struct fman_ext_pools *ext_buf_pools, uint32_t mask)
64009 +{
64010 + int i, j;
64011 + uint32_t vector = 0;
64012 + for (i = 0; i < max_pools; i++)
64013 + if (pools[i])
64014 + for (j = 0; j < ext_buf_pools->num_pools_used; j++)
64015 + if (i == ext_buf_pools->ext_buf_pool[j].id) {
64016 + vector |= mask >> j;
64017 + break;
64018 + }
64019 + return vector;
64020 +}
64021 +
64022 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
64023 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
64024 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
64025 + int max_num_of_pfc_priorities)
64026 +{
64027 + int i = 0, j = 0;
64028 + struct fm_pcd_storage_profile_regs *sp_regs;
64029 + uint32_t tmp_reg, vector;
64030 + struct fman_ext_pools *ext_buf_pools = &fm_vsp_params->fm_ext_pools;
64031 + struct fman_buf_pool_depletion *buf_pool_depletion =
64032 + &fm_vsp_params->buf_pool_depletion;
64033 + struct fman_backup_bm_pools *backup_pools =
64034 + &fm_vsp_params->backup_pools;
64035 + struct fman_sp_int_context_data_copy *int_context_data_copy =
64036 + fm_vsp_params->int_context;
64037 + struct fman_sp_buf_margins *external_buffer_margins =
64038 + fm_vsp_params->buf_margins;
64039 + bool no_scather_gather = fm_vsp_params->no_scather_gather;
64040 + uint16_t liodn_offset = fm_vsp_params->liodn_offset;
64041 +
64042 + sp_regs = &regs[index];
64043 +
64044 + /* fill external buffers manager pool information register*/
64045 + for (i = 0; i < ext_buf_pools->num_pools_used; i++) {
64046 + tmp_reg = FMAN_SP_EXT_BUF_POOL_VALID |
64047 + FMAN_SP_EXT_BUF_POOL_EN_COUNTER;
64048 + tmp_reg |= ((uint32_t)ext_buf_pools->ext_buf_pool[i].id <<
64049 + FMAN_SP_EXT_BUF_POOL_ID_SHIFT);
64050 + tmp_reg |= ext_buf_pools->ext_buf_pool[i].size;
64051 + /* functionality available only for some deriviatives
64052 + (limited by config) */
64053 + for (j = 0; j < backup_pools->num_backup_pools; j++)
64054 + if (ext_buf_pools->ext_buf_pool[i].id ==
64055 + backup_pools->pool_ids[j]) {
64056 + tmp_reg |= FMAN_SP_EXT_BUF_POOL_BACKUP;
64057 + break;
64058 + }
64059 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebmpi[i]);
64060 + }
64061 +
64062 + /* clear unused pools */
64063 + for (i = ext_buf_pools->num_pools_used;
64064 + i < port_max_num_of_ext_pools; i++)
64065 + iowrite32be(0, &sp_regs->fm_sp_ebmpi[i]);
64066 +
64067 + /* fill pool depletion register*/
64068 + tmp_reg = 0;
64069 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->pools_grp_mode_enable) {
64070 + /* calculate vector for number of pools depletion */
64071 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
64072 + pools_to_consider, ext_buf_pools, 0x80000000);
64073 +
64074 + /* configure num of pools and vector for number of pools mode */
64075 + tmp_reg |= (((uint32_t)buf_pool_depletion->num_pools - 1) <<
64076 + FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT);
64077 + tmp_reg |= vector;
64078 + }
64079 +
64080 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->single_pool_mode_enable) {
64081 + /* calculate vector for number of pools depletion */
64082 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
64083 + pools_to_consider_for_single_mode,
64084 + ext_buf_pools, 0x00000080);
64085 +
64086 + /* configure num of pools and vector for number of pools mode */
64087 + tmp_reg |= vector;
64088 + }
64089 +
64090 + /* fill QbbPEV */
64091 + if (buf_pool_depletion->buf_pool_depletion_enabled) {
64092 + vector = 0;
64093 + for (i = 0; i < max_num_of_pfc_priorities; i++)
64094 + if (buf_pool_depletion->pfc_priorities_en[i] == TRUE)
64095 + vector |= 0x00000100 << i;
64096 + tmp_reg |= vector;
64097 + }
64098 + iowrite32be(tmp_reg, &sp_regs->fm_sp_mpd);
64099 +
64100 + /* fill dma attributes register */
64101 + tmp_reg = 0;
64102 + tmp_reg |= (uint32_t)fm_vsp_params->dma_swap_data <<
64103 + FMAN_SP_DMA_ATTR_SWP_SHIFT;
64104 + tmp_reg |= (uint32_t)fm_vsp_params->int_context_cache_attr <<
64105 + FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT;
64106 + tmp_reg |= (uint32_t)fm_vsp_params->header_cache_attr <<
64107 + FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT;
64108 + tmp_reg |= (uint32_t)fm_vsp_params->scatter_gather_cache_attr <<
64109 + FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT;
64110 + if (fm_vsp_params->dma_write_optimize)
64111 + tmp_reg |= FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE;
64112 + iowrite32be(tmp_reg, &sp_regs->fm_sp_da);
64113 +
64114 + /* IC parameters - fill internal context parameters register */
64115 + tmp_reg = 0;
64116 + tmp_reg |= (((uint32_t)int_context_data_copy->ext_buf_offset/
64117 + OFFSET_UNITS) << FMAN_SP_IC_TO_EXT_SHIFT);
64118 + tmp_reg |= (((uint32_t)int_context_data_copy->int_context_offset/
64119 + OFFSET_UNITS) << FMAN_SP_IC_FROM_INT_SHIFT);
64120 + tmp_reg |= (((uint32_t)int_context_data_copy->size/OFFSET_UNITS) <<
64121 + FMAN_SP_IC_SIZE_SHIFT);
64122 + iowrite32be(tmp_reg, &sp_regs->fm_sp_icp);
64123 +
64124 + /* buffer margins - fill external buffer margins register */
64125 + tmp_reg = 0;
64126 + tmp_reg |= (((uint32_t)external_buffer_margins->start_margins) <<
64127 + FMAN_SP_EXT_BUF_MARG_START_SHIFT);
64128 + tmp_reg |= (((uint32_t)external_buffer_margins->end_margins) <<
64129 + FMAN_SP_EXT_BUF_MARG_END_SHIFT);
64130 + if (no_scather_gather)
64131 + tmp_reg |= FMAN_SP_SG_DISABLE;
64132 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebm);
64133 +
64134 + /* buffer margins - fill spliodn register */
64135 + iowrite32be(liodn_offset, &sp_regs->fm_sp_spliodn);
64136 +}
64137 --- /dev/null
64138 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
64139 @@ -0,0 +1,5216 @@
64140 +/*
64141 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64142 + *
64143 + * Redistribution and use in source and binary forms, with or without
64144 + * modification, are permitted provided that the following conditions are met:
64145 + * * Redistributions of source code must retain the above copyright
64146 + * notice, this list of conditions and the following disclaimer.
64147 + * * Redistributions in binary form must reproduce the above copyright
64148 + * notice, this list of conditions and the following disclaimer in the
64149 + * documentation and/or other materials provided with the distribution.
64150 + * * Neither the name of Freescale Semiconductor nor the
64151 + * names of its contributors may be used to endorse or promote products
64152 + * derived from this software without specific prior written permission.
64153 + *
64154 + *
64155 + * ALTERNATIVELY, this software may be distributed under the terms of the
64156 + * GNU General Public License ("GPL") as published by the Free Software
64157 + * Foundation, either version 2 of that License or (at your option) any
64158 + * later version.
64159 + *
64160 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64161 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64162 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64163 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64164 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64165 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64166 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64167 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64168 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64169 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64170 + */
64171 +
64172 +
64173 +/******************************************************************************
64174 + @File fm.c
64175 +
64176 + @Description FM driver routines implementation.
64177 +*//***************************************************************************/
64178 +#include "std_ext.h"
64179 +#include "error_ext.h"
64180 +#include "xx_ext.h"
64181 +#include "string_ext.h"
64182 +#include "sprint_ext.h"
64183 +#include "debug_ext.h"
64184 +#include "fm_muram_ext.h"
64185 +#include <linux/math64.h>
64186 +
64187 +#include "fm_common.h"
64188 +#include "fm_ipc.h"
64189 +#include "fm.h"
64190 +#ifndef CONFIG_FMAN_ARM
64191 +#include <linux/fsl/svr.h>
64192 +#endif
64193 +#include "fsl_fman.h"
64194 +
64195 +
64196 +/****************************************/
64197 +/* static functions */
64198 +/****************************************/
64199 +
64200 +static volatile bool blockingFlag = FALSE;
64201 +static void IpcMsgCompletionCB(t_Handle h_Fm,
64202 + uint8_t *p_Msg,
64203 + uint8_t *p_Reply,
64204 + uint32_t replyLength,
64205 + t_Error status)
64206 +{
64207 + UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
64208 + blockingFlag = FALSE;
64209 +}
64210 +
64211 +static void FreeInitResources(t_Fm *p_Fm)
64212 +{
64213 + if (p_Fm->camBaseAddr)
64214 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
64215 + if (p_Fm->fifoBaseAddr)
64216 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
64217 + if (p_Fm->resAddr)
64218 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
64219 +}
64220 +
64221 +static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
64222 +{
64223 + t_FMIramRegs *p_Iram;
64224 +
64225 + ASSERT_COND(p_Fm);
64226 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64227 +
64228 + return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
64229 +}
64230 +
64231 +static t_Error CheckFmParameters(t_Fm *p_Fm)
64232 +{
64233 + if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->resetOnInit)
64234 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
64235 +#if (DPAA_VERSION < 11)
64236 + if (!p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats ||
64237 + (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
64238 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64239 + ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
64240 +#endif /* (DPAA_VERSION < 11) */
64241 + if (p_Fm->p_FmDriverParam->dma_cam_num_of_entries % DMA_CAM_UNITS)
64242 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be divisble by %d", DMA_CAM_UNITS));
64243 +// 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))
64244 +// 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));
64245 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer > DMA_THRESH_MAX_COMMQ)
64246 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64247 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer > DMA_THRESH_MAX_COMMQ)
64248 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64249 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer >= p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer)
64250 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer must be smaller than dma_comm_qtsh_asrt_emer"));
64251 +#if (DPAA_VERSION < 11)
64252 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64253 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64254 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64255 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64256 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer)
64257 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer must be smaller than dma_read_buf_tsh_asrt_emer"));
64258 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64259 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64260 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64261 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64262 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer)
64263 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer must be smaller than dma_write_buf_tsh_asrt_emer"));
64264 +#else /* (DPAA_VERSION >= 11) */
64265 + if ((p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_READ_EM)||
64266 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_WRITE_EM) ||
64267 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT))
64268 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_dbg_cnt_mode value not supported by this integration."));
64269 + if ((p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_READ_EMERGENCY)||
64270 + (p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_WRITE_EMERGENCY))
64271 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration."));
64272 + if (p_Fm->p_FmDriverParam->dma_stop_on_bus_error)
64273 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_stop_on_bus_error not supported by this integration."));
64274 +#ifdef FM_AID_MODE_NO_TNUM_SW005
64275 + if (p_Fm->p_FmDriverParam->dma_aid_mode != E_FMAN_DMA_AID_OUT_PORT_ID)
64276 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_aid_mode not supported by this integration."));
64277 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
64278 + if (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats)
64279 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_axi_dbg_num_of_beats not supported by this integration."));
64280 +#endif /* (DPAA_VERSION < 11) */
64281 +
64282 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
64283 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
64284 + if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dma_watchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
64285 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64286 + ("dma_watchdog depends on FM clock. dma_watchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
64287 +
64288 +#if (DPAA_VERSION >= 11)
64289 + if ((p_Fm->partVSPBase + p_Fm->partNumOfVSPs) > FM_VSP_MAX_NUM_OF_ENTRIES)
64290 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partVSPBase+partNumOfVSPs out of range!!!"));
64291 +#endif /* (DPAA_VERSION >= 11) */
64292 +
64293 + if (p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
64294 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
64295 + if (!p_Fm->p_FmStateStruct->totalFifoSize ||
64296 + (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
64297 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64298 + ("totalFifoSize (currently defined as %d) has to be in the range of 256 to %d",
64299 + p_Fm->p_FmStateStruct->totalFifoSize,
64300 + BMI_MAX_FIFO_SIZE));
64301 + if (!p_Fm->p_FmStateStruct->totalNumOfTasks ||
64302 + (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
64303 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
64304 +
64305 +#ifdef FM_HAS_TOTAL_DMAS
64306 + if (!p_Fm->p_FmStateStruct->maxNumOfOpenDmas ||
64307 + (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
64308 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
64309 +#endif /* FM_HAS_TOTAL_DMAS */
64310 +
64311 + if (p_Fm->p_FmDriverParam->disp_limit_tsh > FPM_MAX_DISP_LIMIT)
64312 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("disp_limit_tsh can't be greater than %d", FPM_MAX_DISP_LIMIT));
64313 +
64314 + if (!p_Fm->f_Exception)
64315 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64316 + if (!p_Fm->f_BusError)
64317 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64318 +
64319 +#ifdef FM_NO_WATCHDOG
64320 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 2) &&
64321 + (p_Fm->p_FmDriverParam->dma_watchdog))
64322 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("watchdog!"));
64323 +#endif /* FM_NO_WATCHDOG */
64324 +
64325 +#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
64326 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
64327 + (p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err))
64328 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
64329 +#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
64330 +
64331 +#ifdef FM_NO_TNUM_AGING
64332 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64333 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64334 + if (p_Fm->p_FmDriverParam->tnum_aging_period)
64335 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Tnum aging!"));
64336 +#endif /* FM_NO_TNUM_AGING */
64337 +
64338 + /* check that user did not set revision-dependent exceptions */
64339 +#ifdef FM_NO_DISPATCH_RAM_ECC
64340 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64341 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64342 + if (p_Fm->userSetExceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
64343 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
64344 +#endif /* FM_NO_DISPATCH_RAM_ECC */
64345 +
64346 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
64347 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4)
64348 + if (p_Fm->userSetExceptions & (FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC))
64349 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC/e_FM_EX_QMI_DOUBLE_ECC!"));
64350 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
64351 +
64352 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
64353 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
64354 + if (p_Fm->userSetExceptions & FM_EX_QMI_SINGLE_ECC)
64355 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC!"));
64356 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
64357 +
64358 + return E_OK;
64359 +}
64360 +
64361 +
64362 +static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
64363 +{
64364 + ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
64365 +
64366 + if (p_Fm->intrMng[macEvent].guestId == NCSW_MASTER_ID)
64367 + p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
64368 +
64369 + /* If the MAC is running on guest-partition and we have IPC session with it,
64370 + we inform him about the event through IPC; otherwise, we ignore the event. */
64371 + else if (p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId])
64372 + {
64373 + t_Error err;
64374 + t_FmIpcIsr fmIpcIsr;
64375 + t_FmIpcMsg msg;
64376 +
64377 + memset(&msg, 0, sizeof(msg));
64378 + msg.msgId = FM_GUEST_ISR;
64379 + fmIpcIsr.pendingReg = pendingReg;
64380 + fmIpcIsr.boolErr = FALSE;
64381 + memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
64382 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
64383 + (uint8_t*)&msg,
64384 + sizeof(msg.msgId) + sizeof(fmIpcIsr),
64385 + NULL,
64386 + NULL,
64387 + NULL,
64388 + NULL);
64389 + if (err != E_OK)
64390 + REPORT_ERROR(MINOR, err, NO_MSG);
64391 + }
64392 + else
64393 + DBG(TRACE, ("FM Guest mode, without IPC - can't call ISR!"));
64394 +}
64395 +
64396 +static void BmiErrEvent(t_Fm *p_Fm)
64397 +{
64398 + uint32_t event;
64399 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
64400 +
64401 +
64402 + event = fman_get_bmi_err_event(bmi_rg);
64403 +
64404 + if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC)
64405 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STORAGE_PROFILE_ECC);
64406 + if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
64407 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
64408 + if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
64409 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
64410 + if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
64411 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
64412 +}
64413 +
64414 +static void QmiErrEvent(t_Fm *p_Fm)
64415 +{
64416 + uint32_t event;
64417 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64418 +
64419 + event = fman_get_qmi_err_event(qmi_rg);
64420 +
64421 + if (event & QMI_ERR_INTR_EN_DOUBLE_ECC)
64422 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
64423 + if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
64424 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
64425 +}
64426 +
64427 +static void DmaErrEvent(t_Fm *p_Fm)
64428 +{
64429 + uint32_t status, com_id;
64430 + uint8_t tnum;
64431 + uint8_t hardwarePortId;
64432 + uint8_t relativePortId;
64433 + uint16_t liodn;
64434 + struct fman_dma_regs *dma_rg = p_Fm->p_FmDmaRegs;
64435 +
64436 + status = fman_get_dma_err_event(dma_rg);
64437 +
64438 + if (status & DMA_STATUS_BUS_ERR)
64439 + {
64440 + com_id = fman_get_dma_com_id(dma_rg);
64441 + hardwarePortId = (uint8_t)(((com_id & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
64442 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
64443 + HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
64444 + tnum = (uint8_t)((com_id & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
64445 + liodn = (uint16_t)(com_id & DMA_TRANSFER_LIODN_MASK);
64446 + ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
64447 + p_Fm->f_BusError(p_Fm->h_App,
64448 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId],
64449 + relativePortId,
64450 + fman_get_dma_addr(dma_rg),
64451 + tnum,
64452 + liodn);
64453 + }
64454 + if (status & DMA_STATUS_FM_SPDAT_ECC)
64455 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SINGLE_PORT_ECC);
64456 + if (status & DMA_STATUS_READ_ECC)
64457 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
64458 + if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
64459 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
64460 + if (status & DMA_STATUS_FM_WRITE_ECC)
64461 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
64462 + }
64463 +
64464 +static void FpmErrEvent(t_Fm *p_Fm)
64465 +{
64466 + uint32_t event;
64467 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64468 +
64469 + event = fman_get_fpm_err_event(fpm_rg);
64470 +
64471 + if ((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
64472 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
64473 + if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
64474 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
64475 + if ((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
64476 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
64477 +}
64478 +
64479 +static void MuramErrIntr(t_Fm *p_Fm)
64480 +{
64481 + uint32_t event;
64482 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64483 +
64484 + event = fman_get_muram_err_event(fpm_rg);
64485 +
64486 + if (event & FPM_RAM_MURAM_ECC)
64487 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
64488 +}
64489 +
64490 +static void IramErrIntr(t_Fm *p_Fm)
64491 +{
64492 + uint32_t event;
64493 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64494 +
64495 + event = fman_get_iram_err_event(fpm_rg);
64496 +
64497 + if (event & FPM_RAM_IRAM_ECC)
64498 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
64499 +}
64500 +
64501 +static void QmiEvent(t_Fm *p_Fm)
64502 +{
64503 + uint32_t event;
64504 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64505 +
64506 + event = fman_get_qmi_event(qmi_rg);
64507 +
64508 + if (event & QMI_INTR_EN_SINGLE_ECC)
64509 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
64510 +}
64511 +
64512 +static void UnimplementedIsr(t_Handle h_Arg)
64513 +{
64514 + UNUSED(h_Arg);
64515 +
64516 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented ISR!"));
64517 +}
64518 +
64519 +static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
64520 +{
64521 + UNUSED(h_Arg); UNUSED(event);
64522 +
64523 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl ISR!"));
64524 +}
64525 +
64526 +static void EnableTimeStamp(t_Fm *p_Fm)
64527 +{
64528 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64529 +
64530 + ASSERT_COND(p_Fm->p_FmStateStruct);
64531 + ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit);
64532 +
64533 + fman_enable_time_stamp(fpm_rg, p_Fm->p_FmStateStruct->count1MicroBit, p_Fm->p_FmStateStruct->fmClkFreq);
64534 +
64535 + p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
64536 +}
64537 +
64538 +static t_Error ClearIRam(t_Fm *p_Fm)
64539 +{
64540 + t_FMIramRegs *p_Iram;
64541 + int i;
64542 + int iram_size;
64543 +
64544 + ASSERT_COND(p_Fm);
64545 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64546 + iram_size = FM_IRAM_SIZE(p_Fm->p_FmStateStruct->revInfo.majorRev,p_Fm->p_FmStateStruct->revInfo.minorRev);
64547 +
64548 + /* Enable the auto-increment */
64549 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64550 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64551 +
64552 + for (i=0; i < (iram_size/4); i++)
64553 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64554 +
64555 + WRITE_UINT32(p_Iram->iadd, iram_size - 4);
64556 + CORE_MemoryBarrier();
64557 + while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
64558 +
64559 + return E_OK;
64560 +}
64561 +
64562 +static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
64563 +{
64564 + t_FMIramRegs *p_Iram;
64565 + int i;
64566 + uint32_t tmp;
64567 + uint8_t compTo16;
64568 +
64569 + ASSERT_COND(p_Fm);
64570 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64571 +
64572 + /* Enable the auto-increment */
64573 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64574 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64575 +
64576 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64577 + WRITE_UINT32(p_Iram->idata, p_Fm->firmware.p_Code[i]);
64578 +
64579 + compTo16 = (uint8_t)(p_Fm->firmware.size % 16);
64580 + if (compTo16)
64581 + for (i=0; i < ((16-compTo16) / 4); i++)
64582 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64583 +
64584 + WRITE_UINT32(p_Iram->iadd,p_Fm->firmware.size-4);
64585 + while (GET_UINT32(p_Iram->iadd) != (p_Fm->firmware.size-4)) ;
64586 +
64587 + /* verify that writing has completed */
64588 + while (GET_UINT32(p_Iram->idata) != p_Fm->firmware.p_Code[(p_Fm->firmware.size / 4)-1]) ;
64589 +
64590 + if (p_Fm->fwVerify)
64591 + {
64592 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64593 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64594 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64595 + {
64596 + tmp = GET_UINT32(p_Iram->idata);
64597 + if (tmp != p_Fm->firmware.p_Code[i])
64598 + RETURN_ERROR(MAJOR, E_WRITE_FAILED,
64599 + ("UCode write error : write 0x%x, read 0x%x",
64600 + p_Fm->firmware.p_Code[i],tmp));
64601 + }
64602 + WRITE_UINT32(p_Iram->iadd, 0x0);
64603 + }
64604 +
64605 + /* Enable patch from IRAM */
64606 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64607 + XX_UDelay(1000);
64608 +
64609 + DBG(INFO, ("FMan-Controller code (ver %d.%d.%d) loaded to IRAM.",
64610 + ((uint16_t *)p_Fm->firmware.p_Code)[2],
64611 + ((uint8_t *)p_Fm->firmware.p_Code)[6],
64612 + ((uint8_t *)p_Fm->firmware.p_Code)[7]));
64613 +
64614 + return E_OK;
64615 +}
64616 +
64617 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
64618 +static t_Error FwNotResetErratumBugzilla6173WA(t_Fm *p_Fm)
64619 +{
64620 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64621 + uint32_t tmpReg;
64622 + uint32_t savedSpliodn[63];
64623 +
64624 + /* write to IRAM first location the debug instruction */
64625 + WRITE_UINT32(p_Iram->iadd, 0);
64626 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64627 + WRITE_UINT32(p_Iram->idata, FM_FW_DEBUG_INSTRUCTION);
64628 +
64629 + WRITE_UINT32(p_Iram->iadd, 0);
64630 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64631 + while (GET_UINT32(p_Iram->idata) != FM_FW_DEBUG_INSTRUCTION) ;
64632 +
64633 + /* Enable patch from IRAM */
64634 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64635 + CORE_MemoryBarrier();
64636 + XX_UDelay(100);
64637 + IO2MemCpy32((uint8_t *)savedSpliodn,
64638 + (uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64639 + 63*sizeof(uint32_t));
64640 +
64641 + /* reset FMAN */
64642 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64643 + CORE_MemoryBarrier();
64644 + XX_UDelay(100);
64645 +
64646 + /* verify breakpoint debug status register */
64647 + tmpReg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
64648 + if (!tmpReg)
64649 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid debug status register value is '0'"));
64650 +
64651 + /*************************************/
64652 + /* Load FMan-Controller code to IRAM */
64653 + /*************************************/
64654 + ClearIRam(p_Fm);
64655 + if (p_Fm->firmware.p_Code &&
64656 + (LoadFmanCtrlCode(p_Fm) != E_OK))
64657 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
64658 + XX_UDelay(100);
64659 +
64660 + /* reset FMAN again to start the microcode */
64661 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64662 + CORE_MemoryBarrier();
64663 + XX_UDelay(100);
64664 + Mem2IOCpy32((uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64665 + (uint8_t *)savedSpliodn,
64666 + 63*sizeof(uint32_t));
64667 +
64668 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
64669 + {
64670 + fman_resume(p_Fm->p_FmFpmRegs);
64671 + CORE_MemoryBarrier();
64672 + XX_UDelay(100);
64673 + }
64674 +
64675 + return E_OK;
64676 +}
64677 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
64678 +
64679 +static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
64680 +{
64681 +#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \
64682 +do { \
64683 + 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);\
64684 +} while (0)
64685 +#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \
64686 +do { \
64687 + 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);\
64688 +} while (0)
64689 +
64690 + /* error interrupts */
64691 + if (pending & ERR_INTR_EN_1G_MAC0)
64692 + FM_G_CALL_1G_MAC_ERR_ISR(0);
64693 + if (pending & ERR_INTR_EN_1G_MAC1)
64694 + FM_G_CALL_1G_MAC_ERR_ISR(1);
64695 + if (pending & ERR_INTR_EN_1G_MAC2)
64696 + FM_G_CALL_1G_MAC_ERR_ISR(2);
64697 + if (pending & ERR_INTR_EN_1G_MAC3)
64698 + FM_G_CALL_1G_MAC_ERR_ISR(3);
64699 + if (pending & ERR_INTR_EN_1G_MAC4)
64700 + FM_G_CALL_1G_MAC_ERR_ISR(4);
64701 + if (pending & ERR_INTR_EN_1G_MAC5)
64702 + FM_G_CALL_1G_MAC_ERR_ISR(5);
64703 + if (pending & ERR_INTR_EN_1G_MAC6)
64704 + FM_G_CALL_1G_MAC_ERR_ISR(6);
64705 + if (pending & ERR_INTR_EN_1G_MAC7)
64706 + FM_G_CALL_1G_MAC_ERR_ISR(7);
64707 + if (pending & ERR_INTR_EN_10G_MAC0)
64708 + FM_G_CALL_10G_MAC_ERR_ISR(0);
64709 + if (pending & ERR_INTR_EN_10G_MAC1)
64710 + FM_G_CALL_10G_MAC_ERR_ISR(1);
64711 +}
64712 +
64713 +static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
64714 +{
64715 +#define FM_G_CALL_1G_MAC_ISR(_id) \
64716 +do { \
64717 + 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);\
64718 +} while (0)
64719 +#define FM_G_CALL_10G_MAC_ISR(_id) \
64720 +do { \
64721 + 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);\
64722 +} while (0)
64723 +
64724 + if (pending & INTR_EN_1G_MAC0)
64725 + FM_G_CALL_1G_MAC_ISR(0);
64726 + if (pending & INTR_EN_1G_MAC1)
64727 + FM_G_CALL_1G_MAC_ISR(1);
64728 + if (pending & INTR_EN_1G_MAC2)
64729 + FM_G_CALL_1G_MAC_ISR(2);
64730 + if (pending & INTR_EN_1G_MAC3)
64731 + FM_G_CALL_1G_MAC_ISR(3);
64732 + if (pending & INTR_EN_1G_MAC4)
64733 + FM_G_CALL_1G_MAC_ISR(4);
64734 + if (pending & INTR_EN_1G_MAC5)
64735 + FM_G_CALL_1G_MAC_ISR(5);
64736 + if (pending & INTR_EN_1G_MAC6)
64737 + FM_G_CALL_1G_MAC_ISR(6);
64738 + if (pending & INTR_EN_1G_MAC7)
64739 + FM_G_CALL_1G_MAC_ISR(7);
64740 + if (pending & INTR_EN_10G_MAC0)
64741 + FM_G_CALL_10G_MAC_ISR(0);
64742 + if (pending & INTR_EN_10G_MAC1)
64743 + FM_G_CALL_10G_MAC_ISR(1);
64744 + if (pending & INTR_EN_TMR)
64745 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
64746 +}
64747 +
64748 +#if (DPAA_VERSION >= 11)
64749 +static t_Error SetVSPWindow(t_Handle h_Fm,
64750 + uint8_t hardwarePortId,
64751 + uint8_t baseStorageProfile,
64752 + uint8_t log2NumOfProfiles)
64753 +{
64754 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64755 +
64756 + ASSERT_COND(h_Fm);
64757 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
64758 +
64759 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
64760 + !p_Fm->p_FmBmiRegs &&
64761 + p_Fm->h_IpcSessions[0])
64762 + {
64763 + t_FmIpcVspSetPortWindow fmIpcVspSetPortWindow;
64764 + t_FmIpcMsg msg;
64765 + t_Error err = E_OK;
64766 +
64767 + memset(&msg, 0, sizeof(msg));
64768 + memset(&fmIpcVspSetPortWindow, 0, sizeof(t_FmIpcVspSetPortWindow));
64769 + fmIpcVspSetPortWindow.hardwarePortId = hardwarePortId;
64770 + fmIpcVspSetPortWindow.baseStorageProfile = baseStorageProfile;
64771 + fmIpcVspSetPortWindow.log2NumOfProfiles = log2NumOfProfiles;
64772 + msg.msgId = FM_VSP_SET_PORT_WINDOW;
64773 + memcpy(msg.msgBody, &fmIpcVspSetPortWindow, sizeof(t_FmIpcVspSetPortWindow));
64774 +
64775 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
64776 + (uint8_t*)&msg,
64777 + sizeof(msg.msgId),
64778 + NULL,
64779 + NULL,
64780 + NULL,
64781 + NULL);
64782 + if (err != E_OK)
64783 + RETURN_ERROR(MINOR, err, NO_MSG);
64784 + return E_OK;
64785 + }
64786 + else if (!p_Fm->p_FmBmiRegs)
64787 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
64788 + ("Either IPC or 'baseAddress' is required!"));
64789 +
64790 + fman_set_vsp_window(p_Fm->p_FmBmiRegs,
64791 + hardwarePortId,
64792 + baseStorageProfile,
64793 + log2NumOfProfiles);
64794 +
64795 + return E_OK;
64796 +}
64797 +
64798 +static uint8_t AllocVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
64799 +{
64800 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64801 + uint8_t profilesFound = 0;
64802 + int i = 0;
64803 + uint32_t intFlags;
64804 +
64805 + if (!numOfProfiles)
64806 + return E_OK;
64807 +
64808 + if ((numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES) ||
64809 + (base + numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES))
64810 + return (uint8_t)ILLEGAL_BASE;
64811 +
64812 + if (p_Fm->h_IpcSessions[0])
64813 + {
64814 + t_FmIpcResourceAllocParams ipcAllocParams;
64815 + t_FmIpcMsg msg;
64816 + t_FmIpcReply reply;
64817 + t_Error err;
64818 + uint32_t replyLength;
64819 +
64820 + memset(&msg, 0, sizeof(msg));
64821 + memset(&reply, 0, sizeof(reply));
64822 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
64823 + ipcAllocParams.guestId = p_Fm->guestId;
64824 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
64825 + ipcAllocParams.base = p_Fm->partVSPBase;
64826 + msg.msgId = FM_VSP_ALLOC;
64827 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
64828 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
64829 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
64830 + (uint8_t*)&msg,
64831 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
64832 + (uint8_t*)&reply,
64833 + &replyLength,
64834 + NULL,
64835 + NULL);
64836 + if ((err != E_OK) ||
64837 + (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))))
64838 + RETURN_ERROR(MAJOR, err, NO_MSG);
64839 + else
64840 + memcpy((uint8_t*)&p_Fm->partVSPBase, reply.replyBody, sizeof(uint8_t));
64841 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
64842 + RETURN_ERROR(MAJOR, err, NO_MSG);
64843 + }
64844 + if (p_Fm->guestId != NCSW_MASTER_ID)
64845 + {
64846 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
64847 + return (uint8_t)ILLEGAL_BASE;
64848 + }
64849 +
64850 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
64851 + for (i = base; i < base + numOfProfiles; i++)
64852 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
64853 + profilesFound++;
64854 + else
64855 + break;
64856 +
64857 + if (profilesFound == numOfProfiles)
64858 + for (i = base; i<base + numOfProfiles; i++)
64859 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = guestId;
64860 + else
64861 + {
64862 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
64863 + return (uint8_t)ILLEGAL_BASE;
64864 + }
64865 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
64866 +
64867 + return base;
64868 +}
64869 +
64870 +static void FreeVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
64871 +{
64872 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64873 + int i = 0;
64874 +
64875 + ASSERT_COND(p_Fm);
64876 +
64877 + if (p_Fm->h_IpcSessions[0])
64878 + {
64879 + t_FmIpcResourceAllocParams ipcAllocParams;
64880 + t_FmIpcMsg msg;
64881 + t_FmIpcReply reply;
64882 + uint32_t replyLength;
64883 + t_Error err;
64884 +
64885 + memset(&msg, 0, sizeof(msg));
64886 + memset(&reply, 0, sizeof(reply));
64887 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
64888 + ipcAllocParams.guestId = p_Fm->guestId;
64889 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
64890 + ipcAllocParams.base = p_Fm->partVSPBase;
64891 + msg.msgId = FM_VSP_FREE;
64892 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
64893 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
64894 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
64895 + (uint8_t*)&msg,
64896 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
64897 + (uint8_t*)&reply,
64898 + &replyLength,
64899 + NULL,
64900 + NULL);
64901 + if (err != E_OK)
64902 + REPORT_ERROR(MAJOR, err, NO_MSG);
64903 + return;
64904 + }
64905 + if (p_Fm->guestId != NCSW_MASTER_ID)
64906 + {
64907 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
64908 + return;
64909 + }
64910 +
64911 + ASSERT_COND(p_Fm->p_FmSp);
64912 +
64913 + for (i=base; i<numOfProfiles; i++)
64914 + {
64915 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == guestId)
64916 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
64917 + else
64918 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
64919 + }
64920 +}
64921 +#endif /* (DPAA_VERSION >= 11) */
64922 +
64923 +static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm,
64924 + uint8_t *p_Msg,
64925 + uint32_t msgLength,
64926 + uint8_t *p_Reply,
64927 + uint32_t *p_ReplyLength)
64928 +{
64929 + t_Fm *p_Fm = (t_Fm*)h_Fm;
64930 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
64931 +
64932 + UNUSED(p_Reply);
64933 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
64934 + SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
64935 +
64936 +#ifdef DISABLE_SANITY_CHECKS
64937 + UNUSED(msgLength);
64938 +#endif /* DISABLE_SANITY_CHECKS */
64939 +
64940 + ASSERT_COND(p_Msg);
64941 +
64942 + *p_ReplyLength = 0;
64943 +
64944 + switch (p_IpcMsg->msgId)
64945 + {
64946 + case (FM_GUEST_ISR):
64947 + {
64948 + t_FmIpcIsr ipcIsr;
64949 +
64950 + memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
64951 + if (ipcIsr.boolErr)
64952 + GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
64953 + else
64954 + GuestEventIsr(p_Fm, ipcIsr.pendingReg);
64955 + break;
64956 + }
64957 + default:
64958 + *p_ReplyLength = 0;
64959 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
64960 + }
64961 + return E_OK;
64962 +}
64963 +
64964 +static t_Error FmHandleIpcMsgCB(t_Handle h_Fm,
64965 + uint8_t *p_Msg,
64966 + uint32_t msgLength,
64967 + uint8_t *p_Reply,
64968 + uint32_t *p_ReplyLength)
64969 +{
64970 + t_Error err;
64971 + t_Fm *p_Fm = (t_Fm*)h_Fm;
64972 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
64973 + t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply;
64974 +
64975 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
64976 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
64977 +
64978 +#ifdef DISABLE_SANITY_CHECKS
64979 + UNUSED(msgLength);
64980 +#endif /* DISABLE_SANITY_CHECKS */
64981 +
64982 + ASSERT_COND(p_IpcMsg);
64983 +
64984 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
64985 + *p_ReplyLength = 0;
64986 +
64987 + switch (p_IpcMsg->msgId)
64988 + {
64989 + case (FM_GET_SET_PORT_PARAMS):
64990 + {
64991 + t_FmIpcPortInInitParams ipcInitParams;
64992 + t_FmInterModulePortInitParams initParams;
64993 + t_FmIpcPortOutInitParams ipcOutInitParams;
64994 +
64995 + memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
64996 + initParams.hardwarePortId = ipcInitParams.hardwarePortId;
64997 + initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
64998 + initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
64999 + initParams.liodnOffset = ipcInitParams.liodnOffset;
65000 + initParams.numOfTasks = ipcInitParams.numOfTasks;
65001 + initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
65002 + initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
65003 + initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
65004 + initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
65005 + initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
65006 + initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
65007 + initParams.maxFrameLength = ipcInitParams.maxFrameLength;
65008 + initParams.liodnBase = ipcInitParams.liodnBase;
65009 +
65010 + p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
65011 +
65012 + ipcOutInitParams.ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
65013 + ipcOutInitParams.ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
65014 + ipcOutInitParams.sizeOfFifo = initParams.sizeOfFifo;
65015 + ipcOutInitParams.extraSizeOfFifo = initParams.extraSizeOfFifo;
65016 + ipcOutInitParams.numOfTasks = initParams.numOfTasks;
65017 + ipcOutInitParams.numOfExtraTasks = initParams.numOfExtraTasks;
65018 + ipcOutInitParams.numOfOpenDmas = initParams.numOfOpenDmas;
65019 + ipcOutInitParams.numOfExtraOpenDmas = initParams.numOfExtraOpenDmas;
65020 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcOutInitParams, sizeof(ipcOutInitParams));
65021 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams);
65022 + break;
65023 + }
65024 + case (FM_SET_SIZE_OF_FIFO):
65025 + {
65026 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65027 +
65028 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65029 + p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm,
65030 + ipcPortRsrcParams.hardwarePortId,
65031 + &ipcPortRsrcParams.val,
65032 + &ipcPortRsrcParams.extra,
65033 + (bool)ipcPortRsrcParams.boolInitialConfig);
65034 + *p_ReplyLength = sizeof(uint32_t);
65035 + break;
65036 + }
65037 + case (FM_SET_NUM_OF_TASKS):
65038 + {
65039 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65040 +
65041 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65042 + p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
65043 + (uint8_t*)&ipcPortRsrcParams.val,
65044 + (uint8_t*)&ipcPortRsrcParams.extra,
65045 + (bool)ipcPortRsrcParams.boolInitialConfig);
65046 + *p_ReplyLength = sizeof(uint32_t);
65047 + break;
65048 + }
65049 + case (FM_SET_NUM_OF_OPEN_DMAS):
65050 + {
65051 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65052 +
65053 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65054 + p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
65055 + (uint8_t*)&ipcPortRsrcParams.val,
65056 + (uint8_t*)&ipcPortRsrcParams.extra,
65057 + (bool)ipcPortRsrcParams.boolInitialConfig);
65058 + *p_ReplyLength = sizeof(uint32_t);
65059 + break;
65060 + }
65061 + case (FM_RESUME_STALLED_PORT):
65062 + *p_ReplyLength = sizeof(uint32_t);
65063 + p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
65064 + break;
65065 + case (FM_MASTER_IS_ALIVE):
65066 + {
65067 + uint8_t guestId = p_IpcMsg->msgBody[0];
65068 + /* build the FM master partition IPC address */
65069 + memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
65070 + if (Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
65071 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
65072 + p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
65073 + if (p_Fm->h_IpcSessions[guestId] == NULL)
65074 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
65075 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
65076 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65077 + break;
65078 + }
65079 + case (FM_IS_PORT_STALLED):
65080 + {
65081 + bool tmp;
65082 +
65083 + p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
65084 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
65085 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65086 + break;
65087 + }
65088 + case (FM_RESET_MAC):
65089 + {
65090 + t_FmIpcMacParams ipcMacParams;
65091 +
65092 + memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
65093 + p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
65094 + (e_FmMacType)(ipcMacParams.enumType),
65095 + ipcMacParams.id);
65096 + *p_ReplyLength = sizeof(uint32_t);
65097 + break;
65098 + }
65099 + case (FM_SET_MAC_MAX_FRAME):
65100 + {
65101 + t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams;
65102 +
65103 + memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
65104 + err = FmSetMacMaxFrame(p_Fm,
65105 + (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
65106 + ipcMacMaxFrameParams.macParams.id,
65107 + ipcMacMaxFrameParams.maxFrameLength);
65108 + if (err != E_OK)
65109 + REPORT_ERROR(MINOR, err, NO_MSG);
65110 + break;
65111 + }
65112 +#if (DPAA_VERSION >= 11)
65113 + case (FM_VSP_ALLOC) :
65114 + {
65115 + t_FmIpcResourceAllocParams ipcAllocParams;
65116 + uint8_t vspBase;
65117 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
65118 + vspBase = AllocVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
65119 + memcpy(p_IpcReply->replyBody, (uint8_t*)&vspBase, sizeof(uint8_t));
65120 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65121 + break;
65122 + }
65123 + case (FM_VSP_FREE) :
65124 + {
65125 + t_FmIpcResourceAllocParams ipcAllocParams;
65126 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
65127 + FreeVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
65128 + break;
65129 + }
65130 + case (FM_VSP_SET_PORT_WINDOW) :
65131 + {
65132 + t_FmIpcVspSetPortWindow ipcVspSetPortWindow;
65133 + memcpy(&ipcVspSetPortWindow, p_IpcMsg->msgBody, sizeof(t_FmIpcVspSetPortWindow));
65134 + err = SetVSPWindow(h_Fm,
65135 + ipcVspSetPortWindow.hardwarePortId,
65136 + ipcVspSetPortWindow.baseStorageProfile,
65137 + ipcVspSetPortWindow.log2NumOfProfiles);
65138 + return err;
65139 + }
65140 + case (FM_SET_CONG_GRP_PFC_PRIO) :
65141 + {
65142 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65143 + memcpy(&fmIpcSetCongestionGroupPfcPriority, p_IpcMsg->msgBody, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65144 + err = FmSetCongestionGroupPFCpriority(h_Fm,
65145 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId,
65146 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap);
65147 + return err;
65148 + }
65149 +#endif /* (DPAA_VERSION >= 11) */
65150 +
65151 + case (FM_FREE_PORT):
65152 + {
65153 + t_FmInterModulePortFreeParams portParams;
65154 + t_FmIpcPortFreeParams ipcPortParams;
65155 +
65156 + memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
65157 + portParams.hardwarePortId = ipcPortParams.hardwarePortId;
65158 + portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
65159 + portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
65160 + FmFreePortParams(h_Fm, &portParams);
65161 + break;
65162 + }
65163 + case (FM_REGISTER_INTR):
65164 + {
65165 + t_FmIpcRegisterIntr ipcRegIntr;
65166 +
65167 + memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
65168 + p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
65169 + break;
65170 + }
65171 + case (FM_GET_PARAMS):
65172 + {
65173 + t_FmIpcParams ipcParams;
65174 +
65175 + /* Get clock frequency */
65176 + ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq;
65177 + ipcParams.fmMacClkFreq = p_Fm->p_FmStateStruct->fmMacClkFreq;
65178 +
65179 + fman_get_revision(p_Fm->p_FmFpmRegs,&ipcParams.majorRev,&ipcParams.minorRev);
65180 +
65181 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcParams, sizeof(t_FmIpcParams));
65182 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
65183 + break;
65184 + }
65185 + case (FM_GET_FMAN_CTRL_CODE_REV):
65186 + {
65187 + t_FmCtrlCodeRevisionInfo fmanCtrlRevInfo;
65188 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
65189 +
65190 + p_IpcReply->error = (uint32_t)FM_GetFmanCtrlCodeRevision(h_Fm, &fmanCtrlRevInfo);
65191 + ipcRevInfo.packageRev = fmanCtrlRevInfo.packageRev;
65192 + ipcRevInfo.majorRev = fmanCtrlRevInfo.majorRev;
65193 + ipcRevInfo.minorRev = fmanCtrlRevInfo.minorRev;
65194 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcFmanCtrlCodeRevisionInfo));
65195 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcFmanCtrlCodeRevisionInfo);
65196 + break;
65197 + }
65198 +
65199 + case (FM_DMA_STAT):
65200 + {
65201 + t_FmDmaStatus dmaStatus;
65202 + t_FmIpcDmaStatus ipcDmaStatus;
65203 +
65204 + FM_GetDmaStatus(h_Fm, &dmaStatus);
65205 + ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
65206 + ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
65207 + ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
65208 + ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
65209 + ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
65210 + ipcDmaStatus.boolSinglePortEccError = (uint8_t)dmaStatus.singlePortEccError;
65211 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
65212 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
65213 + break;
65214 + }
65215 + case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
65216 + p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
65217 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65218 + break;
65219 + case (FM_FREE_FMAN_CTRL_EVENT_REG):
65220 + FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
65221 + break;
65222 + case (FM_GET_TIMESTAMP_SCALE):
65223 + {
65224 + uint32_t timeStamp = FmGetTimeStampScale(h_Fm);
65225 +
65226 + memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
65227 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65228 + break;
65229 + }
65230 + case (FM_GET_COUNTER):
65231 + {
65232 + e_FmCounters inCounter;
65233 + uint32_t outCounter;
65234 +
65235 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
65236 + outCounter = FM_GetCounter(h_Fm, inCounter);
65237 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
65238 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65239 + break;
65240 + }
65241 + case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
65242 + {
65243 + t_FmIpcFmanEvents ipcFmanEvents;
65244 +
65245 + memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
65246 + FmSetFmanCtrlIntr(h_Fm,
65247 + ipcFmanEvents.eventRegId,
65248 + ipcFmanEvents.enableEvents);
65249 + break;
65250 + }
65251 + case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
65252 + {
65253 + uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
65254 +
65255 + memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
65256 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65257 + break;
65258 + }
65259 + case (FM_GET_PHYS_MURAM_BASE):
65260 + {
65261 + t_FmPhysAddr physAddr;
65262 + t_FmIpcPhysAddr ipcPhysAddr;
65263 +
65264 + FmGetPhysicalMuramBase(h_Fm, &physAddr);
65265 + ipcPhysAddr.high = physAddr.high;
65266 + ipcPhysAddr.low = physAddr.low;
65267 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
65268 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
65269 + break;
65270 + }
65271 + case (FM_ENABLE_RAM_ECC):
65272 + {
65273 + if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
65274 + ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
65275 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
65276 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65277 + UNUSED(err);
65278 +#else
65279 + REPORT_ERROR(MINOR, err, NO_MSG);
65280 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65281 + break;
65282 + }
65283 + case (FM_DISABLE_RAM_ECC):
65284 + {
65285 +
65286 + if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
65287 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
65288 + ((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
65289 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65290 + UNUSED(err);
65291 +#else
65292 + REPORT_ERROR(MINOR, err, NO_MSG);
65293 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65294 + break;
65295 + }
65296 + case (FM_SET_NUM_OF_FMAN_CTRL):
65297 + {
65298 + t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls;
65299 +
65300 + memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
65301 + err = FmSetNumOfRiscsPerPort(h_Fm,
65302 + ipcPortNumOfFmanCtrls.hardwarePortId,
65303 + ipcPortNumOfFmanCtrls.numOfFmanCtrls,
65304 + ipcPortNumOfFmanCtrls.orFmanCtrl);
65305 + if (err != E_OK)
65306 + REPORT_ERROR(MINOR, err, NO_MSG);
65307 + break;
65308 + }
65309 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65310 + case (FM_10G_TX_ECC_WA):
65311 + p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
65312 + *p_ReplyLength = sizeof(uint32_t);
65313 + break;
65314 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65315 + default:
65316 + *p_ReplyLength = 0;
65317 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
65318 + }
65319 + return E_OK;
65320 +}
65321 +
65322 +
65323 +/****************************************/
65324 +/* Inter-Module functions */
65325 +/****************************************/
65326 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65327 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
65328 +{
65329 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65330 + t_Error err = E_OK;
65331 + t_FmIpcMsg msg;
65332 + t_FmIpcReply reply;
65333 + uint32_t replyLength;
65334 + uint8_t rxHardwarePortId, txHardwarePortId;
65335 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65336 +
65337 + if (p_Fm->guestId != NCSW_MASTER_ID)
65338 + {
65339 + memset(&msg, 0, sizeof(msg));
65340 + memset(&reply, 0, sizeof(reply));
65341 + msg.msgId = FM_10G_TX_ECC_WA;
65342 + msg.msgBody[0] = macId;
65343 + replyLength = sizeof(uint32_t);
65344 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65345 + (uint8_t*)&msg,
65346 + sizeof(msg.msgId)+sizeof(macId),
65347 + (uint8_t*)&reply,
65348 + &replyLength,
65349 + NULL,
65350 + NULL)) != E_OK)
65351 + RETURN_ERROR(MINOR, err, NO_MSG);
65352 + if (replyLength != sizeof(uint32_t))
65353 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65354 + return (t_Error)(reply.error);
65355 + }
65356 +
65357 + SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
65358 + SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
65359 +
65360 + rxHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_RX_10G,
65361 + macId,
65362 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65363 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65364 + txHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_TX_10G,
65365 + macId,
65366 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65367 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65368 + if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
65369 + (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
65370 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
65371 + ("MAC should be initialized prior to Rx and Tx ports!"));
65372 +
65373 + return fman_set_erratum_10gmac_a004_wa(fpm_rg);
65374 +}
65375 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65376 +
65377 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm)
65378 +{
65379 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65380 +
65381 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65382 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
65383 +
65384 + return p_Fm->tnumAgingPeriod;
65385 +}
65386 +
65387 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm,
65388 + uint8_t portNum,
65389 + bool preFetchConfigured)
65390 +{
65391 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65392 +
65393 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65394 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65395 +
65396 + p_Fm->portsPreFetchConfigured[portNum] = TRUE;
65397 + p_Fm->portsPreFetchValue[portNum] = preFetchConfigured;
65398 +
65399 + return E_OK;
65400 +}
65401 +
65402 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm,
65403 + uint8_t portNum,
65404 + bool *p_PortConfigured,
65405 + bool *p_PreFetchConfigured)
65406 +{
65407 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65408 +
65409 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65410 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65411 +
65412 + /* If the prefetch wasn't configured yet (not enable or disabled)
65413 + we return the value TRUE as it was already configured */
65414 + if (!p_Fm->portsPreFetchConfigured[portNum])
65415 + {
65416 + *p_PortConfigured = FALSE;
65417 + *p_PreFetchConfigured = FALSE;
65418 + }
65419 + else
65420 + {
65421 + *p_PortConfigured = TRUE;
65422 + *p_PreFetchConfigured = (p_Fm->portsPreFetchConfigured[portNum]);
65423 + }
65424 +
65425 + return E_OK;
65426 +}
65427 +
65428 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
65429 + uint32_t congestionGroupId,
65430 + uint8_t priorityBitMap)
65431 +{
65432 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65433 + uint32_t regNum;
65434 +
65435 + ASSERT_COND(h_Fm);
65436 +
65437 + if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS)
65438 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
65439 + ("Congestion group ID bigger than %d",
65440 + FM_PORT_NUM_OF_CONGESTION_GRPS));
65441 +
65442 + if (p_Fm->guestId == NCSW_MASTER_ID)
65443 + {
65444 + ASSERT_COND(p_Fm->baseAddr);
65445 + regNum = (FM_PORT_NUM_OF_CONGESTION_GRPS - 1 - congestionGroupId) / 4;
65446 + fman_set_congestion_group_pfc_priority((uint32_t *)((p_Fm->baseAddr+FM_MM_CGP)),
65447 + congestionGroupId,
65448 + priorityBitMap,
65449 + regNum);
65450 + }
65451 + else if (p_Fm->h_IpcSessions[0])
65452 + {
65453 + t_Error err;
65454 + t_FmIpcMsg msg;
65455 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65456 +
65457 + memset(&msg, 0, sizeof(msg));
65458 + memset(&fmIpcSetCongestionGroupPfcPriority, 0, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65459 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId = congestionGroupId;
65460 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap = priorityBitMap;
65461 +
65462 + msg.msgId = FM_SET_CONG_GRP_PFC_PRIO;
65463 + memcpy(msg.msgBody, &fmIpcSetCongestionGroupPfcPriority, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65464 +
65465 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65466 + (uint8_t*)&msg,
65467 + sizeof(msg.msgId),
65468 + NULL,
65469 + NULL,
65470 + NULL,
65471 + NULL);
65472 + if (err != E_OK)
65473 + RETURN_ERROR(MINOR, err, NO_MSG);
65474 + }
65475 + else
65476 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("guest without IPC!"));
65477 +
65478 + return E_OK;
65479 +}
65480 +
65481 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
65482 +{
65483 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65484 +
65485 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65486 +
65487 + if (!p_Fm->baseAddr)
65488 + {
65489 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65490 + ("No base-addr; probably Guest with IPC!"));
65491 + return 0;
65492 + }
65493 +
65494 + return (p_Fm->baseAddr + FM_MM_PRS);
65495 +}
65496 +
65497 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
65498 +{
65499 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65500 +
65501 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65502 +
65503 + if (!p_Fm->baseAddr)
65504 + {
65505 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65506 + ("No base-addr; probably Guest with IPC!"));
65507 + return 0;
65508 + }
65509 +
65510 + return (p_Fm->baseAddr + FM_MM_KG);
65511 +}
65512 +
65513 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
65514 +{
65515 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65516 +
65517 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65518 +
65519 + if (!p_Fm->baseAddr)
65520 + {
65521 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65522 + ("No base-addr; probably Guest with IPC!"));
65523 + return 0;
65524 + }
65525 +
65526 + return (p_Fm->baseAddr + FM_MM_PLCR);
65527 +}
65528 +
65529 +#if (DPAA_VERSION >= 11)
65530 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm)
65531 +{
65532 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65533 +
65534 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65535 +
65536 + return p_Fm->vspBaseAddr;
65537 +}
65538 +#endif /* (DPAA_VERSION >= 11) */
65539 +
65540 +t_Handle FmGetMuramHandle(t_Handle h_Fm)
65541 +{
65542 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65543 +
65544 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
65545 +
65546 + return (p_Fm->h_FmMuram);
65547 +}
65548 +
65549 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
65550 +{
65551 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65552 +
65553 + if (p_Fm->fmMuramPhysBaseAddr)
65554 + {
65555 + /* General FM driver initialization */
65556 + p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
65557 + p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
65558 + return;
65559 + }
65560 +
65561 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
65562 +
65563 + if (p_Fm->h_IpcSessions[0])
65564 + {
65565 + t_Error err;
65566 + t_FmIpcMsg msg;
65567 + t_FmIpcReply reply;
65568 + uint32_t replyLength;
65569 + t_FmIpcPhysAddr ipcPhysAddr;
65570 +
65571 + memset(&msg, 0, sizeof(msg));
65572 + memset(&reply, 0, sizeof(reply));
65573 + msg.msgId = FM_GET_PHYS_MURAM_BASE;
65574 + replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
65575 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65576 + (uint8_t*)&msg,
65577 + sizeof(msg.msgId),
65578 + (uint8_t*)&reply,
65579 + &replyLength,
65580 + NULL,
65581 + NULL);
65582 + if (err != E_OK)
65583 + {
65584 + REPORT_ERROR(MINOR, err, NO_MSG);
65585 + return;
65586 + }
65587 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
65588 + {
65589 + REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
65590 + return;
65591 + }
65592 + memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
65593 + p_FmPhysAddr->high = ipcPhysAddr.high;
65594 + p_FmPhysAddr->low = ipcPhysAddr.low;
65595 + }
65596 + else
65597 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65598 + ("running in guest-mode without neither IPC nor mapped register!"));
65599 +}
65600 +
65601 +#if (DPAA_VERSION >= 11)
65602 +t_Error FmVSPAllocForPort (t_Handle h_Fm,
65603 + e_FmPortType portType,
65604 + uint8_t portId,
65605 + uint8_t numOfVSPs)
65606 +{
65607 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65608 + t_Error err = E_OK;
65609 + uint32_t profilesFound, intFlags;
65610 + uint8_t first, i;
65611 + uint8_t log2Num;
65612 + uint8_t swPortIndex=0, hardwarePortId;
65613 +
65614 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65615 +
65616 + if (!numOfVSPs)
65617 + return E_OK;
65618 +
65619 + if (numOfVSPs > FM_VSP_MAX_NUM_OF_ENTRIES)
65620 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles can not be bigger than %d.",FM_VSP_MAX_NUM_OF_ENTRIES));
65621 +
65622 + if (!POWER_OF_2(numOfVSPs))
65623 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
65624 +
65625 + LOG2((uint64_t)numOfVSPs, log2Num);
65626 +
65627 + if ((log2Num == 0) || (p_Fm->partVSPBase == 0))
65628 + first = 0;
65629 + else
65630 + first = 1<<log2Num;
65631 +
65632 + if (first > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65633 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65634 +
65635 + if (first < p_Fm->partVSPBase)
65636 + while (first < p_Fm->partVSPBase)
65637 + first = first + numOfVSPs;
65638 +
65639 + if ((first + numOfVSPs) > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65640 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65641 +
65642 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65643 + profilesFound = 0;
65644 + for (i=first; i < p_Fm->partVSPBase + p_Fm->partNumOfVSPs; )
65645 + {
65646 + if (!p_Fm->p_FmSp->profiles[i].profilesMng.allocated)
65647 + {
65648 + profilesFound++;
65649 + i++;
65650 + if (profilesFound == numOfVSPs)
65651 + break;
65652 + }
65653 + else
65654 + {
65655 + profilesFound = 0;
65656 + /* advance i to the next aligned address */
65657 + first = i = (uint8_t)(first + numOfVSPs);
65658 + }
65659 + }
65660 + if (profilesFound == numOfVSPs)
65661 + for (i = first; i<first + numOfVSPs; i++)
65662 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = TRUE;
65663 + else
65664 + {
65665 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65666 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
65667 + }
65668 +
65669 + hardwarePortId = SwPortIdToHwPortId(portType,
65670 + portId,
65671 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65672 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65673 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65674 +
65675 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = numOfVSPs;
65676 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = first;
65677 +
65678 + if ((err = SetVSPWindow(h_Fm,hardwarePortId, first,log2Num)) != E_OK)
65679 + for (i = first; i < first + numOfVSPs; i++)
65680 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65681 +
65682 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65683 +
65684 + return err;
65685 +}
65686 +
65687 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
65688 + e_FmPortType portType,
65689 + uint8_t portId)
65690 +{
65691 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65692 + uint8_t swPortIndex=0, hardwarePortId, first, numOfVSPs, i;
65693 + uint32_t intFlags;
65694 +
65695 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65696 +
65697 + hardwarePortId = SwPortIdToHwPortId(portType,
65698 + portId,
65699 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65700 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65701 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65702 +
65703 + numOfVSPs = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles;
65704 + first = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase;
65705 +
65706 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65707 + for (i = first; i < first + numOfVSPs; i++)
65708 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65709 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65710 +
65711 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = 0;
65712 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = 0;
65713 +
65714 + return E_OK;
65715 +}
65716 +#endif /* (DPAA_VERSION >= 11) */
65717 +
65718 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
65719 +{
65720 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65721 + uint8_t i;
65722 +
65723 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65724 +
65725 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65726 + p_Fm->h_IpcSessions[0])
65727 + {
65728 + t_Error err;
65729 + t_FmIpcMsg msg;
65730 + t_FmIpcReply reply;
65731 + uint32_t replyLength;
65732 +
65733 + memset(&msg, 0, sizeof(msg));
65734 + memset(&reply, 0, sizeof(reply));
65735 + msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
65736 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
65737 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65738 + (uint8_t*)&msg,
65739 + sizeof(msg.msgId),
65740 + (uint8_t*)&reply,
65741 + &replyLength,
65742 + NULL,
65743 + NULL)) != E_OK)
65744 + RETURN_ERROR(MAJOR, err, NO_MSG);
65745 +
65746 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
65747 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65748 +
65749 + *p_EventId = *(uint8_t*)(reply.replyBody);
65750 +
65751 + return (t_Error)(reply.error);
65752 + }
65753 + else if (p_Fm->guestId != NCSW_MASTER_ID)
65754 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
65755 + ("running in guest-mode without IPC!"));
65756 +
65757 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
65758 + if (!p_Fm->usedEventRegs[i])
65759 + {
65760 + p_Fm->usedEventRegs[i] = TRUE;
65761 + *p_EventId = i;
65762 + break;
65763 + }
65764 +
65765 + if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
65766 + RETURN_ERROR(MAJOR, E_BUSY, ("No resource - FMan controller event register."));
65767 +
65768 + return E_OK;
65769 +}
65770 +
65771 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
65772 +{
65773 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65774 +
65775 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
65776 +
65777 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65778 + p_Fm->h_IpcSessions[0])
65779 + {
65780 + t_Error err;
65781 + t_FmIpcMsg msg;
65782 +
65783 + memset(&msg, 0, sizeof(msg));
65784 + msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
65785 + msg.msgBody[0] = eventId;
65786 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65787 + (uint8_t*)&msg,
65788 + sizeof(msg.msgId)+sizeof(eventId),
65789 + NULL,
65790 + NULL,
65791 + NULL,
65792 + NULL);
65793 + if (err != E_OK)
65794 + REPORT_ERROR(MINOR, err, NO_MSG);
65795 + return;
65796 + }
65797 + else if (p_Fm->guestId != NCSW_MASTER_ID)
65798 + {
65799 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65800 + ("running in guest-mode without IPC!"));
65801 + return;
65802 + }
65803 +
65804 + ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
65805 +}
65806 +
65807 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents)
65808 +{
65809 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65810 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65811 +
65812 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65813 + !p_Fm->p_FmFpmRegs &&
65814 + p_Fm->h_IpcSessions[0])
65815 + {
65816 + t_FmIpcFmanEvents fmanCtrl;
65817 + t_Error err;
65818 + t_FmIpcMsg msg;
65819 +
65820 + fmanCtrl.eventRegId = eventRegId;
65821 + fmanCtrl.enableEvents = enableEvents;
65822 + memset(&msg, 0, sizeof(msg));
65823 + msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
65824 + memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
65825 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65826 + (uint8_t*)&msg,
65827 + sizeof(msg.msgId)+sizeof(fmanCtrl),
65828 + NULL,
65829 + NULL,
65830 + NULL,
65831 + NULL);
65832 + if (err != E_OK)
65833 + REPORT_ERROR(MINOR, err, NO_MSG);
65834 + return;
65835 + }
65836 + else if (!p_Fm->p_FmFpmRegs)
65837 + {
65838 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65839 + ("Either IPC or 'baseAddress' is required!"));
65840 + return;
65841 + }
65842 +
65843 + ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
65844 + fman_set_ctrl_intr(fpm_rg, eventRegId, enableEvents);
65845 +}
65846 +
65847 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
65848 +{
65849 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65850 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65851 +
65852 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65853 + !p_Fm->p_FmFpmRegs &&
65854 + p_Fm->h_IpcSessions[0])
65855 + {
65856 + t_Error err;
65857 + t_FmIpcMsg msg;
65858 + t_FmIpcReply reply;
65859 + uint32_t replyLength, ctrlIntr;
65860 +
65861 + memset(&msg, 0, sizeof(msg));
65862 + memset(&reply, 0, sizeof(reply));
65863 + msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
65864 + msg.msgBody[0] = eventRegId;
65865 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
65866 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65867 + (uint8_t*)&msg,
65868 + sizeof(msg.msgId)+sizeof(eventRegId),
65869 + (uint8_t*)&reply,
65870 + &replyLength,
65871 + NULL,
65872 + NULL);
65873 + if (err != E_OK)
65874 + {
65875 + REPORT_ERROR(MINOR, err, NO_MSG);
65876 + return 0;
65877 + }
65878 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
65879 + {
65880 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65881 + return 0;
65882 + }
65883 + memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
65884 + return ctrlIntr;
65885 + }
65886 + else if (!p_Fm->p_FmFpmRegs)
65887 + {
65888 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65889 + ("Either IPC or 'baseAddress' is required!"));
65890 + return 0;
65891 + }
65892 +
65893 + return fman_get_ctrl_intr(fpm_rg, eventRegId);
65894 +}
65895 +
65896 +void FmRegisterIntr(t_Handle h_Fm,
65897 + e_FmEventModules module,
65898 + uint8_t modId,
65899 + e_FmIntrType intrType,
65900 + void (*f_Isr) (t_Handle h_Arg),
65901 + t_Handle h_Arg)
65902 +{
65903 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65904 + int event = 0;
65905 +
65906 + ASSERT_COND(h_Fm);
65907 +
65908 + GET_FM_MODULE_EVENT(module, modId, intrType, event);
65909 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
65910 +
65911 + /* register in local FM structure */
65912 + p_Fm->intrMng[event].f_Isr = f_Isr;
65913 + p_Fm->intrMng[event].h_SrcHandle = h_Arg;
65914 +
65915 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65916 + p_Fm->h_IpcSessions[0])
65917 + {
65918 + t_FmIpcRegisterIntr fmIpcRegisterIntr;
65919 + t_Error err;
65920 + t_FmIpcMsg msg;
65921 +
65922 + /* register in Master FM structure */
65923 + fmIpcRegisterIntr.event = (uint32_t)event;
65924 + fmIpcRegisterIntr.guestId = p_Fm->guestId;
65925 + memset(&msg, 0, sizeof(msg));
65926 + msg.msgId = FM_REGISTER_INTR;
65927 + memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
65928 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65929 + (uint8_t*)&msg,
65930 + sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
65931 + NULL,
65932 + NULL,
65933 + NULL,
65934 + NULL);
65935 + if (err != E_OK)
65936 + REPORT_ERROR(MINOR, err, NO_MSG);
65937 + }
65938 + else if (p_Fm->guestId != NCSW_MASTER_ID)
65939 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65940 + ("running in guest-mode without IPC!"));
65941 +}
65942 +
65943 +void FmUnregisterIntr(t_Handle h_Fm,
65944 + e_FmEventModules module,
65945 + uint8_t modId,
65946 + e_FmIntrType intrType)
65947 +{
65948 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65949 + int event = 0;
65950 +
65951 + ASSERT_COND(h_Fm);
65952 +
65953 + GET_FM_MODULE_EVENT(module, modId,intrType, event);
65954 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
65955 +
65956 + p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
65957 + p_Fm->intrMng[event].h_SrcHandle = NULL;
65958 +}
65959 +
65960 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg)
65961 +{
65962 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65963 +
65964 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
65965 +
65966 + if (p_Fm->guestId != NCSW_MASTER_ID)
65967 + {
65968 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
65969 + return;
65970 + }
65971 +
65972 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
65973 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
65974 +}
65975 +
65976 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
65977 +{
65978 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65979 +
65980 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
65981 +
65982 + if (p_Fm->guestId != NCSW_MASTER_ID)
65983 + {
65984 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
65985 + return;
65986 + }
65987 +
65988 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
65989 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
65990 +}
65991 +
65992 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
65993 +{
65994 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65995 +
65996 + if (p_Fm->h_Pcd)
65997 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
65998 +
65999 + p_Fm->h_Pcd = h_FmPcd;
66000 +}
66001 +
66002 +void FmUnregisterPcd(t_Handle h_Fm)
66003 +{
66004 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66005 +
66006 + if (!p_Fm->h_Pcd)
66007 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("PCD handle!"));
66008 +
66009 + p_Fm->h_Pcd = NULL;
66010 +}
66011 +
66012 +t_Handle FmGetPcdHandle(t_Handle h_Fm)
66013 +{
66014 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66015 +
66016 + return p_Fm->h_Pcd;
66017 +}
66018 +
66019 +uint8_t FmGetId(t_Handle h_Fm)
66020 +{
66021 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66022 +
66023 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
66024 +
66025 + return p_Fm->p_FmStateStruct->fmId;
66026 +}
66027 +
66028 +t_Error FmReset(t_Handle h_Fm)
66029 +{
66030 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66031 +
66032 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66033 +
66034 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
66035 + CORE_MemoryBarrier();
66036 + XX_UDelay(100);
66037 +
66038 + return E_OK;
66039 +}
66040 +
66041 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm,
66042 + uint8_t hardwarePortId,
66043 + uint8_t numOfFmanCtrls,
66044 + t_FmFmanCtrl orFmanCtrl)
66045 +{
66046 +
66047 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66048 + struct fman_fpm_regs *fpm_rg;
66049 +
66050 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66051 + SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
66052 +
66053 + fpm_rg = p_Fm->p_FmFpmRegs;
66054 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66055 + !p_Fm->p_FmFpmRegs &&
66056 + p_Fm->h_IpcSessions[0])
66057 + {
66058 + t_Error err;
66059 + t_FmIpcPortNumOfFmanCtrls params;
66060 + t_FmIpcMsg msg;
66061 +
66062 + memset(&msg, 0, sizeof(msg));
66063 + params.hardwarePortId = hardwarePortId;
66064 + params.numOfFmanCtrls = numOfFmanCtrls;
66065 + params.orFmanCtrl = orFmanCtrl;
66066 + msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
66067 + memcpy(msg.msgBody, &params, sizeof(params));
66068 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66069 + (uint8_t*)&msg,
66070 + sizeof(msg.msgId) +sizeof(params),
66071 + NULL,
66072 + NULL,
66073 + NULL,
66074 + NULL);
66075 + if (err != E_OK)
66076 + RETURN_ERROR(MINOR, err, NO_MSG);
66077 + return E_OK;
66078 + }
66079 + else if (!p_Fm->p_FmFpmRegs)
66080 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66081 + ("Either IPC or 'baseAddress' is required!"));
66082 +
66083 + fman_set_num_of_riscs_per_port(fpm_rg, hardwarePortId, numOfFmanCtrls, orFmanCtrl);
66084 +
66085 + return E_OK;
66086 +}
66087 +
66088 +t_Error FmGetSetPortParams(t_Handle h_Fm, t_FmInterModulePortInitParams *p_PortParams)
66089 +{
66090 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66091 + t_Error err;
66092 + uint32_t intFlags;
66093 + uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId;
66094 + struct fman_rg fman_rg;
66095 +
66096 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
66097 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
66098 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
66099 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
66100 +
66101 + if (p_Fm->guestId != NCSW_MASTER_ID)
66102 + {
66103 + t_FmIpcPortInInitParams portInParams;
66104 + t_FmIpcPortOutInitParams portOutParams;
66105 + t_FmIpcMsg msg;
66106 + t_FmIpcReply reply;
66107 + uint32_t replyLength;
66108 +
66109 + portInParams.hardwarePortId = p_PortParams->hardwarePortId;
66110 + portInParams.enumPortType = (uint32_t)p_PortParams->portType;
66111 + portInParams.boolIndependentMode= (uint8_t)p_PortParams->independentMode;
66112 + portInParams.liodnOffset = p_PortParams->liodnOffset;
66113 + portInParams.numOfTasks = p_PortParams->numOfTasks;
66114 + portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
66115 + portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
66116 + portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
66117 + portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
66118 + portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
66119 + portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
66120 + portInParams.maxFrameLength = p_PortParams->maxFrameLength;
66121 + portInParams.liodnBase = p_PortParams->liodnBase;
66122 +
66123 + memset(&msg, 0, sizeof(msg));
66124 + memset(&reply, 0, sizeof(reply));
66125 + msg.msgId = FM_GET_SET_PORT_PARAMS;
66126 + memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
66127 + replyLength = (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams));
66128 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66129 + (uint8_t*)&msg,
66130 + sizeof(msg.msgId) +sizeof(portInParams),
66131 + (uint8_t*)&reply,
66132 + &replyLength,
66133 + NULL,
66134 + NULL)) != E_OK)
66135 + RETURN_ERROR(MINOR, err, NO_MSG);
66136 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams)))
66137 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66138 + memcpy((uint8_t*)&portOutParams, reply.replyBody, sizeof(t_FmIpcPortOutInitParams));
66139 +
66140 + p_PortParams->fmMuramPhysBaseAddr.high = portOutParams.ipcPhysAddr.high;
66141 + p_PortParams->fmMuramPhysBaseAddr.low = portOutParams.ipcPhysAddr.low;
66142 + p_PortParams->numOfTasks = portOutParams.numOfTasks;
66143 + p_PortParams->numOfExtraTasks = portOutParams.numOfExtraTasks;
66144 + p_PortParams->numOfOpenDmas = portOutParams.numOfOpenDmas;
66145 + p_PortParams->numOfExtraOpenDmas = portOutParams.numOfExtraOpenDmas;
66146 + p_PortParams->sizeOfFifo = portOutParams.sizeOfFifo;
66147 + p_PortParams->extraSizeOfFifo = portOutParams.extraSizeOfFifo;
66148 +
66149 + return (t_Error)(reply.error);
66150 + }
66151 +
66152 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66153 +
66154 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66155 + if (p_PortParams->independentMode)
66156 + {
66157 + /* set port parameters */
66158 + p_Fm->independentMode = p_PortParams->independentMode;
66159 + /* disable dispatch limit */
66160 + fman_qmi_disable_dispatch_limit(fman_rg.fpm_rg);
66161 + }
66162 +
66163 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66164 + {
66165 + if (p_Fm->hcPortInitialized)
66166 + {
66167 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66168 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
66169 + }
66170 + else
66171 + p_Fm->hcPortInitialized = TRUE;
66172 + }
66173 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
66174 +
66175 + err = FmSetNumOfTasks(p_Fm, hardwarePortId, &p_PortParams->numOfTasks, &p_PortParams->numOfExtraTasks, TRUE);
66176 + if (err)
66177 + {
66178 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66179 + RETURN_ERROR(MAJOR, err, NO_MSG);
66180 + }
66181 +
66182 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66183 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66184 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66185 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66186 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66187 + /* for transmit & O/H ports */
66188 + {
66189 + uint8_t enqTh;
66190 + uint8_t deqTh;
66191 +
66192 + /* update qmi ENQ/DEQ threshold */
66193 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
66194 + enqTh = fman_get_qmi_enq_th(fman_rg.qmi_rg);
66195 + /* if enqTh is too big, we reduce it to the max value that is still OK */
66196 + if (enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
66197 + {
66198 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66199 + fman_set_qmi_enq_th(fman_rg.qmi_rg, enqTh);
66200 + }
66201 +
66202 + deqTh = fman_get_qmi_deq_th(fman_rg.qmi_rg);
66203 + /* if deqTh is too small, we enlarge it to the min value that is still OK.
66204 + deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
66205 + if ((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
66206 + {
66207 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66208 + fman_set_qmi_deq_th(fman_rg.qmi_rg, deqTh);
66209 + }
66210 + }
66211 +
66212 +#ifdef FM_LOW_END_RESTRICTION
66213 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66214 + {
66215 + if (p_Fm->p_FmStateStruct->lowEndRestriction)
66216 + {
66217 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66218 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
66219 + }
66220 + else
66221 + p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
66222 + }
66223 +#endif /* FM_LOW_END_RESTRICTION */
66224 +
66225 + err = FmSetSizeOfFifo(p_Fm,
66226 + hardwarePortId,
66227 + &p_PortParams->sizeOfFifo,
66228 + &p_PortParams->extraSizeOfFifo,
66229 + TRUE);
66230 + if (err)
66231 + {
66232 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66233 + RETURN_ERROR(MAJOR, err, NO_MSG);
66234 + }
66235 +
66236 + err = FmSetNumOfOpenDmas(p_Fm,
66237 + hardwarePortId,
66238 + &p_PortParams->numOfOpenDmas,
66239 + &p_PortParams->numOfExtraOpenDmas,
66240 + TRUE);
66241 + if (err)
66242 + {
66243 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66244 + RETURN_ERROR(MAJOR, err, NO_MSG);
66245 + }
66246 +
66247 + fman_set_liodn_per_port(&fman_rg,
66248 + hardwarePortId,
66249 + p_PortParams->liodnBase,
66250 + p_PortParams->liodnOffset);
66251 +
66252 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66253 + fman_set_order_restoration_per_port(fman_rg.fpm_rg,
66254 + hardwarePortId,
66255 + p_PortParams->independentMode,
66256 + !!((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G)));
66257 +
66258 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66259 +
66260 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66261 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66262 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66263 + {
66264 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66265 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId])
66266 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = p_PortParams->maxFrameLength;
66267 + else
66268 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66269 + }
66270 + else
66271 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66272 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66273 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66274 + {
66275 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66276 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId])
66277 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = p_PortParams->maxFrameLength;
66278 + else
66279 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66280 + }
66281 +
66282 + FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
66283 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66284 +
66285 + return E_OK;
66286 +}
66287 +
66288 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
66289 +{
66290 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66291 + uint32_t intFlags;
66292 + uint8_t hardwarePortId = p_PortParams->hardwarePortId;
66293 + uint8_t numOfTasks, numOfDmas, macId;
66294 + uint16_t sizeOfFifo;
66295 + t_Error err;
66296 + t_FmIpcPortFreeParams portParams;
66297 + t_FmIpcMsg msg;
66298 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
66299 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66300 +
66301 + if (p_Fm->guestId != NCSW_MASTER_ID)
66302 + {
66303 + portParams.hardwarePortId = p_PortParams->hardwarePortId;
66304 + portParams.enumPortType = (uint32_t)p_PortParams->portType;
66305 + portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
66306 + memset(&msg, 0, sizeof(msg));
66307 + msg.msgId = FM_FREE_PORT;
66308 + memcpy(msg.msgBody, &portParams, sizeof(portParams));
66309 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66310 + (uint8_t*)&msg,
66311 + sizeof(msg.msgId)+sizeof(portParams),
66312 + NULL,
66313 + NULL,
66314 + NULL,
66315 + NULL);
66316 + if (err != E_OK)
66317 + REPORT_ERROR(MINOR, err, NO_MSG);
66318 + return;
66319 + }
66320 +
66321 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66322 +
66323 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66324 +
66325 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66326 + {
66327 + ASSERT_COND(p_Fm->hcPortInitialized);
66328 + p_Fm->hcPortInitialized = FALSE;
66329 + }
66330 +
66331 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
66332 +
66333 + /* free numOfTasks */
66334 + numOfTasks = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
66335 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
66336 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
66337 +
66338 + /* free numOfOpenDmas */
66339 + numOfDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
66340 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= numOfDmas);
66341 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= numOfDmas;
66342 +
66343 +#ifdef FM_HAS_TOTAL_DMAS
66344 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66345 + {
66346 + /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
66347 + fman_set_num_of_open_dmas(bmi_rg,
66348 + hardwarePortId,
66349 + 1,
66350 + 0,
66351 + (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize));
66352 + }
66353 +#endif /* FM_HAS_TOTAL_DMAS */
66354 +
66355 + /* free sizeOfFifo */
66356 + sizeOfFifo = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
66357 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= (sizeOfFifo * BMI_FIFO_UNITS));
66358 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= (sizeOfFifo * BMI_FIFO_UNITS);
66359 +
66360 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66361 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66362 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66363 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66364 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66365 + /* for transmit & O/H ports */
66366 + {
66367 + uint8_t enqTh;
66368 + uint8_t deqTh;
66369 +
66370 + /* update qmi ENQ/DEQ threshold */
66371 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
66372 +
66373 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66374 + so we can enlarge enqTh */
66375 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66376 +
66377 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66378 + so we can reduce deqTh */
66379 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66380 +
66381 + fman_set_qmi_enq_th(qmi_rg, enqTh);
66382 + fman_set_qmi_deq_th(qmi_rg, deqTh);
66383 + }
66384 +
66385 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66386 +
66387 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66388 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66389 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66390 + {
66391 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66392 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = 0;
66393 + }
66394 + else
66395 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66396 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66397 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66398 + {
66399 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66400 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = 0;
66401 + }
66402 +
66403 +#ifdef FM_LOW_END_RESTRICTION
66404 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66405 + p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
66406 +#endif /* FM_LOW_END_RESTRICTION */
66407 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66408 +}
66409 +
66410 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
66411 +{
66412 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66413 + t_Error err;
66414 + t_FmIpcMsg msg;
66415 + t_FmIpcReply reply;
66416 + uint32_t replyLength;
66417 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66418 +
66419 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66420 + !p_Fm->baseAddr &&
66421 + p_Fm->h_IpcSessions[0])
66422 + {
66423 + memset(&msg, 0, sizeof(msg));
66424 + memset(&reply, 0, sizeof(reply));
66425 + msg.msgId = FM_IS_PORT_STALLED;
66426 + msg.msgBody[0] = hardwarePortId;
66427 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
66428 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66429 + (uint8_t*)&msg,
66430 + sizeof(msg.msgId)+sizeof(hardwarePortId),
66431 + (uint8_t*)&reply,
66432 + &replyLength,
66433 + NULL,
66434 + NULL);
66435 + if (err != E_OK)
66436 + RETURN_ERROR(MINOR, err, NO_MSG);
66437 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
66438 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66439 +
66440 + *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
66441 +
66442 + return (t_Error)(reply.error);
66443 + }
66444 + else if (!p_Fm->baseAddr)
66445 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66446 + ("Either IPC or 'baseAddress' is required!"));
66447 +
66448 + *p_IsStalled = fman_is_port_stalled(fpm_rg, hardwarePortId);
66449 +
66450 + return E_OK;
66451 +}
66452 +
66453 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
66454 +{
66455 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66456 + t_Error err;
66457 + bool isStalled;
66458 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66459 +
66460 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66461 + !p_Fm->baseAddr &&
66462 + p_Fm->h_IpcSessions[0])
66463 + {
66464 + t_FmIpcMsg msg;
66465 + t_FmIpcReply reply;
66466 + uint32_t replyLength;
66467 +
66468 + memset(&msg, 0, sizeof(msg));
66469 + memset(&reply, 0, sizeof(reply));
66470 + msg.msgId = FM_RESUME_STALLED_PORT;
66471 + msg.msgBody[0] = hardwarePortId;
66472 + replyLength = sizeof(uint32_t);
66473 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66474 + (uint8_t*)&msg,
66475 + sizeof(msg.msgId) + sizeof(hardwarePortId),
66476 + (uint8_t*)&reply,
66477 + &replyLength,
66478 + NULL,
66479 + NULL);
66480 + if (err != E_OK)
66481 + RETURN_ERROR(MINOR, err, NO_MSG);
66482 + if (replyLength != sizeof(uint32_t))
66483 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66484 + return (t_Error)(reply.error);
66485 + }
66486 + else if (!p_Fm->baseAddr)
66487 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66488 + ("Either IPC or 'baseAddress' is required!"));
66489 +
66490 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66491 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not available for this FM revision!"));
66492 +
66493 + /* Get port status */
66494 + err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
66495 + if (err)
66496 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
66497 + if (!isStalled)
66498 + return E_OK;
66499 +
66500 + fman_resume_stalled_port(fpm_rg, hardwarePortId);
66501 +
66502 + return E_OK;
66503 +}
66504 +
66505 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
66506 +{
66507 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66508 + t_Error err;
66509 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66510 +
66511 +#if (DPAA_VERSION >= 11)
66512 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66513 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66514 + ("FMan MAC reset!"));
66515 +#endif /*(DPAA_VERSION >= 11)*/
66516 +
66517 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66518 + !p_Fm->baseAddr &&
66519 + p_Fm->h_IpcSessions[0])
66520 + {
66521 + t_FmIpcMacParams macParams;
66522 + t_FmIpcMsg msg;
66523 + t_FmIpcReply reply;
66524 + uint32_t replyLength;
66525 +
66526 + memset(&msg, 0, sizeof(msg));
66527 + memset(&reply, 0, sizeof(reply));
66528 + macParams.id = macId;
66529 + macParams.enumType = (uint32_t)type;
66530 + msg.msgId = FM_RESET_MAC;
66531 + memcpy(msg.msgBody, &macParams, sizeof(macParams));
66532 + replyLength = sizeof(uint32_t);
66533 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66534 + (uint8_t*)&msg,
66535 + sizeof(msg.msgId)+sizeof(macParams),
66536 + (uint8_t*)&reply,
66537 + &replyLength,
66538 + NULL,
66539 + NULL);
66540 + if (err != E_OK)
66541 + RETURN_ERROR(MINOR, err, NO_MSG);
66542 + if (replyLength != sizeof(uint32_t))
66543 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66544 + return (t_Error)(reply.error);
66545 + }
66546 + else if (!p_Fm->baseAddr)
66547 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66548 + ("Either IPC or 'baseAddress' is required!"));
66549 +
66550 + err = (t_Error)fman_reset_mac(fpm_rg, macId, !!(type == e_FM_MAC_10G));
66551 +
66552 + if (err == -EBUSY)
66553 + return ERROR_CODE(E_TIMEOUT);
66554 + else if (err)
66555 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal MAC ID"));
66556 +
66557 + return E_OK;
66558 +}
66559 +
66560 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
66561 +{
66562 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66563 +
66564 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66565 + p_Fm->h_IpcSessions[0])
66566 + {
66567 + t_FmIpcMacMaxFrameParams macMaxFrameLengthParams;
66568 + t_Error err;
66569 + t_FmIpcMsg msg;
66570 +
66571 + memset(&msg, 0, sizeof(msg));
66572 + macMaxFrameLengthParams.macParams.id = macId;
66573 + macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
66574 + macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
66575 + msg.msgId = FM_SET_MAC_MAX_FRAME;
66576 + memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
66577 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66578 + (uint8_t*)&msg,
66579 + sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
66580 + NULL,
66581 + NULL,
66582 + NULL,
66583 + NULL);
66584 + if (err != E_OK)
66585 + RETURN_ERROR(MINOR, err, NO_MSG);
66586 + return E_OK;
66587 + }
66588 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66589 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66590 + ("running in guest-mode without IPC!"));
66591 +
66592 + /* if port is already initialized, check that MaxFrameLength is smaller
66593 + * or equal to the port's max */
66594 +#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
66595 + if (type == e_FM_MAC_10G)
66596 + {
66597 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])
66598 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] &&
66599 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])))
66600 + p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
66601 + else
66602 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66603 +
66604 + }
66605 + else
66606 +#else
66607 + UNUSED(type);
66608 +#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66609 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])
66610 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] &&
66611 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])))
66612 + p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
66613 + else
66614 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66615 +
66616 + return E_OK;
66617 +}
66618 +
66619 +uint16_t FmGetClockFreq(t_Handle h_Fm)
66620 +{
66621 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66622 +
66623 + /* for multicore environment: this depends on the
66624 + * fact that fmClkFreq was properly initialized at "init". */
66625 + return p_Fm->p_FmStateStruct->fmClkFreq;
66626 +}
66627 +
66628 +uint16_t FmGetMacClockFreq(t_Handle h_Fm)
66629 +{
66630 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66631 +
66632 + return p_Fm->p_FmStateStruct->fmMacClkFreq;
66633 +}
66634 +
66635 +uint32_t FmGetTimeStampScale(t_Handle h_Fm)
66636 +{
66637 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66638 +
66639 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66640 + !p_Fm->baseAddr &&
66641 + p_Fm->h_IpcSessions[0])
66642 + {
66643 + t_Error err;
66644 + t_FmIpcMsg msg;
66645 + t_FmIpcReply reply;
66646 + uint32_t replyLength, timeStamp;
66647 +
66648 + memset(&msg, 0, sizeof(msg));
66649 + memset(&reply, 0, sizeof(reply));
66650 + msg.msgId = FM_GET_TIMESTAMP_SCALE;
66651 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
66652 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66653 + (uint8_t*)&msg,
66654 + sizeof(msg.msgId),
66655 + (uint8_t*)&reply,
66656 + &replyLength,
66657 + NULL,
66658 + NULL)) != E_OK)
66659 + {
66660 + REPORT_ERROR(MAJOR, err, NO_MSG);
66661 + return 0;
66662 + }
66663 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
66664 + {
66665 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66666 + return 0;
66667 + }
66668 +
66669 + memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
66670 + return timeStamp;
66671 + }
66672 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66673 + p_Fm->baseAddr)
66674 + {
66675 + if (!(GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1) & FPM_TS_CTL_EN))
66676 + {
66677 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!"));
66678 + return 0;
66679 + }
66680 + }
66681 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66682 + DBG(WARNING, ("No IPC - can't validate FM if timestamp enabled."));
66683 +
66684 + return p_Fm->p_FmStateStruct->count1MicroBit;
66685 +}
66686 +
66687 +t_Error FmEnableRamsEcc(t_Handle h_Fm)
66688 +{
66689 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66690 +
66691 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66692 +
66693 + p_Fm->p_FmStateStruct->ramsEccOwners++;
66694 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66695 +
66696 + return FM_EnableRamsEcc(p_Fm);
66697 +}
66698 +
66699 +t_Error FmDisableRamsEcc(t_Handle h_Fm)
66700 +{
66701 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66702 +
66703 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66704 +
66705 + ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
66706 + p_Fm->p_FmStateStruct->ramsEccOwners--;
66707 +
66708 + if (p_Fm->p_FmStateStruct->ramsEccOwners==0)
66709 + {
66710 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66711 + return FM_DisableRamsEcc(p_Fm);
66712 + }
66713 +
66714 + return E_OK;
66715 +}
66716 +
66717 +uint8_t FmGetGuestId(t_Handle h_Fm)
66718 +{
66719 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66720 +
66721 + return p_Fm->guestId;
66722 +}
66723 +
66724 +bool FmIsMaster(t_Handle h_Fm)
66725 +{
66726 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66727 +
66728 + return (p_Fm->guestId == NCSW_MASTER_ID);
66729 +}
66730 +
66731 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
66732 + uint8_t hardwarePortId,
66733 + uint32_t *p_SizeOfFifo,
66734 + uint32_t *p_ExtraSizeOfFifo,
66735 + bool initialConfig)
66736 +{
66737 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66738 + t_FmIpcPortRsrcParams rsrcParams;
66739 + t_Error err;
66740 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66741 + uint32_t sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo;
66742 + uint16_t currentVal = 0, currentExtraVal = 0;
66743 +
66744 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66745 + !p_Fm->baseAddr &&
66746 + p_Fm->h_IpcSessions[0])
66747 + {
66748 + t_FmIpcMsg msg;
66749 + t_FmIpcReply reply;
66750 + uint32_t replyLength;
66751 +
66752 + rsrcParams.hardwarePortId = hardwarePortId;
66753 + rsrcParams.val = sizeOfFifo;
66754 + rsrcParams.extra = extraSizeOfFifo;
66755 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
66756 +
66757 + memset(&msg, 0, sizeof(msg));
66758 + memset(&reply, 0, sizeof(reply));
66759 + msg.msgId = FM_SET_SIZE_OF_FIFO;
66760 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
66761 + replyLength = sizeof(uint32_t);
66762 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66763 + (uint8_t*)&msg,
66764 + sizeof(msg.msgId) + sizeof(rsrcParams),
66765 + (uint8_t*)&reply,
66766 + &replyLength,
66767 + NULL,
66768 + NULL)) != E_OK)
66769 + RETURN_ERROR(MINOR, err, NO_MSG);
66770 + if (replyLength != sizeof(uint32_t))
66771 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66772 + return (t_Error)(reply.error);
66773 + }
66774 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66775 + p_Fm->baseAddr)
66776 + {
66777 + DBG(WARNING, ("No IPC - can't validate FM total-fifo size."));
66778 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
66779 + }
66780 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66781 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
66782 + ("running in guest-mode without neither IPC nor mapped register!"));
66783 +
66784 + if (!initialConfig)
66785 + {
66786 + /* !initialConfig - runtime change of existing value.
66787 + * - read the current FIFO and extra FIFO size */
66788 + currentExtraVal = fman_get_size_of_extra_fifo(bmi_rg, hardwarePortId);
66789 + currentVal = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
66790 + }
66791 +
66792 + if (extraSizeOfFifo > currentExtraVal)
66793 + {
66794 + if (extraSizeOfFifo && !p_Fm->p_FmStateStruct->extraFifoPoolSize)
66795 + /* if this is the first time a port requires extraFifoPoolSize, the total extraFifoPoolSize
66796 + * must be initialized to 1 buffer per port
66797 + */
66798 + p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
66799 +
66800 + p_Fm->p_FmStateStruct->extraFifoPoolSize = MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
66801 + }
66802 +
66803 + /* check that there are enough uncommitted fifo size */
66804 + if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - currentVal + sizeOfFifo) >
66805 + (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)){
66806 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
66807 + ("Port request fifo size + accumulated size > total FIFO size:"));
66808 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
66809 + ("port 0x%x requested %d bytes, extra size = %d, accumulated size = %d total size = %d",
66810 + hardwarePortId, sizeOfFifo, p_Fm->p_FmStateStruct->extraFifoPoolSize,
66811 + p_Fm->p_FmStateStruct->accumulatedFifoSize,
66812 + p_Fm->p_FmStateStruct->totalFifoSize));
66813 + }
66814 + else
66815 + {
66816 + /* update accumulated */
66817 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal);
66818 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal;
66819 + p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
66820 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
66821 + }
66822 +
66823 + return E_OK;
66824 +}
66825 +
66826 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
66827 + uint8_t hardwarePortId,
66828 + uint8_t *p_NumOfTasks,
66829 + uint8_t *p_NumOfExtraTasks,
66830 + bool initialConfig)
66831 +{
66832 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66833 + t_Error err;
66834 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66835 + uint8_t currentVal = 0, currentExtraVal = 0, numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks;
66836 +
66837 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66838 +
66839 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66840 + !p_Fm->baseAddr &&
66841 + p_Fm->h_IpcSessions[0])
66842 + {
66843 + t_FmIpcPortRsrcParams rsrcParams;
66844 + t_FmIpcMsg msg;
66845 + t_FmIpcReply reply;
66846 + uint32_t replyLength;
66847 +
66848 + rsrcParams.hardwarePortId = hardwarePortId;
66849 + rsrcParams.val = numOfTasks;
66850 + rsrcParams.extra = numOfExtraTasks;
66851 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
66852 +
66853 + memset(&msg, 0, sizeof(msg));
66854 + memset(&reply, 0, sizeof(reply));
66855 + msg.msgId = FM_SET_NUM_OF_TASKS;
66856 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
66857 + replyLength = sizeof(uint32_t);
66858 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66859 + (uint8_t*)&msg,
66860 + sizeof(msg.msgId) + sizeof(rsrcParams),
66861 + (uint8_t*)&reply,
66862 + &replyLength,
66863 + NULL,
66864 + NULL)) != E_OK)
66865 + RETURN_ERROR(MINOR, err, NO_MSG);
66866 + if (replyLength != sizeof(uint32_t))
66867 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66868 + return (t_Error)(reply.error);
66869 + }
66870 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66871 + p_Fm->baseAddr)
66872 + {
66873 + DBG(WARNING, ("No IPC - can't validate FM total-num-of-tasks."));
66874 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
66875 + }
66876 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66877 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
66878 + ("running in guest-mode without neither IPC nor mapped register!"));
66879 +
66880 + if (!initialConfig)
66881 + {
66882 + /* !initialConfig - runtime change of existing value.
66883 + * - read the current number of tasks */
66884 + currentVal = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
66885 + currentExtraVal = fman_get_num_extra_tasks(bmi_rg, hardwarePortId);
66886 + }
66887 +
66888 + if (numOfExtraTasks > currentExtraVal)
66889 + p_Fm->p_FmStateStruct->extraTasksPoolSize =
66890 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
66891 +
66892 + /* check that there are enough uncommitted tasks */
66893 + if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - currentVal + numOfTasks) >
66894 + (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
66895 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
66896 + ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
66897 + p_Fm->p_FmStateStruct->fmId));
66898 + else
66899 + {
66900 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= currentVal);
66901 + /* update accumulated */
66902 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal;
66903 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
66904 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
66905 + }
66906 +
66907 + return E_OK;
66908 +}
66909 +
66910 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
66911 + uint8_t hardwarePortId,
66912 + uint8_t *p_NumOfOpenDmas,
66913 + uint8_t *p_NumOfExtraOpenDmas,
66914 + bool initialConfig)
66915 +
66916 +{
66917 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66918 + t_Error err;
66919 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66920 + uint8_t numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas;
66921 + uint8_t totalNumDmas = 0, currentVal = 0, currentExtraVal = 0;
66922 +
66923 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66924 +
66925 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66926 + !p_Fm->baseAddr &&
66927 + p_Fm->h_IpcSessions[0])
66928 + {
66929 + t_FmIpcPortRsrcParams rsrcParams;
66930 + t_FmIpcMsg msg;
66931 + t_FmIpcReply reply;
66932 + uint32_t replyLength;
66933 +
66934 + rsrcParams.hardwarePortId = hardwarePortId;
66935 + rsrcParams.val = numOfOpenDmas;
66936 + rsrcParams.extra = numOfExtraOpenDmas;
66937 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
66938 +
66939 + memset(&msg, 0, sizeof(msg));
66940 + memset(&reply, 0, sizeof(reply));
66941 + msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
66942 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
66943 + replyLength = sizeof(uint32_t);
66944 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66945 + (uint8_t*)&msg,
66946 + sizeof(msg.msgId) + sizeof(rsrcParams),
66947 + (uint8_t*)&reply,
66948 + &replyLength,
66949 + NULL,
66950 + NULL)) != E_OK)
66951 + RETURN_ERROR(MINOR, err, NO_MSG);
66952 + if (replyLength != sizeof(uint32_t))
66953 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66954 + return (t_Error)(reply.error);
66955 + }
66956 +#ifdef FM_HAS_TOTAL_DMAS
66957 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66958 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("running in guest-mode without IPC!"));
66959 +#else
66960 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66961 + p_Fm->baseAddr &&
66962 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
66963 + {
66964 + /*DBG(WARNING, ("No IPC - can't validate FM total-num-of-dmas."));*/
66965 +
66966 + if (!numOfOpenDmas)
66967 + {
66968 + /* first config without explic it value: Do Nothing - reset value shouldn't be
66969 + changed, read register for port save */
66970 + *p_NumOfOpenDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
66971 + *p_NumOfExtraOpenDmas = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
66972 + }
66973 + else
66974 + /* whether it is the first time with explicit value, or runtime "set" - write register */
66975 + fman_set_num_of_open_dmas(bmi_rg,
66976 + hardwarePortId,
66977 + numOfOpenDmas,
66978 + numOfExtraOpenDmas,
66979 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
66980 + }
66981 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66982 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
66983 + ("running in guest-mode without neither IPC nor mapped register!"));
66984 +#endif /* FM_HAS_TOTAL_DMAS */
66985 +
66986 + if (!initialConfig)
66987 + {
66988 + /* !initialConfig - runtime change of existing value.
66989 + * - read the current number of open Dma's */
66990 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
66991 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
66992 + }
66993 +
66994 +#ifdef FM_NO_GUARANTEED_RESET_VALUES
66995 + /* it's illegal to be in a state where this is not the first set and no value is specified */
66996 + ASSERT_COND(initialConfig || numOfOpenDmas);
66997 + if (!numOfOpenDmas)
66998 + {
66999 + /* !numOfOpenDmas - first configuration according to values in regs.
67000 + * - read the current number of open Dma's */
67001 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67002 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67003 + /* This is the first configuration and user did not specify value (!numOfOpenDmas),
67004 + * reset values will be used and we just save these values for resource management */
67005 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
67006 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, currentExtraVal);
67007 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += currentVal;
67008 + *p_NumOfOpenDmas = currentVal;
67009 + *p_NumOfExtraOpenDmas = currentExtraVal;
67010 + return E_OK;
67011 + }
67012 +#endif /* FM_NO_GUARANTEED_RESET_VALUES */
67013 +
67014 + if (numOfExtraOpenDmas > currentExtraVal)
67015 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
67016 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
67017 +
67018 +#ifdef FM_HAS_TOTAL_DMAS
67019 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
67020 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas >
67021 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas))
67022 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67023 + ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
67024 + p_Fm->p_FmStateStruct->fmId));
67025 +#else
67026 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) &&
67027 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
67028 + !((p_Fm->p_FmStateStruct->revInfo.majorRev == 6) &&
67029 + (p_Fm->p_FmStateStruct->revInfo.minorRev == 0)) &&
67030 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
67031 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > DMA_THRESH_MAX_COMMQ + 1))
67032 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67033 + ("Requested numOfOpenDmas for fm%d exceeds DMA Command queue (%d)",
67034 + p_Fm->p_FmStateStruct->fmId, DMA_THRESH_MAX_COMMQ+1));
67035 +#endif /* FM_HAS_TOTAL_DMAS */
67036 + else
67037 + {
67038 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= currentVal);
67039 + /* update acummulated */
67040 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= currentVal;
67041 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
67042 +
67043 +#ifdef FM_HAS_TOTAL_DMAS
67044 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
67045 + totalNumDmas = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
67046 +#endif /* FM_HAS_TOTAL_DMAS */
67047 + fman_set_num_of_open_dmas(bmi_rg,
67048 + hardwarePortId,
67049 + numOfOpenDmas,
67050 + numOfExtraOpenDmas,
67051 + totalNumDmas);
67052 + }
67053 +
67054 + return E_OK;
67055 +}
67056 +
67057 +#if (DPAA_VERSION >= 11)
67058 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
67059 + e_FmPortType portType,
67060 + uint8_t portId,
67061 + uint16_t relativeProfile)
67062 +{
67063 + t_Fm *p_Fm;
67064 + t_FmSp *p_FmPcdSp;
67065 + uint8_t swPortIndex=0, hardwarePortId;
67066 +
67067 + ASSERT_COND(h_Fm);
67068 + p_Fm = (t_Fm*)h_Fm;
67069 +
67070 + hardwarePortId = SwPortIdToHwPortId(portType,
67071 + portId,
67072 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67073 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67074 + ASSERT_COND(hardwarePortId);
67075 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67076 +
67077 + p_FmPcdSp = p_Fm->p_FmSp;
67078 + ASSERT_COND(p_FmPcdSp);
67079 +
67080 + if (!p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
67081 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Port has no allocated profiles"));
67082 + if (relativeProfile >= p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
67083 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE , ("Profile id is out of range"));
67084 +
67085 + return E_OK;
67086 +}
67087 +
67088 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
67089 + e_FmPortType portType,
67090 + uint8_t portId,
67091 + uint16_t relativeProfile,
67092 + uint16_t *p_AbsoluteId)
67093 +{
67094 + t_Fm *p_Fm;
67095 + t_FmSp *p_FmPcdSp;
67096 + uint8_t swPortIndex=0, hardwarePortId;
67097 + t_Error err;
67098 +
67099 + ASSERT_COND(h_Fm);
67100 + p_Fm = (t_Fm*)h_Fm;
67101 +
67102 + err = FmVSPCheckRelativeProfile(h_Fm, portType, portId, relativeProfile);
67103 + if (err != E_OK)
67104 + return err;
67105 +
67106 + hardwarePortId = SwPortIdToHwPortId(portType,
67107 + portId,
67108 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67109 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67110 + ASSERT_COND(hardwarePortId);
67111 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67112 +
67113 + p_FmPcdSp = p_Fm->p_FmSp;
67114 + ASSERT_COND(p_FmPcdSp);
67115 +
67116 + *p_AbsoluteId = (uint16_t)(p_FmPcdSp->portsMapping[swPortIndex].profilesBase + relativeProfile);
67117 +
67118 + return E_OK;
67119 +}
67120 +#endif /* (DPAA_VERSION >= 11) */
67121 +
67122 +static t_Error InitFmDma(t_Fm *p_Fm)
67123 +{
67124 + t_Error err;
67125 +
67126 + err = (t_Error)fman_dma_init(p_Fm->p_FmDmaRegs, p_Fm->p_FmDriverParam);
67127 + if (err != E_OK)
67128 + return err;
67129 +
67130 + /* Allocate MURAM for CAM */
67131 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67132 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY),
67133 + DMA_CAM_ALIGN));
67134 + if (!p_Fm->camBaseAddr)
67135 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67136 +
67137 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67138 + 0,
67139 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY));
67140 +
67141 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 2)
67142 + {
67143 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
67144 +
67145 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67146 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128),
67147 + 64));
67148 + if (!p_Fm->camBaseAddr)
67149 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67150 +
67151 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67152 + 0,
67153 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128));
67154 +
67155 + switch(p_Fm->p_FmDriverParam->dma_cam_num_of_entries)
67156 + {
67157 + case (8):
67158 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xff000000);
67159 + break;
67160 + case (16):
67161 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffff0000);
67162 + break;
67163 + case (24):
67164 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffff00);
67165 + break;
67166 + case (32):
67167 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffffff);
67168 + break;
67169 + default:
67170 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("wrong dma_cam_num_of_entries"));
67171 + }
67172 + }
67173 +
67174 + p_Fm->p_FmDriverParam->cam_base_addr =
67175 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
67176 +
67177 + return E_OK;
67178 +}
67179 +
67180 +static t_Error InitFmFpm(t_Fm *p_Fm)
67181 +{
67182 + return (t_Error)fman_fpm_init(p_Fm->p_FmFpmRegs, p_Fm->p_FmDriverParam);
67183 +}
67184 +
67185 +static t_Error InitFmBmi(t_Fm *p_Fm)
67186 +{
67187 + return (t_Error)fman_bmi_init(p_Fm->p_FmBmiRegs, p_Fm->p_FmDriverParam);
67188 +}
67189 +
67190 +static t_Error InitFmQmi(t_Fm *p_Fm)
67191 +{
67192 + return (t_Error)fman_qmi_init(p_Fm->p_FmQmiRegs, p_Fm->p_FmDriverParam);
67193 +}
67194 +
67195 +static t_Error InitGuestMode(t_Fm *p_Fm)
67196 +{
67197 + t_Error err = E_OK;
67198 + int i;
67199 + t_FmIpcMsg msg;
67200 + t_FmIpcReply reply;
67201 + uint32_t replyLength;
67202 +
67203 + ASSERT_COND(p_Fm);
67204 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
67205 +
67206 + /* build the FM guest partition IPC address */
67207 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
67208 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67209 +
67210 + /* build the FM master partition IPC address */
67211 + memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
67212 + if (Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
67213 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67214 +
67215 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
67216 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
67217 +
67218 + p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
67219 + if (p_Fm->h_IpcSessions[0])
67220 + {
67221 + uint8_t isMasterAlive;
67222 + t_FmIpcParams ipcParams;
67223 +
67224 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
67225 + if (err)
67226 + RETURN_ERROR(MAJOR, err, NO_MSG);
67227 +
67228 + memset(&msg, 0, sizeof(msg));
67229 + memset(&reply, 0, sizeof(reply));
67230 + msg.msgId = FM_MASTER_IS_ALIVE;
67231 + msg.msgBody[0] = p_Fm->guestId;
67232 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
67233 + do
67234 + {
67235 + blockingFlag = TRUE;
67236 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67237 + (uint8_t*)&msg,
67238 + sizeof(msg.msgId)+sizeof(p_Fm->guestId),
67239 + (uint8_t*)&reply,
67240 + &replyLength,
67241 + IpcMsgCompletionCB,
67242 + p_Fm)) != E_OK)
67243 + REPORT_ERROR(MINOR, err, NO_MSG);
67244 + while (blockingFlag) ;
67245 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
67246 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67247 + isMasterAlive = *(uint8_t*)(reply.replyBody);
67248 + } while (!isMasterAlive);
67249 +
67250 + /* read FM parameters and save */
67251 + memset(&msg, 0, sizeof(msg));
67252 + memset(&reply, 0, sizeof(reply));
67253 + msg.msgId = FM_GET_PARAMS;
67254 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
67255 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67256 + (uint8_t*)&msg,
67257 + sizeof(msg.msgId),
67258 + (uint8_t*)&reply,
67259 + &replyLength,
67260 + NULL,
67261 + NULL)) != E_OK)
67262 + RETURN_ERROR(MAJOR, err, NO_MSG);
67263 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcParams)))
67264 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67265 + memcpy((uint8_t*)&ipcParams, reply.replyBody, sizeof(t_FmIpcParams));
67266 +
67267 + p_Fm->p_FmStateStruct->fmClkFreq = ipcParams.fmClkFreq;
67268 + p_Fm->p_FmStateStruct->fmMacClkFreq = ipcParams.fmMacClkFreq;
67269 + p_Fm->p_FmStateStruct->revInfo.majorRev = ipcParams.majorRev;
67270 + p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev;
67271 + }
67272 + else
67273 + {
67274 + DBG(WARNING, ("FM Guest mode - without IPC"));
67275 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
67276 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
67277 + if (p_Fm->baseAddr)
67278 + {
67279 + fman_get_revision(p_Fm->p_FmFpmRegs,
67280 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67281 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67282 +
67283 + }
67284 + }
67285 +
67286 +#if (DPAA_VERSION >= 11)
67287 + p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67288 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
67289 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
67290 +#endif /* (DPAA_VERSION >= 11) */
67291 +
67292 + /* General FM driver initialization */
67293 + if (p_Fm->baseAddr)
67294 + p_Fm->fmMuramPhysBaseAddr =
67295 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
67296 +
67297 + XX_Free(p_Fm->p_FmDriverParam);
67298 + p_Fm->p_FmDriverParam = NULL;
67299 +
67300 + if ((p_Fm->guestId == NCSW_MASTER_ID) ||
67301 + (p_Fm->h_IpcSessions[0]))
67302 + {
67303 + FM_DisableRamsEcc(p_Fm);
67304 + FmMuramClear(p_Fm->h_FmMuram);
67305 + FM_EnableRamsEcc(p_Fm);
67306 + }
67307 +
67308 + return E_OK;
67309 +}
67310 +
67311 +static __inline__ enum fman_exceptions FmanExceptionTrans(e_FmExceptions exception)
67312 +{
67313 + switch (exception) {
67314 + case e_FM_EX_DMA_BUS_ERROR:
67315 + return E_FMAN_EX_DMA_BUS_ERROR;
67316 + case e_FM_EX_DMA_READ_ECC:
67317 + return E_FMAN_EX_DMA_READ_ECC;
67318 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC:
67319 + return E_FMAN_EX_DMA_SYSTEM_WRITE_ECC;
67320 + case e_FM_EX_DMA_FM_WRITE_ECC:
67321 + return E_FMAN_EX_DMA_FM_WRITE_ECC;
67322 + case e_FM_EX_FPM_STALL_ON_TASKS:
67323 + return E_FMAN_EX_FPM_STALL_ON_TASKS;
67324 + case e_FM_EX_FPM_SINGLE_ECC:
67325 + return E_FMAN_EX_FPM_SINGLE_ECC;
67326 + case e_FM_EX_FPM_DOUBLE_ECC:
67327 + return E_FMAN_EX_FPM_DOUBLE_ECC;
67328 + case e_FM_EX_QMI_SINGLE_ECC:
67329 + return E_FMAN_EX_QMI_SINGLE_ECC;
67330 + case e_FM_EX_QMI_DOUBLE_ECC:
67331 + return E_FMAN_EX_QMI_DOUBLE_ECC;
67332 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
67333 + return E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID;
67334 + case e_FM_EX_BMI_LIST_RAM_ECC:
67335 + return E_FMAN_EX_BMI_LIST_RAM_ECC;
67336 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
67337 + return E_FMAN_EX_BMI_STORAGE_PROFILE_ECC;
67338 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
67339 + return E_FMAN_EX_BMI_STATISTICS_RAM_ECC;
67340 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
67341 + return E_FMAN_EX_BMI_DISPATCH_RAM_ECC;
67342 + case e_FM_EX_IRAM_ECC:
67343 + return E_FMAN_EX_IRAM_ECC;
67344 + case e_FM_EX_MURAM_ECC:
67345 + return E_FMAN_EX_MURAM_ECC;
67346 + default:
67347 + return E_FMAN_EX_DMA_BUS_ERROR;
67348 + }
67349 +}
67350 +
67351 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev)
67352 +{
67353 + switch (type)
67354 + {
67355 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
67356 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
67357 + CHECK_PORT_ID_OH_PORTS(relativePortId);
67358 + return (uint8_t)(BASE_OH_PORTID + (relativePortId));
67359 + case (e_FM_PORT_TYPE_RX):
67360 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67361 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67362 + case (e_FM_PORT_TYPE_RX_10G):
67363 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67364 + * This is the reason why the 1G port offset is used.
67365 + */
67366 + if (majorRev == 6 && minorRev == 4)
67367 + {
67368 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67369 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67370 + }
67371 + else
67372 + {
67373 + CHECK_PORT_ID_10G_RX_PORTS(relativePortId);
67374 + return (uint8_t)(BASE_10G_RX_PORTID + (relativePortId));
67375 + }
67376 + case (e_FM_PORT_TYPE_TX):
67377 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67378 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67379 + case (e_FM_PORT_TYPE_TX_10G):
67380 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67381 + * This is the reason why the 1G port offset is used.
67382 + */
67383 + if (majorRev == 6 && minorRev == 4)
67384 + {
67385 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67386 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67387 + }
67388 + else
67389 + {
67390 + CHECK_PORT_ID_10G_TX_PORTS(relativePortId);
67391 + return (uint8_t)(BASE_10G_TX_PORTID + (relativePortId));
67392 + }
67393 + default:
67394 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
67395 + return 0;
67396 + }
67397 +}
67398 +
67399 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
67400 +t_Error FmDumpPortRegs (t_Handle h_Fm, uint8_t hardwarePortId)
67401 +{
67402 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67403 +
67404 + DECLARE_DUMP;
67405 +
67406 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67407 +
67408 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67409 + SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) ||
67410 + p_Fm->baseAddr), E_INVALID_OPERATION);
67411 +
67412 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
67413 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
67414 +
67415 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
67416 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
67417 +
67418 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], ("fmbm_spliodn for port %u", (hardwarePortId)));
67419 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], sizeof(uint32_t));
67420 +
67421 + DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], ("fmfp_ps for port %u", (hardwarePortId)));
67422 + DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], sizeof(uint32_t));
67423 +
67424 + DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], ("fmdmplr for port %u", (hardwarePortId)));
67425 + DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], sizeof(uint32_t));
67426 +
67427 + return E_OK;
67428 +}
67429 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
67430 +
67431 +
67432 +/*****************************************************************************/
67433 +/* API Init unit functions */
67434 +/*****************************************************************************/
67435 +t_Handle FM_Config(t_FmParams *p_FmParam)
67436 +{
67437 + t_Fm *p_Fm;
67438 + uint8_t i;
67439 + uintptr_t baseAddr;
67440 +
67441 + SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
67442 + SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
67443 + (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
67444 + E_INVALID_VALUE, NULL);
67445 +
67446 + baseAddr = p_FmParam->baseAddr;
67447 +
67448 + /* Allocate FM structure */
67449 + p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
67450 + if (!p_Fm)
67451 + {
67452 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
67453 + return NULL;
67454 + }
67455 + memset(p_Fm, 0, sizeof(t_Fm));
67456 +
67457 + p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
67458 + if (!p_Fm->p_FmStateStruct)
67459 + {
67460 + XX_Free(p_Fm);
67461 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
67462 + return NULL;
67463 + }
67464 + memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
67465 +
67466 + /* Initialize FM parameters which will be kept by the driver */
67467 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67468 + p_Fm->guestId = p_FmParam->guestId;
67469 +
67470 + for (i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
67471 + p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
67472 +
67473 + /* Allocate the FM driver's parameters structure */
67474 + p_Fm->p_FmDriverParam = (struct fman_cfg *)XX_Malloc(sizeof(struct fman_cfg));
67475 + if (!p_Fm->p_FmDriverParam)
67476 + {
67477 + XX_Free(p_Fm->p_FmStateStruct);
67478 + XX_Free(p_Fm);
67479 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
67480 + return NULL;
67481 + }
67482 + memset(p_Fm->p_FmDriverParam, 0, sizeof(struct fman_cfg));
67483 +
67484 +#if (DPAA_VERSION >= 11)
67485 + p_Fm->p_FmSp = (t_FmSp *)XX_Malloc(sizeof(t_FmSp));
67486 + if (!p_Fm->p_FmSp)
67487 + {
67488 + XX_Free(p_Fm->p_FmDriverParam);
67489 + XX_Free(p_Fm->p_FmStateStruct);
67490 + XX_Free(p_Fm);
67491 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("allocation for internal data structure failed"));
67492 + return NULL;
67493 + }
67494 + memset(p_Fm->p_FmSp, 0, sizeof(t_FmSp));
67495 +
67496 + for (i=0; i<FM_VSP_MAX_NUM_OF_ENTRIES; i++)
67497 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
67498 +#endif /* (DPAA_VERSION >= 11) */
67499 +
67500 + /* Initialize FM parameters which will be kept by the driver */
67501 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67502 + p_Fm->h_FmMuram = p_FmParam->h_FmMuram;
67503 + p_Fm->h_App = p_FmParam->h_App;
67504 + p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq;
67505 + p_Fm->p_FmStateStruct->fmMacClkFreq = p_FmParam->fmClkFreq / ((!p_FmParam->fmMacClkRatio)? 2: p_FmParam->fmMacClkRatio);
67506 + p_Fm->f_Exception = p_FmParam->f_Exception;
67507 + p_Fm->f_BusError = p_FmParam->f_BusError;
67508 + p_Fm->p_FmFpmRegs = (struct fman_fpm_regs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
67509 + p_Fm->p_FmBmiRegs = (struct fman_bmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67510 + p_Fm->p_FmQmiRegs = (struct fman_qmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
67511 + p_Fm->p_FmDmaRegs = (struct fman_dma_regs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
67512 + p_Fm->p_FmRegs = (struct fman_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67513 + p_Fm->baseAddr = baseAddr;
67514 + p_Fm->p_FmStateStruct->irq = p_FmParam->irq;
67515 + p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq;
67516 + p_Fm->hcPortInitialized = FALSE;
67517 + p_Fm->independentMode = FALSE;
67518 +
67519 + p_Fm->h_Spinlock = XX_InitSpinlock();
67520 + if (!p_Fm->h_Spinlock)
67521 + {
67522 + XX_Free(p_Fm->p_FmDriverParam);
67523 + XX_Free(p_Fm->p_FmStateStruct);
67524 + XX_Free(p_Fm);
67525 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("can't allocate spinlock!"));
67526 + return NULL;
67527 + }
67528 +
67529 +#if (DPAA_VERSION >= 11)
67530 + p_Fm->partVSPBase = p_FmParam->partVSPBase;
67531 + p_Fm->partNumOfVSPs = p_FmParam->partNumOfVSPs;
67532 + p_Fm->vspBaseAddr = p_FmParam->vspBaseAddr;
67533 +#endif /* (DPAA_VERSION >= 11) */
67534 +
67535 + fman_defconfig(p_Fm->p_FmDriverParam,
67536 + !!(p_Fm->guestId == NCSW_MASTER_ID));
67537 +/* overide macros dependent parameters */
67538 +#ifdef FM_PEDANTIC_DMA
67539 + p_Fm->p_FmDriverParam->pedantic_dma = TRUE;
67540 + p_Fm->p_FmDriverParam->dma_aid_override = TRUE;
67541 +#endif /* FM_PEDANTIC_DMA */
67542 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67543 + p_Fm->p_FmDriverParam->qmi_deq_option_support = TRUE;
67544 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67545 +
67546 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
67547 + p_Fm->p_FmStateStruct->extraFifoPoolSize = 0;
67548 + p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions;
67549 + p_Fm->resetOnInit = DEFAULT_resetOnInit;
67550 + p_Fm->f_ResetOnInitOverride = DEFAULT_resetOnInitOverrideCallback;
67551 + p_Fm->fwVerify = DEFAULT_VerifyUcode;
67552 + p_Fm->firmware.size = p_FmParam->firmware.size;
67553 + if (p_Fm->firmware.size)
67554 + {
67555 + p_Fm->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->firmware.size);
67556 + if (!p_Fm->firmware.p_Code)
67557 + {
67558 + XX_FreeSpinlock(p_Fm->h_Spinlock);
67559 + XX_Free(p_Fm->p_FmStateStruct);
67560 + XX_Free(p_Fm->p_FmDriverParam);
67561 + XX_Free(p_Fm);
67562 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
67563 + return NULL;
67564 + }
67565 + memcpy(p_Fm->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->firmware.size);
67566 + }
67567 +
67568 + if (p_Fm->guestId != NCSW_MASTER_ID)
67569 + return p_Fm;
67570 +
67571 + /* read revision */
67572 + /* Chip dependent, will be configured in Init */
67573 + fman_get_revision(p_Fm->p_FmFpmRegs,
67574 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67575 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67576 +
67577 +#ifdef FM_AID_MODE_NO_TNUM_SW005
67578 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
67579 + p_Fm->p_FmDriverParam->dma_aid_mode = e_FM_DMA_AID_OUT_PORT_ID;
67580 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
67581 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67582 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
67583 + p_Fm->p_FmDriverParam->qmi_def_tnums_thresh = QMI_DEF_TNUMS_THRESH;
67584 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67585 +
67586 + p_Fm->p_FmStateStruct->totalFifoSize = 0;
67587 + p_Fm->p_FmStateStruct->totalNumOfTasks =
67588 + DEFAULT_totalNumOfTasks(p_Fm->p_FmStateStruct->revInfo.majorRev,
67589 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67590 +
67591 +#ifdef FM_HAS_TOTAL_DMAS
67592 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS;
67593 +#endif /* FM_HAS_TOTAL_DMAS */
67594 +#if (DPAA_VERSION < 11)
67595 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = DEFAULT_dmaCommQLow;
67596 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = DEFAULT_dmaCommQHigh;
67597 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = DEFAULT_dmaCamNumOfEntries;
67598 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = DEFAULT_dmaReadIntBufLow;
67599 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = DEFAULT_dmaReadIntBufHigh;
67600 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = DEFAULT_dmaWriteIntBufLow;
67601 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = DEFAULT_dmaWriteIntBufHigh;
67602 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = DEFAULT_axiDbgNumOfBeats;
67603 +#endif /* (DPAA_VERSION < 11) */
67604 +#ifdef FM_NO_TNUM_AGING
67605 + p_Fm->p_FmDriverParam->tnum_aging_period = 0;
67606 +#endif
67607 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
67608 +
67609 + return p_Fm;
67610 +}
67611 +
67612 +/**************************************************************************//**
67613 + @Function FM_Init
67614 +
67615 + @Description Initializes the FM module
67616 +
67617 + @Param[in] h_Fm - FM module descriptor
67618 +
67619 + @Return E_OK on success; Error code otherwise.
67620 +*//***************************************************************************/
67621 +t_Error FM_Init(t_Handle h_Fm)
67622 +{
67623 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67624 + struct fman_cfg *p_FmDriverParam = NULL;
67625 + t_Error err = E_OK;
67626 + int i;
67627 + t_FmRevisionInfo revInfo;
67628 + struct fman_rg fman_rg;
67629 +
67630 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67631 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67632 +
67633 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
67634 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
67635 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
67636 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
67637 +
67638 + p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT;
67639 + p_Fm->p_FmDriverParam->num_of_fman_ctrl_evnt_regs = FM_NUM_OF_FMAN_CTRL_EVENT_REGS;
67640 +
67641 + if (p_Fm->guestId != NCSW_MASTER_ID)
67642 + return InitGuestMode(p_Fm);
67643 +
67644 + /* if user didn't configured totalFifoSize - (totalFifoSize=0) we configure default
67645 + * according to chip. otherwise, we use user's configuration.
67646 + */
67647 + if (p_Fm->p_FmStateStruct->totalFifoSize == 0)
67648 + p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize(p_Fm->p_FmStateStruct->revInfo.majorRev,
67649 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67650 +
67651 + CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
67652 +
67653 + p_FmDriverParam = p_Fm->p_FmDriverParam;
67654 +
67655 + FM_GetRevision(p_Fm, &revInfo);
67656 +
67657 + /* clear revision-dependent non existing exception */
67658 +#ifdef FM_NO_DISPATCH_RAM_ECC
67659 + if ((revInfo.majorRev != 4) &&
67660 + (revInfo.majorRev < 6))
67661 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
67662 +#endif /* FM_NO_DISPATCH_RAM_ECC */
67663 +
67664 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
67665 + if (revInfo.majorRev == 4)
67666 + p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
67667 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
67668 +
67669 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
67670 + if (revInfo.majorRev >= 6)
67671 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_QMI_SINGLE_ECC;
67672 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
67673 +
67674 + FmMuramClear(p_Fm->h_FmMuram);
67675 +
67676 + /* clear CPG */
67677 + IOMemSet32(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_CGP), 0, FM_PORT_NUM_OF_CONGESTION_GRPS);
67678 +
67679 + /* add to the default exceptions the user's definitions */
67680 + p_Fm->p_FmStateStruct->exceptions |= p_Fm->userSetExceptions;
67681 +
67682 + /* Reset the FM if required */
67683 + if (p_Fm->resetOnInit)
67684 + {
67685 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67686 + if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK)
67687 + RETURN_ERROR(MAJOR, err, NO_MSG);
67688 +#else /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67689 +
67690 + if (p_Fm->f_ResetOnInitOverride)
67691 + {
67692 + /* Perform user specific FMan reset */
67693 + p_Fm->f_ResetOnInitOverride(h_Fm);
67694 + }
67695 + else
67696 + {
67697 + /* Perform FMan reset */
67698 + FmReset(h_Fm);
67699 + }
67700 +
67701 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
67702 + {
67703 + fman_resume(p_Fm->p_FmFpmRegs);
67704 + XX_UDelay(100);
67705 + }
67706 +#endif /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67707 + }
67708 +
67709 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67710 + if (!p_Fm->resetOnInit) /* Skip operations done in errata workaround */
67711 + {
67712 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67713 + /* Load FMan-Controller code to IRAM */
67714 +
67715 + ClearIRam(p_Fm);
67716 +
67717 + if (p_Fm->firmware.p_Code && (LoadFmanCtrlCode(p_Fm) != E_OK))
67718 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
67719 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67720 + }
67721 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67722 +
67723 +#ifdef FM_CAPWAP_SUPPORT
67724 + /* save first 256 byte in MURAM */
67725 + p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
67726 + if (!p_Fm->resAddr)
67727 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
67728 +
67729 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
67730 +#endif /* FM_CAPWAP_SUPPORT */
67731 +
67732 +#if (DPAA_VERSION >= 11)
67733 + p_Fm->partVSPBase = AllocVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67734 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
67735 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
67736 +#endif /* (DPAA_VERSION >= 11) */
67737 +
67738 + /* General FM driver initialization */
67739 + p_Fm->fmMuramPhysBaseAddr =
67740 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
67741 +
67742 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
67743 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
67744 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
67745 + p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
67746 +
67747 + p_FmDriverParam->exceptions = p_Fm->p_FmStateStruct->exceptions;
67748 +
67749 + /**********************/
67750 + /* Init DMA Registers */
67751 + /**********************/
67752 + err = InitFmDma(p_Fm);
67753 + if (err != E_OK)
67754 + {
67755 + FreeInitResources(p_Fm);
67756 + RETURN_ERROR(MAJOR, err, NO_MSG);
67757 + }
67758 +
67759 + /**********************/
67760 + /* Init FPM Registers */
67761 + /**********************/
67762 + err = InitFmFpm(p_Fm);
67763 + if (err != E_OK)
67764 + {
67765 + FreeInitResources(p_Fm);
67766 + RETURN_ERROR(MAJOR, err, NO_MSG);
67767 + }
67768 +
67769 + /* define common resources */
67770 + /* allocate MURAM for FIFO according to total size */
67771 + p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67772 + p_Fm->p_FmStateStruct->totalFifoSize,
67773 + BMI_FIFO_ALIGN));
67774 + if (!p_Fm->fifoBaseAddr)
67775 + {
67776 + FreeInitResources(p_Fm);
67777 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for BMI FIFO failed"));
67778 + }
67779 +
67780 + p_FmDriverParam->fifo_base_addr = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
67781 + p_FmDriverParam->total_fifo_size = p_Fm->p_FmStateStruct->totalFifoSize;
67782 + p_FmDriverParam->total_num_of_tasks = p_Fm->p_FmStateStruct->totalNumOfTasks;
67783 + p_FmDriverParam->clk_freq = p_Fm->p_FmStateStruct->fmClkFreq;
67784 +
67785 + /**********************/
67786 + /* Init BMI Registers */
67787 + /**********************/
67788 + err = InitFmBmi(p_Fm);
67789 + if (err != E_OK)
67790 + {
67791 + FreeInitResources(p_Fm);
67792 + RETURN_ERROR(MAJOR, err, NO_MSG);
67793 + }
67794 +
67795 + /**********************/
67796 + /* Init QMI Registers */
67797 + /**********************/
67798 + err = InitFmQmi(p_Fm);
67799 + if (err != E_OK)
67800 + {
67801 + FreeInitResources(p_Fm);
67802 + RETURN_ERROR(MAJOR, err, NO_MSG);
67803 + }
67804 +
67805 + /* build the FM master partition IPC address */
67806 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
67807 + {
67808 + FreeInitResources(p_Fm);
67809 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67810 + }
67811 +
67812 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
67813 + if (err)
67814 + {
67815 + FreeInitResources(p_Fm);
67816 + RETURN_ERROR(MAJOR, err, NO_MSG);
67817 + }
67818 +
67819 + /* Register the FM interrupts handlers */
67820 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
67821 + {
67822 + XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
67823 + XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
67824 + }
67825 +
67826 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
67827 + {
67828 + XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, (void (*) (t_Handle))FM_ErrorIsr, p_Fm);
67829 + XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
67830 + }
67831 +
67832 + err = (t_Error)fman_enable(&fman_rg , p_FmDriverParam);
67833 + if (err != E_OK)
67834 + return err; /* FIXME */
67835 +
67836 + EnableTimeStamp(p_Fm);
67837 +
67838 + if (p_Fm->firmware.p_Code)
67839 + {
67840 + XX_Free(p_Fm->firmware.p_Code);
67841 + p_Fm->firmware.p_Code = NULL;
67842 + }
67843 +
67844 + XX_Free(p_Fm->p_FmDriverParam);
67845 + p_Fm->p_FmDriverParam = NULL;
67846 +
67847 + return E_OK;
67848 +}
67849 +
67850 +/**************************************************************************//**
67851 + @Function FM_Free
67852 +
67853 + @Description Frees all resources that were assigned to FM module.
67854 +
67855 + Calling this routine invalidates the descriptor.
67856 +
67857 + @Param[in] h_Fm - FM module descriptor
67858 +
67859 + @Return E_OK on success; Error code otherwise.
67860 +*//***************************************************************************/
67861 +t_Error FM_Free(t_Handle h_Fm)
67862 +{
67863 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67864 + struct fman_rg fman_rg;
67865 +
67866 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67867 +
67868 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
67869 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
67870 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
67871 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
67872 +
67873 + if (p_Fm->guestId != NCSW_MASTER_ID)
67874 + {
67875 +#if (DPAA_VERSION >= 11)
67876 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67877 +
67878 + if (p_Fm->p_FmSp)
67879 + {
67880 + XX_Free(p_Fm->p_FmSp);
67881 + p_Fm->p_FmSp = NULL;
67882 + }
67883 +#endif /* (DPAA_VERSION >= 11) */
67884 +
67885 + if (p_Fm->fmModuleName[0] != 0)
67886 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
67887 +
67888 + if (!p_Fm->recoveryMode)
67889 + XX_Free(p_Fm->p_FmStateStruct);
67890 +
67891 + XX_Free(p_Fm);
67892 +
67893 + return E_OK;
67894 + }
67895 +
67896 + fman_free_resources(&fman_rg);
67897 +
67898 + if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
67899 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
67900 +
67901 + if (p_Fm->p_FmStateStruct)
67902 + {
67903 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
67904 + {
67905 + XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
67906 + XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
67907 + }
67908 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
67909 + {
67910 + XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
67911 + XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
67912 + }
67913 + }
67914 +
67915 +#if (DPAA_VERSION >= 11)
67916 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67917 +
67918 + if (p_Fm->p_FmSp)
67919 + {
67920 + XX_Free(p_Fm->p_FmSp);
67921 + p_Fm->p_FmSp = NULL;
67922 + }
67923 +#endif /* (DPAA_VERSION >= 11) */
67924 +
67925 + if (p_Fm->h_Spinlock)
67926 + XX_FreeSpinlock(p_Fm->h_Spinlock);
67927 +
67928 + if (p_Fm->p_FmDriverParam)
67929 + {
67930 + if (p_Fm->firmware.p_Code)
67931 + XX_Free(p_Fm->firmware.p_Code);
67932 + XX_Free(p_Fm->p_FmDriverParam);
67933 + p_Fm->p_FmDriverParam = NULL;
67934 + }
67935 +
67936 + FreeInitResources(p_Fm);
67937 +
67938 + if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
67939 + XX_Free(p_Fm->p_FmStateStruct);
67940 +
67941 + XX_Free(p_Fm);
67942 +
67943 + return E_OK;
67944 +}
67945 +
67946 +/*************************************************/
67947 +/* API Advanced Init unit functions */
67948 +/*************************************************/
67949 +
67950 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
67951 +{
67952 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67953 +
67954 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67955 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67956 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67957 +
67958 + p_Fm->resetOnInit = enable;
67959 +
67960 + return E_OK;
67961 +}
67962 +
67963 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride)
67964 +{
67965 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67966 +
67967 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67968 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67969 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67970 +
67971 + p_Fm->f_ResetOnInitOverride = f_ResetOnInitOverride;
67972 +
67973 + return E_OK;
67974 +}
67975 +
67976 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
67977 +{
67978 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67979 +
67980 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67981 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67982 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67983 +
67984 + p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
67985 +
67986 + return E_OK;
67987 +}
67988 +
67989 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
67990 +{
67991 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67992 + enum fman_dma_cache_override fsl_cache_override;
67993 +
67994 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67995 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67996 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67997 +
67998 + FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, cacheOverride)
67999 + p_Fm->p_FmDriverParam->dma_cache_override = fsl_cache_override;
68000 +
68001 + return E_OK;
68002 +}
68003 +
68004 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
68005 +{
68006 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68007 +
68008 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68009 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68010 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68011 +
68012 + p_Fm->p_FmDriverParam->dma_aid_override = aidOverride;
68013 +
68014 + return E_OK;
68015 +}
68016 +
68017 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
68018 +{
68019 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68020 + enum fman_dma_aid_mode fsl_aid_mode;
68021 +
68022 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68023 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68024 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68025 +
68026 + FMAN_AID_MODE_TRANS(fsl_aid_mode, aidMode);
68027 + p_Fm->p_FmDriverParam->dma_aid_mode = fsl_aid_mode;
68028 +
68029 + return E_OK;
68030 +}
68031 +
68032 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
68033 +{
68034 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68035 +
68036 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68037 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68038 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68039 +
68040 +#if (DPAA_VERSION >= 11)
68041 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68042 +#else
68043 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = axiDbgNumOfBeats;
68044 +
68045 + return E_OK;
68046 +#endif /* (DPAA_VERSION >= 11) */
68047 +}
68048 +
68049 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
68050 +{
68051 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68052 +
68053 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68054 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68055 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68056 +
68057 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = numOfEntries;
68058 +
68059 + return E_OK;
68060 +}
68061 +
68062 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
68063 +{
68064 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68065 + enum fman_dma_dbg_cnt_mode fsl_dma_dbg_cnt;
68066 +
68067 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68068 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68069 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68070 +
68071 + FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, fmDmaDbgCntMode);
68072 + p_Fm->p_FmDriverParam->dma_dbg_cnt_mode = fsl_dma_dbg_cnt;
68073 +
68074 + return E_OK;
68075 +}
68076 +
68077 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
68078 +{
68079 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68080 +
68081 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68082 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68083 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68084 +
68085 + p_Fm->p_FmDriverParam->dma_stop_on_bus_error = stop;
68086 +
68087 + return E_OK;
68088 +}
68089 +
68090 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
68091 +{
68092 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68093 + enum fman_dma_emergency_level fsl_dma_emer;
68094 +
68095 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68096 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68097 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68098 +
68099 + FMAN_DMA_EMER_TRANS(fsl_dma_emer, p_Emergency->emergencyLevel);
68100 + p_Fm->p_FmDriverParam->dma_en_emergency = TRUE;
68101 + p_Fm->p_FmDriverParam->dma_emergency_bus_select = (uint32_t)p_Emergency->emergencyBusSelect;
68102 + p_Fm->p_FmDriverParam->dma_emergency_level = fsl_dma_emer;
68103 +
68104 + return E_OK;
68105 +}
68106 +
68107 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
68108 +{
68109 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68110 +
68111 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68112 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68113 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68114 +
68115 + p_Fm->p_FmDriverParam->dma_en_emergency_smoother = TRUE;
68116 + p_Fm->p_FmDriverParam->dma_emergency_switch_counter = emergencyCnt;
68117 +
68118 + return E_OK;
68119 +}
68120 +
68121 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
68122 +{
68123 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68124 + enum fman_dma_err fsl_dma_err;
68125 +
68126 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68127 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68128 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68129 +
68130 + FMAN_DMA_ERR_TRANS(fsl_dma_err, dmaErr);
68131 + p_Fm->p_FmDriverParam->dma_err = fsl_dma_err;
68132 +
68133 + return E_OK;
68134 +}
68135 +
68136 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
68137 +{
68138 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68139 + enum fman_catastrophic_err fsl_catastrophic_err;
68140 +
68141 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68142 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68143 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68144 +
68145 + FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, catastrophicErr);
68146 + p_Fm->p_FmDriverParam->catastrophic_err = fsl_catastrophic_err;
68147 +
68148 + return E_OK;
68149 +}
68150 +
68151 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
68152 +{
68153 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68154 +
68155 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68156 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68157 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68158 +
68159 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68160 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68161 +
68162 + p_Fm->p_FmDriverParam->en_muram_test_mode = TRUE;
68163 +
68164 + return E_OK;
68165 +}
68166 +
68167 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
68168 +{
68169 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68170 +
68171 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE );
68172 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68173 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68174 +
68175 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68176 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68177 +
68178 + p_Fm->p_FmDriverParam->en_iram_test_mode = TRUE;
68179 +
68180 + return E_OK;
68181 +}
68182 +
68183 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
68184 +{
68185 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68186 +
68187 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68188 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68189 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68190 +
68191 + p_Fm->p_FmDriverParam->halt_on_external_activ = enable;
68192 +
68193 + return E_OK;
68194 +}
68195 +
68196 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable)
68197 +{
68198 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68199 +
68200 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68201 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68202 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68203 +
68204 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68205 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68206 +
68207 + p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err = enable;
68208 +
68209 + return E_OK;
68210 +}
68211 +
68212 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
68213 +{
68214 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68215 + uint32_t bitMask = 0;
68216 +
68217 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68218 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68219 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68220 +
68221 + GET_EXCEPTION_FLAG(bitMask, exception);
68222 + if (bitMask)
68223 + {
68224 + if (enable)
68225 + p_Fm->userSetExceptions |= bitMask;
68226 + else
68227 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
68228 + }
68229 + else
68230 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
68231 +
68232 + return E_OK;
68233 +}
68234 +
68235 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
68236 +{
68237 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68238 +
68239 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68240 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68241 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68242 +
68243 + p_Fm->p_FmDriverParam->external_ecc_rams_enable = enable;
68244 +
68245 + return E_OK;
68246 +}
68247 +
68248 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
68249 +{
68250 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68251 +
68252 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68253 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68254 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68255 +
68256 + p_Fm->p_FmDriverParam->tnum_aging_period = tnumAgingPeriod;
68257 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
68258 +
68259 + return E_OK;
68260 +}
68261 +
68262 +/****************************************************/
68263 +/* Hidden-DEBUG Only API */
68264 +/****************************************************/
68265 +
68266 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
68267 +{
68268 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68269 +
68270 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68271 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68272 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68273 +
68274 + p_Fm->p_FmDriverParam->disp_limit_tsh = p_FmThresholds->dispLimit;
68275 + p_Fm->p_FmDriverParam->prs_disp_tsh = p_FmThresholds->prsDispTh;
68276 + p_Fm->p_FmDriverParam->plcr_disp_tsh = p_FmThresholds->plcrDispTh;
68277 + p_Fm->p_FmDriverParam->kg_disp_tsh = p_FmThresholds->kgDispTh;
68278 + p_Fm->p_FmDriverParam->bmi_disp_tsh = p_FmThresholds->bmiDispTh;
68279 + p_Fm->p_FmDriverParam->qmi_enq_disp_tsh = p_FmThresholds->qmiEnqDispTh;
68280 + p_Fm->p_FmDriverParam->qmi_deq_disp_tsh = p_FmThresholds->qmiDeqDispTh;
68281 + p_Fm->p_FmDriverParam->fm_ctl1_disp_tsh = p_FmThresholds->fmCtl1DispTh;
68282 + p_Fm->p_FmDriverParam->fm_ctl2_disp_tsh = p_FmThresholds->fmCtl2DispTh;
68283 +
68284 + return E_OK;
68285 +}
68286 +
68287 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
68288 +{
68289 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68290 +
68291 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68292 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68293 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68294 +
68295 + p_Fm->p_FmDriverParam->dma_sos_emergency = dmaSosEmergency;
68296 +
68297 + return E_OK;
68298 +}
68299 +
68300 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68301 +
68302 +{
68303 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68304 +
68305 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68306 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68307 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68308 +
68309 +#if (DPAA_VERSION >= 11)
68310 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68311 +#else
68312 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68313 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68314 +
68315 + return E_OK;
68316 +#endif
68317 +}
68318 +
68319 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68320 +{
68321 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68322 +
68323 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68324 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68325 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68326 +
68327 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68328 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68329 +
68330 + return E_OK;
68331 +}
68332 +
68333 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68334 +{
68335 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68336 +
68337 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68338 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68339 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68340 +
68341 +#if (DPAA_VERSION >= 11)
68342 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68343 +#else
68344 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68345 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68346 +
68347 + return E_OK;
68348 +#endif
68349 +}
68350 +
68351 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
68352 +{
68353 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68354 +
68355 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68356 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68357 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68358 +
68359 + p_Fm->p_FmDriverParam->dma_watchdog = watchdogValue;
68360 +
68361 + return E_OK;
68362 +}
68363 +
68364 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
68365 +{
68366 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68367 +
68368 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68369 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68370 +UNUSED(p_Fm);
68371 +
68372 + return E_OK;
68373 +}
68374 +
68375 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
68376 +{
68377 + t_Fm* p_Fm = (t_Fm*)h_Fm;
68378 + if (p_Params->setParams.type & UPDATE_FM_CLD)
68379 + {
68380 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32(
68381 + p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800);
68382 + }
68383 + if (p_Params->setParams.type & CLEAR_IRAM_READY)
68384 + {
68385 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
68386 + WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY);
68387 + }
68388 + if (p_Params->setParams.type & UPDATE_FPM_EXTC)
68389 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000);
68390 + if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR)
68391 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x00800000);
68392 + if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP)
68393 + {
68394 + if (p_Params->setParams.sleep)
68395 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68396 + p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP);
68397 + else
68398 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68399 + p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP);
68400 + }
68401 + if (p_Params->getParams.type & GET_FM_CLD)
68402 + p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld);
68403 + if (p_Params->getParams.type & GET_FMQM_GS)
68404 + p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs);
68405 + if (p_Params->getParams.type & GET_FM_NPI)
68406 + p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi);
68407 + if (p_Params->getParams.type & GET_FMFP_EXTC)
68408 + p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc);
68409 + return E_OK;
68410 +}
68411 +
68412 +
68413 +/****************************************************/
68414 +/* API Run-time Control uint functions */
68415 +/****************************************************/
68416 +void FM_EventIsr(t_Handle h_Fm)
68417 +{
68418 +#define FM_M_CALL_1G_MAC_ISR(_id) \
68419 + { \
68420 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].guestId) \
68421 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id), pending); \
68422 + else \
68423 + 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);\
68424 + }
68425 +#define FM_M_CALL_10G_MAC_ISR(_id) \
68426 + { \
68427 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].guestId) \
68428 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id), pending); \
68429 + else \
68430 + 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);\
68431 + }
68432 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68433 + uint32_t pending, event;
68434 + struct fman_fpm_regs *fpm_rg;
68435 +
68436 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
68437 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68438 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68439 +
68440 + fpm_rg = p_Fm->p_FmFpmRegs;
68441 +
68442 + /* normal interrupts */
68443 + pending = fman_get_normal_pending(fpm_rg);
68444 + if (!pending)
68445 + return;
68446 + if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt
68447 + {
68448 + t_FmGetSetParams fmGetSetParams;
68449 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
68450 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
68451 + fmGetSetParams.setParams.sleep = 0;
68452 + FmGetSetParams(h_Fm, &fmGetSetParams);
68453 + }
68454 + if (pending & INTR_EN_QMI)
68455 + QmiEvent(p_Fm);
68456 + if (pending & INTR_EN_PRS)
68457 + p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
68458 + if (pending & INTR_EN_PLCR)
68459 + p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
68460 + if (pending & INTR_EN_TMR)
68461 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
68462 +
68463 + /* MAC events may belong to different partitions */
68464 + if (pending & INTR_EN_1G_MAC0)
68465 + FM_M_CALL_1G_MAC_ISR(0);
68466 + if (pending & INTR_EN_1G_MAC1)
68467 + FM_M_CALL_1G_MAC_ISR(1);
68468 + if (pending & INTR_EN_1G_MAC2)
68469 + FM_M_CALL_1G_MAC_ISR(2);
68470 + if (pending & INTR_EN_1G_MAC3)
68471 + FM_M_CALL_1G_MAC_ISR(3);
68472 + if (pending & INTR_EN_1G_MAC4)
68473 + FM_M_CALL_1G_MAC_ISR(4);
68474 + if (pending & INTR_EN_1G_MAC5)
68475 + FM_M_CALL_1G_MAC_ISR(5);
68476 + if (pending & INTR_EN_1G_MAC6)
68477 + FM_M_CALL_1G_MAC_ISR(6);
68478 + if (pending & INTR_EN_1G_MAC7)
68479 + FM_M_CALL_1G_MAC_ISR(7);
68480 + if (pending & INTR_EN_10G_MAC0)
68481 + FM_M_CALL_10G_MAC_ISR(0);
68482 + if (pending & INTR_EN_10G_MAC1)
68483 + FM_M_CALL_10G_MAC_ISR(1);
68484 +
68485 + /* IM port events may belong to different partitions */
68486 + if (pending & INTR_EN_REV0)
68487 + {
68488 + event = fman_get_controller_event(fpm_rg, 0);
68489 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
68490 + /*TODO IPC ISR For Fman Ctrl */
68491 + ASSERT_COND(0);
68492 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
68493 + else
68494 + p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
68495 +
68496 + }
68497 + if (pending & INTR_EN_REV1)
68498 + {
68499 + event = fman_get_controller_event(fpm_rg, 1);
68500 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
68501 + /*TODO IPC ISR For Fman Ctrl */
68502 + ASSERT_COND(0);
68503 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
68504 + else
68505 + p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
68506 + }
68507 + if (pending & INTR_EN_REV2)
68508 + {
68509 + event = fman_get_controller_event(fpm_rg, 2);
68510 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
68511 + /*TODO IPC ISR For Fman Ctrl */
68512 + ASSERT_COND(0);
68513 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
68514 + else
68515 + p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
68516 + }
68517 + if (pending & INTR_EN_REV3)
68518 + {
68519 + event = fman_get_controller_event(fpm_rg, 3);
68520 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
68521 + /*TODO IPC ISR For Fman Ctrl */
68522 + ASSERT_COND(0);
68523 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
68524 + else
68525 + p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
68526 + }
68527 +#ifdef FM_MACSEC_SUPPORT
68528 + if (pending & INTR_EN_MACSEC_MAC0)
68529 + {
68530 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].guestId)
68531 + SendIpcIsr(p_Fm, e_FM_EV_MACSEC_MAC0, pending);
68532 + else
68533 + p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].h_SrcHandle);
68534 + }
68535 +#endif /* FM_MACSEC_SUPPORT */
68536 +}
68537 +
68538 +t_Error FM_ErrorIsr(t_Handle h_Fm)
68539 +{
68540 +#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \
68541 + { \
68542 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
68543 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \
68544 + else \
68545 + 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);\
68546 + }
68547 +#define FM_M_CALL_10G_MAC_ERR_ISR(_id) \
68548 + { \
68549 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].guestId) \
68550 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id), pending); \
68551 + else \
68552 + 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);\
68553 + }
68554 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68555 + uint32_t pending;
68556 + struct fman_fpm_regs *fpm_rg;
68557 +
68558 + SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
68559 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68560 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68561 +
68562 + fpm_rg = p_Fm->p_FmFpmRegs;
68563 +
68564 + /* error interrupts */
68565 + pending = fman_get_fpm_error_interrupts(fpm_rg);
68566 + if (!pending)
68567 + return ERROR_CODE(E_EMPTY);
68568 +
68569 + if (pending & ERR_INTR_EN_BMI)
68570 + BmiErrEvent(p_Fm);
68571 + if (pending & ERR_INTR_EN_QMI)
68572 + QmiErrEvent(p_Fm);
68573 + if (pending & ERR_INTR_EN_FPM)
68574 + FpmErrEvent(p_Fm);
68575 + if (pending & ERR_INTR_EN_DMA)
68576 + DmaErrEvent(p_Fm);
68577 + if (pending & ERR_INTR_EN_IRAM)
68578 + IramErrIntr(p_Fm);
68579 + if (pending & ERR_INTR_EN_MURAM)
68580 + MuramErrIntr(p_Fm);
68581 + if (pending & ERR_INTR_EN_PRS)
68582 + p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
68583 + if (pending & ERR_INTR_EN_PLCR)
68584 + p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
68585 + if (pending & ERR_INTR_EN_KG)
68586 + p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
68587 +
68588 + /* MAC events may belong to different partitions */
68589 + if (pending & ERR_INTR_EN_1G_MAC0)
68590 + FM_M_CALL_1G_MAC_ERR_ISR(0);
68591 + if (pending & ERR_INTR_EN_1G_MAC1)
68592 + FM_M_CALL_1G_MAC_ERR_ISR(1);
68593 + if (pending & ERR_INTR_EN_1G_MAC2)
68594 + FM_M_CALL_1G_MAC_ERR_ISR(2);
68595 + if (pending & ERR_INTR_EN_1G_MAC3)
68596 + FM_M_CALL_1G_MAC_ERR_ISR(3);
68597 + if (pending & ERR_INTR_EN_1G_MAC4)
68598 + FM_M_CALL_1G_MAC_ERR_ISR(4);
68599 + if (pending & ERR_INTR_EN_1G_MAC5)
68600 + FM_M_CALL_1G_MAC_ERR_ISR(5);
68601 + if (pending & ERR_INTR_EN_1G_MAC6)
68602 + FM_M_CALL_1G_MAC_ERR_ISR(6);
68603 + if (pending & ERR_INTR_EN_1G_MAC7)
68604 + FM_M_CALL_1G_MAC_ERR_ISR(7);
68605 + if (pending & ERR_INTR_EN_10G_MAC0)
68606 + FM_M_CALL_10G_MAC_ERR_ISR(0);
68607 + if (pending & ERR_INTR_EN_10G_MAC1)
68608 + FM_M_CALL_10G_MAC_ERR_ISR(1);
68609 +
68610 +#ifdef FM_MACSEC_SUPPORT
68611 + if (pending & ERR_INTR_EN_MACSEC_MAC0)
68612 + {
68613 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].guestId)
68614 + SendIpcIsr(p_Fm, e_FM_EV_ERR_MACSEC_MAC0, pending);
68615 + else
68616 + p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].h_SrcHandle);
68617 + }
68618 +#endif /* FM_MACSEC_SUPPORT */
68619 +
68620 + return E_OK;
68621 +}
68622 +
68623 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
68624 +{
68625 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68626 + int i;
68627 + uint8_t sum;
68628 + uint8_t hardwarePortId;
68629 + uint8_t weights[64];
68630 + uint8_t weight, maxPercent = 0;
68631 + struct fman_bmi_regs *bmi_rg;
68632 +
68633 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68634 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68635 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68636 +
68637 + bmi_rg = p_Fm->p_FmBmiRegs;
68638 +
68639 + memset(weights, 0, (sizeof(uint8_t) * 64));
68640 +
68641 + /* check that all ports add up to 100% */
68642 + sum = 0;
68643 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68644 + sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
68645 + if (sum != 100)
68646 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
68647 +
68648 + /* find highest percent */
68649 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68650 + {
68651 + if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
68652 + maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
68653 + }
68654 +
68655 + ASSERT_COND(maxPercent > 0); /* guaranteed by sum = 100 */
68656 +
68657 + /* calculate weight for each port */
68658 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68659 + {
68660 + weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) / maxPercent);
68661 + /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exact division
68662 + is not reached, we round up so that:
68663 + 0 until maxPercent/PORT_MAX_WEIGHT get "1"
68664 + maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
68665 + ...
68666 + maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
68667 + if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
68668 + weight++;
68669 +
68670 + /* find the location of this port within the register */
68671 + hardwarePortId =
68672 + SwPortIdToHwPortId(p_PortsBandwidth->portsBandwidths[i].type,
68673 + p_PortsBandwidth->portsBandwidths[i].relativePortId,
68674 + p_Fm->p_FmStateStruct->revInfo.majorRev,
68675 + p_Fm->p_FmStateStruct->revInfo.minorRev);
68676 +
68677 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68678 + weights[hardwarePortId] = weight;
68679 + }
68680 +
68681 + fman_set_ports_bandwidth(bmi_rg, weights);
68682 +
68683 + return E_OK;
68684 +}
68685 +
68686 +t_Error FM_EnableRamsEcc(t_Handle h_Fm)
68687 +{
68688 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68689 + struct fman_fpm_regs *fpm_rg;
68690 +
68691 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68692 +
68693 + fpm_rg = p_Fm->p_FmFpmRegs;
68694 +
68695 + if (p_Fm->guestId != NCSW_MASTER_ID)
68696 + {
68697 + t_FmIpcMsg msg;
68698 + t_Error err;
68699 +
68700 + memset(&msg, 0, sizeof(msg));
68701 + msg.msgId = FM_ENABLE_RAM_ECC;
68702 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68703 + (uint8_t*)&msg,
68704 + sizeof(msg.msgId),
68705 + NULL,
68706 + NULL,
68707 + NULL,
68708 + NULL);
68709 + if (err != E_OK)
68710 + RETURN_ERROR(MINOR, err, NO_MSG);
68711 + return E_OK;
68712 + }
68713 +
68714 + if (!p_Fm->p_FmStateStruct->internalCall)
68715 + p_Fm->p_FmStateStruct->explicitEnable = TRUE;
68716 + p_Fm->p_FmStateStruct->internalCall = FALSE;
68717 +
68718 + if (p_Fm->p_FmStateStruct->ramsEccEnable)
68719 + return E_OK;
68720 + else
68721 + {
68722 + fman_enable_rams_ecc(fpm_rg);
68723 + p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
68724 + }
68725 +
68726 + return E_OK;
68727 +}
68728 +
68729 +t_Error FM_DisableRamsEcc(t_Handle h_Fm)
68730 +{
68731 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68732 + bool explicitDisable = FALSE;
68733 + struct fman_fpm_regs *fpm_rg;
68734 +
68735 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68736 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68737 +
68738 + fpm_rg = p_Fm->p_FmFpmRegs;
68739 +
68740 + if (p_Fm->guestId != NCSW_MASTER_ID)
68741 + {
68742 + t_Error err;
68743 + t_FmIpcMsg msg;
68744 +
68745 + memset(&msg, 0, sizeof(msg));
68746 + msg.msgId = FM_DISABLE_RAM_ECC;
68747 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68748 + (uint8_t*)&msg,
68749 + sizeof(msg.msgId),
68750 + NULL,
68751 + NULL,
68752 + NULL,
68753 + NULL)) != E_OK)
68754 + RETURN_ERROR(MINOR, err, NO_MSG);
68755 + return E_OK;
68756 + }
68757 +
68758 + if (!p_Fm->p_FmStateStruct->internalCall)
68759 + explicitDisable = TRUE;
68760 + p_Fm->p_FmStateStruct->internalCall = FALSE;
68761 +
68762 + /* if rams are already disabled, or if rams were explicitly enabled and are
68763 + currently called indirectly (not explicitly), ignore this call. */
68764 + if (!p_Fm->p_FmStateStruct->ramsEccEnable ||
68765 + (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
68766 + return E_OK;
68767 + else
68768 + {
68769 + if (p_Fm->p_FmStateStruct->explicitEnable)
68770 + /* This is the case were both explicit are TRUE.
68771 + Turn off this flag for cases were following ramsEnable
68772 + routines are called */
68773 + p_Fm->p_FmStateStruct->explicitEnable = FALSE;
68774 +
68775 + fman_enable_rams_ecc(fpm_rg);
68776 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
68777 + }
68778 +
68779 + return E_OK;
68780 +}
68781 +
68782 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
68783 +{
68784 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68785 + uint32_t bitMask = 0;
68786 + enum fman_exceptions fslException;
68787 + struct fman_rg fman_rg;
68788 +
68789 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68790 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68791 +
68792 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68793 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68794 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68795 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68796 +
68797 + GET_EXCEPTION_FLAG(bitMask, exception);
68798 + if (bitMask)
68799 + {
68800 + if (enable)
68801 + p_Fm->p_FmStateStruct->exceptions |= bitMask;
68802 + else
68803 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
68804 +
68805 + fslException = FmanExceptionTrans(exception);
68806 +
68807 + return (t_Error)fman_set_exception(&fman_rg,
68808 + fslException,
68809 + enable);
68810 + }
68811 + else
68812 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
68813 +
68814 + return E_OK;
68815 +}
68816 +
68817 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
68818 +{
68819 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68820 +
68821 + p_FmRevisionInfo->majorRev = p_Fm->p_FmStateStruct->revInfo.majorRev;
68822 + p_FmRevisionInfo->minorRev = p_Fm->p_FmStateStruct->revInfo.minorRev;
68823 +
68824 + return E_OK;
68825 +}
68826 +
68827 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo)
68828 +{
68829 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68830 + t_FMIramRegs *p_Iram;
68831 + uint32_t revInfo;
68832 +
68833 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68834 + SANITY_CHECK_RETURN_ERROR(p_RevisionInfo, E_NULL_POINTER);
68835 +
68836 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68837 + p_Fm->h_IpcSessions[0])
68838 + {
68839 + t_Error err;
68840 + t_FmIpcMsg msg;
68841 + t_FmIpcReply reply;
68842 + uint32_t replyLength;
68843 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
68844 +
68845 + memset(&msg, 0, sizeof(msg));
68846 + memset(&reply, 0, sizeof(reply));
68847 + msg.msgId = FM_GET_FMAN_CTRL_CODE_REV;
68848 + replyLength = sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo);
68849 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68850 + (uint8_t*)&msg,
68851 + sizeof(msg.msgId),
68852 + (uint8_t*)&reply,
68853 + &replyLength,
68854 + NULL,
68855 + NULL)) != E_OK)
68856 + RETURN_ERROR(MINOR, err, NO_MSG);
68857 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo)))
68858 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68859 + memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmCtrlCodeRevisionInfo));
68860 + p_RevisionInfo->packageRev = ipcRevInfo.packageRev;
68861 + p_RevisionInfo->majorRev = ipcRevInfo.majorRev;
68862 + p_RevisionInfo->minorRev = ipcRevInfo.minorRev;
68863 + return (t_Error)(reply.error);
68864 + }
68865 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68866 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68867 + ("running in guest-mode without IPC!"));
68868 +
68869 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
68870 + WRITE_UINT32(p_Iram->iadd, 0x4);
68871 + while (GET_UINT32(p_Iram->iadd) != 0x4) ;
68872 + revInfo = GET_UINT32(p_Iram->idata);
68873 + p_RevisionInfo->packageRev = (uint16_t)((revInfo & 0xFFFF0000) >> 16);
68874 + p_RevisionInfo->majorRev = (uint8_t)((revInfo & 0x0000FF00) >> 8);
68875 + p_RevisionInfo->minorRev = (uint8_t)(revInfo & 0x000000FF);
68876 +
68877 + return E_OK;
68878 +}
68879 +
68880 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
68881 +{
68882 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68883 + t_Error err;
68884 + uint32_t counterValue;
68885 + struct fman_rg fman_rg;
68886 + enum fman_counters fsl_counter;
68887 +
68888 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
68889 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
68890 +
68891 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68892 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68893 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68894 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68895 +
68896 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68897 + !p_Fm->baseAddr &&
68898 + p_Fm->h_IpcSessions[0])
68899 + {
68900 + t_FmIpcMsg msg;
68901 + t_FmIpcReply reply;
68902 + uint32_t replyLength, outCounter;
68903 +
68904 + memset(&msg, 0, sizeof(msg));
68905 + memset(&reply, 0, sizeof(reply));
68906 + msg.msgId = FM_GET_COUNTER;
68907 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
68908 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
68909 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68910 + (uint8_t*)&msg,
68911 + sizeof(msg.msgId) +sizeof(counterValue),
68912 + (uint8_t*)&reply,
68913 + &replyLength,
68914 + NULL,
68915 + NULL);
68916 + if (err != E_OK)
68917 + {
68918 + REPORT_ERROR(MAJOR, err, NO_MSG);
68919 + return 0;
68920 + }
68921 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
68922 + {
68923 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68924 + return 0;
68925 + }
68926 +
68927 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
68928 + return outCounter;
68929 + }
68930 + else if (!p_Fm->baseAddr)
68931 + {
68932 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Either IPC or 'baseAddress' is required!"));
68933 + return 0;
68934 + }
68935 +
68936 + /* When applicable (when there is an 'enable counters' bit,
68937 + check that counters are enabled */
68938 + switch (counter)
68939 + {
68940 + case (e_FM_COUNTERS_DEQ_1):
68941 + case (e_FM_COUNTERS_DEQ_2):
68942 + case (e_FM_COUNTERS_DEQ_3):
68943 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) ||
68944 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
68945 + {
68946 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported"));
68947 + return 0;
68948 + }
68949 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
68950 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
68951 + case (e_FM_COUNTERS_DEQ_0):
68952 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
68953 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
68954 + case (e_FM_COUNTERS_DEQ_FROM_FD):
68955 + case (e_FM_COUNTERS_DEQ_CONFIRM):
68956 + if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
68957 + {
68958 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Requested counter was not enabled"));
68959 + return 0;
68960 + }
68961 + break;
68962 + default:
68963 + break;
68964 + }
68965 +
68966 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
68967 + return fman_get_counter(&fman_rg, fsl_counter);
68968 +}
68969 +
68970 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
68971 +{
68972 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68973 + struct fman_rg fman_rg;
68974 + enum fman_counters fsl_counter;
68975 +
68976 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68977 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68978 +
68979 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68980 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68981 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68982 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68983 +
68984 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
68985 + return (t_Error)fman_modify_counter(&fman_rg, fsl_counter, val);
68986 +}
68987 +
68988 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
68989 +{
68990 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68991 + struct fman_dma_regs *dma_rg;
68992 +
68993 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
68994 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68995 +
68996 + dma_rg = p_Fm->p_FmDmaRegs;
68997 +
68998 + fman_set_dma_emergency(dma_rg, !!(muramPort==e_FM_DMA_MURAM_PORT_WRITE), enable);
68999 +}
69000 +
69001 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
69002 +{
69003 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69004 + struct fman_dma_regs *dma_rg;
69005 +
69006 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69007 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69008 +
69009 + dma_rg = p_Fm->p_FmDmaRegs;
69010 +
69011 + fman_set_dma_ext_bus_pri(dma_rg, pri);
69012 +}
69013 +
69014 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
69015 +{
69016 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69017 + uint32_t dmaStatus;
69018 + struct fman_dma_regs *dma_rg;
69019 +
69020 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69021 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69022 +
69023 + dma_rg = p_Fm->p_FmDmaRegs;
69024 +
69025 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
69026 + !p_Fm->baseAddr &&
69027 + p_Fm->h_IpcSessions[0])
69028 + {
69029 + t_FmIpcDmaStatus ipcDmaStatus;
69030 + t_FmIpcMsg msg;
69031 + t_FmIpcReply reply;
69032 + t_Error err;
69033 + uint32_t replyLength;
69034 +
69035 + memset(&msg, 0, sizeof(msg));
69036 + memset(&reply, 0, sizeof(reply));
69037 + msg.msgId = FM_DMA_STAT;
69038 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
69039 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69040 + (uint8_t*)&msg,
69041 + sizeof(msg.msgId),
69042 + (uint8_t*)&reply,
69043 + &replyLength,
69044 + NULL,
69045 + NULL);
69046 + if (err != E_OK)
69047 + {
69048 + REPORT_ERROR(MINOR, err, NO_MSG);
69049 + return;
69050 + }
69051 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
69052 + {
69053 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69054 + return;
69055 + }
69056 + memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
69057 +
69058 + p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */
69059 + p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */
69060 + p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */
69061 + p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
69062 + p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
69063 + p_FmDmaStatus->singlePortEccError = (bool)ipcDmaStatus.boolSinglePortEccError; /**< Double ECC error on buffer write from FM side */
69064 + return;
69065 + }
69066 + else if (!p_Fm->baseAddr)
69067 + {
69068 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
69069 + ("Either IPC or 'baseAddress' is required!"));
69070 + return;
69071 + }
69072 +
69073 + dmaStatus = fman_get_dma_status(dma_rg);
69074 +
69075 + p_FmDmaStatus->cmqNotEmpty = (bool)(dmaStatus & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
69076 + p_FmDmaStatus->busError = (bool)(dmaStatus & DMA_STATUS_BUS_ERR);
69077 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69078 + p_FmDmaStatus->singlePortEccError = (bool)(dmaStatus & DMA_STATUS_FM_SPDAT_ECC);
69079 + else
69080 + {
69081 + p_FmDmaStatus->readBufEccError = (bool)(dmaStatus & DMA_STATUS_READ_ECC);
69082 + p_FmDmaStatus->writeBufEccSysError = (bool)(dmaStatus & DMA_STATUS_SYSTEM_WRITE_ECC);
69083 + p_FmDmaStatus->writeBufEccFmError = (bool)(dmaStatus & DMA_STATUS_FM_WRITE_ECC);
69084 + }
69085 +}
69086 +
69087 +void FM_Resume(t_Handle h_Fm)
69088 +{
69089 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69090 + struct fman_fpm_regs *fpm_rg;
69091 +
69092 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69093 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69094 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69095 +
69096 + fpm_rg = p_Fm->p_FmFpmRegs;
69097 +
69098 + fman_resume(fpm_rg);
69099 +}
69100 +
69101 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
69102 + fmSpecialOperations_t spOper,
69103 + uint8_t *p_SpOperCoding)
69104 +{
69105 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69106 + t_FmCtrlCodeRevisionInfo revInfo;
69107 + t_Error err;
69108 +
69109 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69110 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69111 + SANITY_CHECK_RETURN_ERROR(p_SpOperCoding, E_NULL_POINTER);
69112 +
69113 + if (!spOper)
69114 + {
69115 + *p_SpOperCoding = 0;
69116 + return E_OK;
69117 + }
69118 +
69119 + if ((err = FM_GetFmanCtrlCodeRevision(p_Fm, &revInfo)) != E_OK)
69120 + {
69121 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
69122 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
69123 + }
69124 + else if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
69125 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
69126 +
69127 + switch (spOper)
69128 + {
69129 + case (FM_SP_OP_CAPWAP_DTLS_DEC):
69130 + *p_SpOperCoding = 9;
69131 + break;
69132 + case (FM_SP_OP_CAPWAP_DTLS_ENC):
69133 + *p_SpOperCoding = 10;
69134 + break;
69135 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP):
69136 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69137 + *p_SpOperCoding = 5;
69138 + break;
69139 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP):
69140 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69141 + *p_SpOperCoding = 6;
69142 + break;
69143 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_RPD):
69144 + *p_SpOperCoding = 3;
69145 + break;
69146 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN):
69147 + *p_SpOperCoding = 1;
69148 + break;
69149 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_NO_ETH_HDR):
69150 + *p_SpOperCoding = 12;
69151 + break;
69152 + case (FM_SP_OP_IPSEC|FM_SP_OP_RPD):
69153 + *p_SpOperCoding = 4;
69154 + break;
69155 + case (FM_SP_OP_IPSEC):
69156 + *p_SpOperCoding = 2;
69157 + break;
69158 + case (FM_SP_OP_DCL4C):
69159 + *p_SpOperCoding = 7;
69160 + break;
69161 + case (FM_SP_OP_CLEAR_RPD):
69162 + *p_SpOperCoding = 8;
69163 + break;
69164 + default:
69165 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
69166 + }
69167 +
69168 + return E_OK;
69169 +}
69170 +
69171 +t_Error FM_CtrlMonStart(t_Handle h_Fm)
69172 +{
69173 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69174 + t_FmTrbRegs *p_MonRegs;
69175 + uint8_t i;
69176 +
69177 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69178 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69179 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69180 +
69181 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69182 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_RDBG);
69183 +
69184 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69185 + {
69186 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69187 +
69188 + /* Reset control registers */
69189 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_RESET);
69190 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET);
69191 +
69192 + /* Configure: counter #1 counts all stalls in risc - ldsched stall
69193 + counter #2 counts all stalls in risc - other stall*/
69194 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET | TRB_TCRL_UTIL);
69195 +
69196 + /* Enable monitoring */
69197 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_ENABLE_COUNTERS);
69198 + }
69199 +
69200 + return E_OK;
69201 +}
69202 +
69203 +t_Error FM_CtrlMonStop(t_Handle h_Fm)
69204 +{
69205 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69206 + t_FmTrbRegs *p_MonRegs;
69207 + uint8_t i;
69208 +
69209 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69210 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69211 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69212 +
69213 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69214 + {
69215 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69216 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_DISABLE_COUNTERS);
69217 + }
69218 +
69219 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69220 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_RDBG);
69221 +
69222 + return E_OK;
69223 +}
69224 +
69225 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon)
69226 +{
69227 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69228 + t_FmTrbRegs *p_MonRegs;
69229 + uint64_t clkCnt, utilValue, effValue;
69230 +
69231 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69232 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69233 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69234 + SANITY_CHECK_RETURN_ERROR(p_Mon, E_NULL_POINTER);
69235 +
69236 + if (fmCtrlIndex >= FM_NUM_OF_CTRL)
69237 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM Controller index"));
69238 +
69239 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(fmCtrlIndex));
69240 +
69241 + clkCnt = (uint64_t)
69242 + ((uint64_t)GET_UINT32(p_MonRegs->tpcch) << 32 | GET_UINT32(p_MonRegs->tpccl));
69243 +
69244 + utilValue = (uint64_t)
69245 + ((uint64_t)GET_UINT32(p_MonRegs->tpc1h) << 32 | GET_UINT32(p_MonRegs->tpc1l));
69246 +
69247 + effValue = (uint64_t)
69248 + ((uint64_t)GET_UINT32(p_MonRegs->tpc2h) << 32 | GET_UINT32(p_MonRegs->tpc2l));
69249 +
69250 + p_Mon->percentCnt[0] = (uint8_t)div64_u64((clkCnt - utilValue) * 100, clkCnt);
69251 + if (clkCnt != utilValue)
69252 + p_Mon->percentCnt[1] = (uint8_t)div64_u64(((clkCnt - utilValue) - effValue) * 100, clkCnt - utilValue);
69253 + else
69254 + p_Mon->percentCnt[1] = 0;
69255 +
69256 + return E_OK;
69257 +}
69258 +
69259 +t_Handle FM_GetMuramHandle(t_Handle h_Fm)
69260 +{
69261 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69262 +
69263 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
69264 +
69265 + return (p_Fm->h_FmMuram);
69266 +}
69267 +
69268 +/****************************************************/
69269 +/* Hidden-DEBUG Only API */
69270 +/****************************************************/
69271 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
69272 +{
69273 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69274 + enum fman_exceptions fslException;
69275 + struct fman_rg fman_rg;
69276 +
69277 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69278 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69279 +
69280 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69281 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69282 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69283 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69284 +
69285 + switch (exception)
69286 + {
69287 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
69288 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
69289 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69290 + break;
69291 + case e_FM_EX_QMI_SINGLE_ECC:
69292 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69293 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC not supported on this integration."));
69294 +
69295 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
69296 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69297 + break;
69298 + case e_FM_EX_QMI_DOUBLE_ECC:
69299 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
69300 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69301 + break;
69302 + case e_FM_EX_BMI_LIST_RAM_ECC:
69303 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
69304 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69305 + break;
69306 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
69307 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC))
69308 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69309 + break;
69310 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
69311 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
69312 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69313 + break;
69314 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
69315 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
69316 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69317 + break;
69318 + default:
69319 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
69320 + }
69321 +
69322 + fslException = FmanExceptionTrans(exception);
69323 + fman_force_intr (&fman_rg, fslException);
69324 +
69325 + return E_OK;
69326 +}
69327 +
69328 +t_Handle FmGetPcd(t_Handle h_Fm)
69329 +{
69330 + return ((t_Fm*)h_Fm)->h_Pcd;
69331 +}
69332 +#if (DPAA_VERSION >= 11)
69333 +extern void *g_MemacRegs;
69334 +void fm_clk_down(void);
69335 +uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask);
69336 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId)
69337 +{
69338 + int macId;
69339 + uint32_t event, rcr;
69340 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69341 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69342 + rcr |= 0x04000000;
69343 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69344 +
69345 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
69346 + do
69347 + {
69348 + event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF);
69349 + } while ((event & 0x00000020) == 0);
69350 + fm_clk_down();
69351 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69352 + rcr &= ~0x04000000;
69353 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69354 +}
69355 +#endif
69356 --- /dev/null
69357 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
69358 @@ -0,0 +1,648 @@
69359 +/*
69360 + * Copyright 2008-2012 Freescale Semiconductor Inc.
69361 + *
69362 + * Redistribution and use in source and binary forms, with or without
69363 + * modification, are permitted provided that the following conditions are met:
69364 + * * Redistributions of source code must retain the above copyright
69365 + * notice, this list of conditions and the following disclaimer.
69366 + * * Redistributions in binary form must reproduce the above copyright
69367 + * notice, this list of conditions and the following disclaimer in the
69368 + * documentation and/or other materials provided with the distribution.
69369 + * * Neither the name of Freescale Semiconductor nor the
69370 + * names of its contributors may be used to endorse or promote products
69371 + * derived from this software without specific prior written permission.
69372 + *
69373 + *
69374 + * ALTERNATIVELY, this software may be distributed under the terms of the
69375 + * GNU General Public License ("GPL") as published by the Free Software
69376 + * Foundation, either version 2 of that License or (at your option) any
69377 + * later version.
69378 + *
69379 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
69380 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
69381 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
69382 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
69383 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
69384 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69385 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
69386 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69387 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69388 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69389 + */
69390 +
69391 +
69392 +/******************************************************************************
69393 + @File fm.h
69394 +
69395 + @Description FM internal structures and definitions.
69396 +*//***************************************************************************/
69397 +#ifndef __FM_H
69398 +#define __FM_H
69399 +
69400 +#include "error_ext.h"
69401 +#include "std_ext.h"
69402 +#include "fm_ext.h"
69403 +#include "fm_ipc.h"
69404 +
69405 +#include "fsl_fman.h"
69406 +
69407 +#define __ERR_MODULE__ MODULE_FM
69408 +
69409 +#define FM_MAX_NUM_OF_HW_PORT_IDS 64
69410 +#define FM_MAX_NUM_OF_GUESTS 100
69411 +
69412 +/**************************************************************************//**
69413 + @Description Exceptions
69414 +*//***************************************************************************/
69415 +#define FM_EX_DMA_BUS_ERROR 0x80000000 /**< DMA bus error. */
69416 +#define FM_EX_DMA_READ_ECC 0x40000000
69417 +#define FM_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
69418 +#define FM_EX_DMA_FM_WRITE_ECC 0x10000000
69419 +#define FM_EX_FPM_STALL_ON_TASKS 0x08000000 /**< Stall of tasks on FPM */
69420 +#define FM_EX_FPM_SINGLE_ECC 0x04000000 /**< Single ECC on FPM */
69421 +#define FM_EX_FPM_DOUBLE_ECC 0x02000000
69422 +#define FM_EX_QMI_SINGLE_ECC 0x01000000 /**< Single ECC on FPM */
69423 +#define FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 /**< Dequeu from default queue id */
69424 +#define FM_EX_QMI_DOUBLE_ECC 0x00400000
69425 +#define FM_EX_BMI_LIST_RAM_ECC 0x00200000
69426 +#define FM_EX_BMI_STORAGE_PROFILE_ECC 0x00100000
69427 +#define FM_EX_BMI_STATISTICS_RAM_ECC 0x00080000
69428 +#define FM_EX_IRAM_ECC 0x00040000
69429 +#define FM_EX_MURAM_ECC 0x00020000
69430 +#define FM_EX_BMI_DISPATCH_RAM_ECC 0x00010000
69431 +#define FM_EX_DMA_SINGLE_PORT_ECC 0x00008000
69432 +
69433 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
69434 +
69435 +#define DMA_THRESH_COMMQ_MASK 0xFF000000
69436 +#define DMA_THRESH_READ_INT_BUF_MASK 0x007F0000
69437 +#define DMA_THRESH_WRITE_INT_BUF_MASK 0x0000007F
69438 +
69439 +#define GET_EXCEPTION_FLAG(bitMask, exception) \
69440 +switch (exception){ \
69441 + case e_FM_EX_DMA_BUS_ERROR: \
69442 + bitMask = FM_EX_DMA_BUS_ERROR; break; \
69443 + case e_FM_EX_DMA_SINGLE_PORT_ECC: \
69444 + bitMask = FM_EX_DMA_SINGLE_PORT_ECC; break; \
69445 + case e_FM_EX_DMA_READ_ECC: \
69446 + bitMask = FM_EX_DMA_READ_ECC; break; \
69447 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \
69448 + bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \
69449 + case e_FM_EX_DMA_FM_WRITE_ECC: \
69450 + bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \
69451 + case e_FM_EX_FPM_STALL_ON_TASKS: \
69452 + bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \
69453 + case e_FM_EX_FPM_SINGLE_ECC: \
69454 + bitMask = FM_EX_FPM_SINGLE_ECC; break; \
69455 + case e_FM_EX_FPM_DOUBLE_ECC: \
69456 + bitMask = FM_EX_FPM_DOUBLE_ECC; break; \
69457 + case e_FM_EX_QMI_SINGLE_ECC: \
69458 + bitMask = FM_EX_QMI_SINGLE_ECC; break; \
69459 + case e_FM_EX_QMI_DOUBLE_ECC: \
69460 + bitMask = FM_EX_QMI_DOUBLE_ECC; break; \
69461 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \
69462 + bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \
69463 + case e_FM_EX_BMI_LIST_RAM_ECC: \
69464 + bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \
69465 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC: \
69466 + bitMask = FM_EX_BMI_STORAGE_PROFILE_ECC; break; \
69467 + case e_FM_EX_BMI_STATISTICS_RAM_ECC: \
69468 + bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \
69469 + case e_FM_EX_BMI_DISPATCH_RAM_ECC: \
69470 + bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \
69471 + case e_FM_EX_IRAM_ECC: \
69472 + bitMask = FM_EX_IRAM_ECC; break; \
69473 + case e_FM_EX_MURAM_ECC: \
69474 + bitMask = FM_EX_MURAM_ECC; break; \
69475 + default: bitMask = 0;break; \
69476 +}
69477 +
69478 +#define GET_FM_MODULE_EVENT(_mod, _id, _intrType, _event) \
69479 + switch (_mod) { \
69480 + case e_FM_MOD_PRS: \
69481 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69482 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \
69483 + break; \
69484 + case e_FM_MOD_KG: \
69485 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69486 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \
69487 + break; \
69488 + case e_FM_MOD_PLCR: \
69489 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69490 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \
69491 + break; \
69492 + case e_FM_MOD_TMR: \
69493 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69494 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \
69495 + break; \
69496 + case e_FM_MOD_10G_MAC: \
69497 + if (_id >= FM_MAX_NUM_OF_10G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69498 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_10G_MAC0 + _id) : (e_FM_EV_10G_MAC0 + _id); \
69499 + break; \
69500 + case e_FM_MOD_1G_MAC: \
69501 + if (_id >= FM_MAX_NUM_OF_1G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69502 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_1G_MAC0 + _id) : (e_FM_EV_1G_MAC0 + _id); \
69503 + break; \
69504 + case e_FM_MOD_MACSEC: \
69505 + switch (_id){ \
69506 + case (0): _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_MACSEC_MAC0:e_FM_EV_MACSEC_MAC0; \
69507 + break; \
69508 + } \
69509 + break; \
69510 + case e_FM_MOD_FMAN_CTRL: \
69511 + if (_intrType == e_FM_INTR_TYPE_ERR) _event = e_FM_EV_DUMMY_LAST; \
69512 + else _event = (e_FM_EV_FMAN_CTRL_0 + _id); \
69513 + break; \
69514 + default: _event = e_FM_EV_DUMMY_LAST; \
69515 + break; \
69516 + }
69517 +
69518 +#define FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, _cache_override) \
69519 + switch (_cache_override){ \
69520 + case e_FM_DMA_NO_CACHE_OR: \
69521 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69522 + case e_FM_DMA_NO_STASH_DATA: \
69523 + fsl_cache_override = E_FMAN_DMA_NO_STASH_DATA; break; \
69524 + case e_FM_DMA_MAY_STASH_DATA: \
69525 + fsl_cache_override = E_FMAN_DMA_MAY_STASH_DATA; break; \
69526 + case e_FM_DMA_STASH_DATA: \
69527 + fsl_cache_override = E_FMAN_DMA_STASH_DATA; break; \
69528 + default: \
69529 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69530 + }
69531 +
69532 +#define FMAN_AID_MODE_TRANS(fsl_aid_mode, _aid_mode) \
69533 + switch (_aid_mode){ \
69534 + case e_FM_DMA_AID_OUT_PORT_ID: \
69535 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69536 + case e_FM_DMA_AID_OUT_TNUM: \
69537 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_TNUM; break; \
69538 + default: \
69539 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69540 + }
69541 +
69542 +#define FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, _dma_dbg_cnt) \
69543 + switch (_dma_dbg_cnt){ \
69544 + case e_FM_DMA_DBG_NO_CNT: \
69545 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69546 + case e_FM_DMA_DBG_CNT_DONE: \
69547 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_DONE; break; \
69548 + case e_FM_DMA_DBG_CNT_COMM_Q_EM: \
69549 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_COMM_Q_EM; break; \
69550 + case e_FM_DMA_DBG_CNT_INT_READ_EM: \
69551 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_READ_EM; break; \
69552 + case e_FM_DMA_DBG_CNT_INT_WRITE_EM: \
69553 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_WRITE_EM ; break; \
69554 + case e_FM_DMA_DBG_CNT_FPM_WAIT: \
69555 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_FPM_WAIT ; break; \
69556 + case e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC: \
69557 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC ; break; \
69558 + case e_FM_DMA_DBG_CNT_RAW_WAR_PROT: \
69559 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT ; break; \
69560 + default: \
69561 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69562 + }
69563 +
69564 +#define FMAN_DMA_EMER_TRANS(fsl_dma_emer, _dma_emer) \
69565 + switch (_dma_emer){ \
69566 + case e_FM_DMA_EM_EBS: \
69567 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69568 + case e_FM_DMA_EM_SOS: \
69569 + fsl_dma_emer = E_FMAN_DMA_EM_SOS; break; \
69570 + default: \
69571 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69572 + }
69573 +
69574 +#define FMAN_DMA_ERR_TRANS(fsl_dma_err, _dma_err) \
69575 + switch (_dma_err){ \
69576 + case e_FM_DMA_ERR_CATASTROPHIC: \
69577 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69578 + case e_FM_DMA_ERR_REPORT: \
69579 + fsl_dma_err = E_FMAN_DMA_ERR_REPORT; break; \
69580 + default: \
69581 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69582 + }
69583 +
69584 +#define FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, _catastrophic_err) \
69585 + switch (_catastrophic_err){ \
69586 + case e_FM_CATASTROPHIC_ERR_STALL_PORT: \
69587 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69588 + case e_FM_CATASTROPHIC_ERR_STALL_TASK: \
69589 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_TASK; break; \
69590 + default: \
69591 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69592 + }
69593 +
69594 +#define FMAN_COUNTERS_TRANS(fsl_counters, _counters) \
69595 + switch (_counters){ \
69596 + case e_FM_COUNTERS_ENQ_TOTAL_FRAME: \
69597 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69598 + case e_FM_COUNTERS_DEQ_TOTAL_FRAME: \
69599 + fsl_counters = E_FMAN_COUNTERS_DEQ_TOTAL_FRAME; break; \
69600 + case e_FM_COUNTERS_DEQ_0: \
69601 + fsl_counters = E_FMAN_COUNTERS_DEQ_0; break; \
69602 + case e_FM_COUNTERS_DEQ_1: \
69603 + fsl_counters = E_FMAN_COUNTERS_DEQ_1; break; \
69604 + case e_FM_COUNTERS_DEQ_2: \
69605 + fsl_counters = E_FMAN_COUNTERS_DEQ_2; break; \
69606 + case e_FM_COUNTERS_DEQ_3: \
69607 + fsl_counters = E_FMAN_COUNTERS_DEQ_3; break; \
69608 + case e_FM_COUNTERS_DEQ_FROM_DEFAULT: \
69609 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_DEFAULT; break; \
69610 + case e_FM_COUNTERS_DEQ_FROM_CONTEXT: \
69611 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_CONTEXT; break; \
69612 + case e_FM_COUNTERS_DEQ_FROM_FD: \
69613 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_FD; break; \
69614 + case e_FM_COUNTERS_DEQ_CONFIRM: \
69615 + fsl_counters = E_FMAN_COUNTERS_DEQ_CONFIRM; break; \
69616 + default: \
69617 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69618 + }
69619 +
69620 +/**************************************************************************//**
69621 + @Description defaults
69622 +*//***************************************************************************/
69623 +#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\
69624 + FM_EX_DMA_READ_ECC |\
69625 + FM_EX_DMA_SYSTEM_WRITE_ECC |\
69626 + FM_EX_DMA_FM_WRITE_ECC |\
69627 + FM_EX_FPM_STALL_ON_TASKS |\
69628 + FM_EX_FPM_SINGLE_ECC |\
69629 + FM_EX_FPM_DOUBLE_ECC |\
69630 + FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID|\
69631 + FM_EX_BMI_LIST_RAM_ECC |\
69632 + FM_EX_BMI_STORAGE_PROFILE_ECC |\
69633 + FM_EX_BMI_STATISTICS_RAM_ECC |\
69634 + FM_EX_IRAM_ECC |\
69635 + FM_EX_MURAM_ECC |\
69636 + FM_EX_BMI_DISPATCH_RAM_ECC |\
69637 + FM_EX_QMI_DOUBLE_ECC |\
69638 + FM_EX_QMI_SINGLE_ECC)
69639 +
69640 +#define DEFAULT_eccEnable FALSE
69641 +#ifdef FM_PEDANTIC_DMA
69642 +#define DEFAULT_aidOverride TRUE
69643 +#else
69644 +#define DEFAULT_aidOverride FALSE
69645 +#endif /* FM_PEDANTIC_DMA */
69646 +#define DEFAULT_aidMode e_FM_DMA_AID_OUT_TNUM
69647 +#define DEFAULT_dmaStopOnBusError FALSE
69648 +#define DEFAULT_stopAtBusError FALSE
69649 +#define DEFAULT_axiDbgNumOfBeats 1
69650 +#define DEFAULT_dmaReadIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69651 +#define DEFAULT_dmaReadIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69652 +#define DEFAULT_dmaWriteIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69653 +#define DEFAULT_dmaWriteIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69654 +#define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT
69655 +#define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC
69656 +#define DEFAULT_resetOnInit FALSE
69657 +#define DEFAULT_resetOnInitOverrideCallback NULL
69658 +#define DEFAULT_haltOnExternalActivation FALSE /* do not change! if changed, must be disabled for rev1 ! */
69659 +#define DEFAULT_haltOnUnrecoverableEccError FALSE /* do not change! if changed, must be disabled for rev1 ! */
69660 +#define DEFAULT_externalEccRamsEnable FALSE
69661 +#define DEFAULT_VerifyUcode FALSE
69662 +
69663 +#if (DPAA_VERSION < 11)
69664 +#define DEFAULT_totalFifoSize(major, minor) \
69665 + (((major == 2) || (major == 5)) ? \
69666 + (100*KILOBYTE) : ((major == 4) ? \
69667 + (49*KILOBYTE) : (122*KILOBYTE)))
69668 +#define DEFAULT_totalNumOfTasks(major, minor) \
69669 + BMI_MAX_NUM_OF_TASKS
69670 +
69671 +#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2)
69672 +#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4)
69673 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69674 +#define DEFAULT_dmaCamNumOfEntries 32
69675 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69676 +#define DEFAULT_dmaEnEmergency FALSE
69677 +#define DEFAULT_dmaSosEmergency 0
69678 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69679 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69680 +#define DEFAULT_dmaEmergencySwitchCounter 0
69681 +
69682 +#define DEFAULT_dispLimit 0
69683 +#define DEFAULT_prsDispTh 16
69684 +#define DEFAULT_plcrDispTh 16
69685 +#define DEFAULT_kgDispTh 16
69686 +#define DEFAULT_bmiDispTh 16
69687 +#define DEFAULT_qmiEnqDispTh 16
69688 +#define DEFAULT_qmiDeqDispTh 16
69689 +#define DEFAULT_fmCtl1DispTh 16
69690 +#define DEFAULT_fmCtl2DispTh 16
69691 +
69692 +#else /* (DPAA_VERSION < 11) */
69693 +/* Defaults are registers' reset values */
69694 +#define DEFAULT_totalFifoSize(major, minor) \
69695 + (((major == 6) && ((minor == 1) || (minor == 4))) ? \
69696 + (156*KILOBYTE) : (295*KILOBYTE))
69697 +
69698 +/* According to the default value of FMBM_CFG2[TNTSKS] */
69699 +#define DEFAULT_totalNumOfTasks(major, minor) \
69700 + (((major == 6) && ((minor == 1) || (minor == 4))) ? 59 : 124)
69701 +
69702 +#define DEFAULT_dmaCommQLow 0x2A
69703 +#define DEFAULT_dmaCommQHigh 0x3F
69704 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69705 +#define DEFAULT_dmaCamNumOfEntries 64
69706 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69707 +#define DEFAULT_dmaEnEmergency FALSE
69708 +#define DEFAULT_dmaSosEmergency 0
69709 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69710 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69711 +#define DEFAULT_dmaEmergencySwitchCounter 0
69712 +
69713 +#define DEFAULT_dispLimit 0
69714 +#define DEFAULT_prsDispTh 16
69715 +#define DEFAULT_plcrDispTh 16
69716 +#define DEFAULT_kgDispTh 16
69717 +#define DEFAULT_bmiDispTh 16
69718 +#define DEFAULT_qmiEnqDispTh 16
69719 +#define DEFAULT_qmiDeqDispTh 16
69720 +#define DEFAULT_fmCtl1DispTh 16
69721 +#define DEFAULT_fmCtl2DispTh 16
69722 +#endif /* (DPAA_VERSION < 11) */
69723 +
69724 +#define FM_TIMESTAMP_1_USEC_BIT 8
69725 +
69726 +/**************************************************************************//**
69727 + @Collection Defines used for enabling/disabling FM interrupts
69728 + @{
69729 +*//***************************************************************************/
69730 +#define ERR_INTR_EN_DMA 0x00010000
69731 +#define ERR_INTR_EN_FPM 0x80000000
69732 +#define ERR_INTR_EN_BMI 0x00800000
69733 +#define ERR_INTR_EN_QMI 0x00400000
69734 +#define ERR_INTR_EN_PRS 0x00200000
69735 +#define ERR_INTR_EN_KG 0x00100000
69736 +#define ERR_INTR_EN_PLCR 0x00080000
69737 +#define ERR_INTR_EN_MURAM 0x00040000
69738 +#define ERR_INTR_EN_IRAM 0x00020000
69739 +#define ERR_INTR_EN_10G_MAC0 0x00008000
69740 +#define ERR_INTR_EN_10G_MAC1 0x00000040
69741 +#define ERR_INTR_EN_1G_MAC0 0x00004000
69742 +#define ERR_INTR_EN_1G_MAC1 0x00002000
69743 +#define ERR_INTR_EN_1G_MAC2 0x00001000
69744 +#define ERR_INTR_EN_1G_MAC3 0x00000800
69745 +#define ERR_INTR_EN_1G_MAC4 0x00000400
69746 +#define ERR_INTR_EN_1G_MAC5 0x00000200
69747 +#define ERR_INTR_EN_1G_MAC6 0x00000100
69748 +#define ERR_INTR_EN_1G_MAC7 0x00000080
69749 +#define ERR_INTR_EN_MACSEC_MAC0 0x00000001
69750 +
69751 +#define INTR_EN_QMI 0x40000000
69752 +#define INTR_EN_PRS 0x20000000
69753 +#define INTR_EN_WAKEUP 0x10000000
69754 +#define INTR_EN_PLCR 0x08000000
69755 +#define INTR_EN_1G_MAC0 0x00080000
69756 +#define INTR_EN_1G_MAC1 0x00040000
69757 +#define INTR_EN_1G_MAC2 0x00020000
69758 +#define INTR_EN_1G_MAC3 0x00010000
69759 +#define INTR_EN_1G_MAC4 0x00000040
69760 +#define INTR_EN_1G_MAC5 0x00000020
69761 +#define INTR_EN_1G_MAC6 0x00000008
69762 +#define INTR_EN_1G_MAC7 0x00000002
69763 +#define INTR_EN_10G_MAC0 0x00200000
69764 +#define INTR_EN_10G_MAC1 0x00100000
69765 +#define INTR_EN_REV0 0x00008000
69766 +#define INTR_EN_REV1 0x00004000
69767 +#define INTR_EN_REV2 0x00002000
69768 +#define INTR_EN_REV3 0x00001000
69769 +#define INTR_EN_BRK 0x00000080
69770 +#define INTR_EN_TMR 0x01000000
69771 +#define INTR_EN_MACSEC_MAC0 0x00000001
69772 +/* @} */
69773 +
69774 +/**************************************************************************//**
69775 + @Description Memory Mapped Registers
69776 +*//***************************************************************************/
69777 +
69778 +#if defined(__MWERKS__) && !defined(__GNUC__)
69779 +#pragma pack(push,1)
69780 +#endif /* defined(__MWERKS__) && ... */
69781 +
69782 +typedef struct
69783 +{
69784 + volatile uint32_t iadd; /**< FM IRAM instruction address register */
69785 + volatile uint32_t idata; /**< FM IRAM instruction data register */
69786 + volatile uint32_t itcfg; /**< FM IRAM timing config register */
69787 + volatile uint32_t iready; /**< FM IRAM ready register */
69788 + volatile uint32_t res[0x1FFFC];
69789 +} t_FMIramRegs;
69790 +
69791 +/* Trace buffer registers -
69792 + each FM Controller has its own trace buffer residing at FM_MM_TRB(fmCtrlIndex) offset */
69793 +typedef struct t_FmTrbRegs
69794 +{
69795 + volatile uint32_t tcrh;
69796 + volatile uint32_t tcrl;
69797 + volatile uint32_t tesr;
69798 + volatile uint32_t tecr0h;
69799 + volatile uint32_t tecr0l;
69800 + volatile uint32_t terf0h;
69801 + volatile uint32_t terf0l;
69802 + volatile uint32_t tecr1h;
69803 + volatile uint32_t tecr1l;
69804 + volatile uint32_t terf1h;
69805 + volatile uint32_t terf1l;
69806 + volatile uint32_t tpcch;
69807 + volatile uint32_t tpccl;
69808 + volatile uint32_t tpc1h;
69809 + volatile uint32_t tpc1l;
69810 + volatile uint32_t tpc2h;
69811 + volatile uint32_t tpc2l;
69812 + volatile uint32_t twdimr;
69813 + volatile uint32_t twicvr;
69814 + volatile uint32_t tar;
69815 + volatile uint32_t tdr;
69816 + volatile uint32_t tsnum1;
69817 + volatile uint32_t tsnum2;
69818 + volatile uint32_t tsnum3;
69819 + volatile uint32_t tsnum4;
69820 +} t_FmTrbRegs;
69821 +
69822 +#if defined(__MWERKS__) && !defined(__GNUC__)
69823 +#pragma pack(pop)
69824 +#endif /* defined(__MWERKS__) && ... */
69825 +
69826 +/**************************************************************************//**
69827 + @Description General defines
69828 +*//***************************************************************************/
69829 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
69830 +#define FM_FW_DEBUG_INSTRUCTION 0x6ffff805UL
69831 +
69832 +/**************************************************************************//**
69833 + @Description FPM defines
69834 +*//***************************************************************************/
69835 +/* masks */
69836 +#define FPM_BRKC_RDBG 0x00000200
69837 +#define FPM_BRKC_SLP 0x00000800
69838 +/**************************************************************************//**
69839 + @Description BMI defines
69840 +*//***************************************************************************/
69841 +/* masks */
69842 +#define BMI_INIT_START 0x80000000
69843 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
69844 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
69845 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
69846 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
69847 +/**************************************************************************//**
69848 + @Description QMI defines
69849 +*//***************************************************************************/
69850 +/* masks */
69851 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
69852 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
69853 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
69854 +
69855 +/**************************************************************************//**
69856 + @Description IRAM defines
69857 +*//***************************************************************************/
69858 +/* masks */
69859 +#define IRAM_IADD_AIE 0x80000000
69860 +#define IRAM_READY 0x80000000
69861 +
69862 +/**************************************************************************//**
69863 + @Description TRB defines
69864 +*//***************************************************************************/
69865 +/* masks */
69866 +#define TRB_TCRH_RESET 0x04000000
69867 +#define TRB_TCRH_ENABLE_COUNTERS 0x84008000
69868 +#define TRB_TCRH_DISABLE_COUNTERS 0x8400C000
69869 +#define TRB_TCRL_RESET 0x20000000
69870 +#define TRB_TCRL_UTIL 0x00000460
69871 +typedef struct {
69872 + void (*f_Isr) (t_Handle h_Arg, uint32_t event);
69873 + t_Handle h_SrcHandle;
69874 +} t_FmanCtrlIntrSrc;
69875 +
69876 +
69877 +typedef void (t_FmanCtrlIsr)( t_Handle h_Fm, uint32_t event);
69878 +
69879 +typedef struct
69880 +{
69881 +/***************************/
69882 +/* Master/Guest parameters */
69883 +/***************************/
69884 + uint8_t fmId;
69885 + e_FmPortType portsTypes[FM_MAX_NUM_OF_HW_PORT_IDS];
69886 + uint16_t fmClkFreq;
69887 + uint16_t fmMacClkFreq;
69888 + t_FmRevisionInfo revInfo;
69889 +/**************************/
69890 +/* Master Only parameters */
69891 +/**************************/
69892 + bool enabledTimeStamp;
69893 + uint8_t count1MicroBit;
69894 + uint8_t totalNumOfTasks;
69895 + uint32_t totalFifoSize;
69896 + uint8_t maxNumOfOpenDmas;
69897 + uint8_t accumulatedNumOfTasks;
69898 + uint32_t accumulatedFifoSize;
69899 + uint8_t accumulatedNumOfOpenDmas;
69900 + uint8_t accumulatedNumOfDeqTnums;
69901 +#ifdef FM_LOW_END_RESTRICTION
69902 + bool lowEndRestriction;
69903 +#endif /* FM_LOW_END_RESTRICTION */
69904 + uint32_t exceptions;
69905 + int irq;
69906 + int errIrq;
69907 + bool ramsEccEnable;
69908 + bool explicitEnable;
69909 + bool internalCall;
69910 + uint8_t ramsEccOwners;
69911 + uint32_t extraFifoPoolSize;
69912 + uint8_t extraTasksPoolSize;
69913 + uint8_t extraOpenDmasPoolSize;
69914 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
69915 + uint16_t portMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
69916 + uint16_t macMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
69917 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
69918 + uint16_t portMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
69919 + uint16_t macMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
69920 +} t_FmStateStruct;
69921 +
69922 +#if (DPAA_VERSION >= 11)
69923 +typedef struct t_FmMapParam {
69924 + uint16_t profilesBase;
69925 + uint16_t numOfProfiles;
69926 + t_Handle h_FmPort;
69927 +} t_FmMapParam;
69928 +
69929 +typedef struct t_FmAllocMng {
69930 + bool allocated;
69931 + uint8_t ownerId; /* guestId for KG in multi-partition only,
69932 + portId for PLCR in any environment */
69933 +} t_FmAllocMng;
69934 +
69935 +typedef struct t_FmPcdSpEntry {
69936 + bool valid;
69937 + t_FmAllocMng profilesMng;
69938 +} t_FmPcdSpEntry;
69939 +
69940 +typedef struct t_FmSp {
69941 + void *p_FmPcdStoragePrflRegs;
69942 + t_FmPcdSpEntry profiles[FM_VSP_MAX_NUM_OF_ENTRIES];
69943 + t_FmMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
69944 +} t_FmSp;
69945 +#endif /* (DPAA_VERSION >= 11) */
69946 +
69947 +typedef struct t_Fm
69948 +{
69949 +/***************************/
69950 +/* Master/Guest parameters */
69951 +/***************************/
69952 +/* locals for recovery */
69953 + uintptr_t baseAddr;
69954 +
69955 +/* un-needed for recovery */
69956 + t_Handle h_Pcd;
69957 + char fmModuleName[MODULE_NAME_SIZE];
69958 + char fmIpcHandlerModuleName[FM_MAX_NUM_OF_GUESTS][MODULE_NAME_SIZE];
69959 + t_Handle h_IpcSessions[FM_MAX_NUM_OF_GUESTS];
69960 + t_FmIntrSrc intrMng[e_FM_EV_DUMMY_LAST]; /* FM exceptions user callback */
69961 + uint8_t guestId;
69962 +/**************************/
69963 +/* Master Only parameters */
69964 +/**************************/
69965 +/* locals for recovery */
69966 + struct fman_fpm_regs *p_FmFpmRegs;
69967 + struct fman_bmi_regs *p_FmBmiRegs;
69968 + struct fman_qmi_regs *p_FmQmiRegs;
69969 + struct fman_dma_regs *p_FmDmaRegs;
69970 + struct fman_regs *p_FmRegs;
69971 + t_FmExceptionsCallback *f_Exception;
69972 + t_FmBusErrorCallback *f_BusError;
69973 + t_Handle h_App; /* Application handle */
69974 + t_Handle h_Spinlock;
69975 + bool recoveryMode;
69976 + t_FmStateStruct *p_FmStateStruct;
69977 + uint16_t tnumAgingPeriod;
69978 +#if (DPAA_VERSION >= 11)
69979 + t_FmSp *p_FmSp;
69980 + uint8_t partNumOfVSPs;
69981 + uint8_t partVSPBase;
69982 + uintptr_t vspBaseAddr;
69983 +#endif /* (DPAA_VERSION >= 11) */
69984 + bool portsPreFetchConfigured[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
69985 + bool portsPreFetchValue[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
69986 +
69987 +/* un-needed for recovery */
69988 + struct fman_cfg *p_FmDriverParam;
69989 + t_Handle h_FmMuram;
69990 + uint64_t fmMuramPhysBaseAddr;
69991 + bool independentMode;
69992 + bool hcPortInitialized;
69993 + uintptr_t camBaseAddr; /* save for freeing */
69994 + uintptr_t resAddr;
69995 + uintptr_t fifoBaseAddr; /* save for freeing */
69996 + t_FmanCtrlIntrSrc fmanCtrlIntr[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; /* FM exceptions user callback */
69997 + bool usedEventRegs[FM_NUM_OF_FMAN_CTRL_EVENT_REGS];
69998 + t_FmFirmwareParams firmware;
69999 + bool fwVerify;
70000 + bool resetOnInit;
70001 + t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride;
70002 + uint32_t userSetExceptions;
70003 +} t_Fm;
70004 +
70005 +
70006 +#endif /* __FM_H */
70007 --- /dev/null
70008 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
70009 @@ -0,0 +1,465 @@
70010 +/*
70011 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70012 + *
70013 + * Redistribution and use in source and binary forms, with or without
70014 + * modification, are permitted provided that the following conditions are met:
70015 + * * Redistributions of source code must retain the above copyright
70016 + * notice, this list of conditions and the following disclaimer.
70017 + * * Redistributions in binary form must reproduce the above copyright
70018 + * notice, this list of conditions and the following disclaimer in the
70019 + * documentation and/or other materials provided with the distribution.
70020 + * * Neither the name of Freescale Semiconductor nor the
70021 + * names of its contributors may be used to endorse or promote products
70022 + * derived from this software without specific prior written permission.
70023 + *
70024 + *
70025 + * ALTERNATIVELY, this software may be distributed under the terms of the
70026 + * GNU General Public License ("GPL") as published by the Free Software
70027 + * Foundation, either version 2 of that License or (at your option) any
70028 + * later version.
70029 + *
70030 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70031 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70032 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70033 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70034 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70035 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70036 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70037 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70038 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70039 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70040 + */
70041 +
70042 +
70043 +/**************************************************************************//**
70044 + @File fm_ipc.h
70045 +
70046 + @Description FM Inter-Partition prototypes, structures and definitions.
70047 +*//***************************************************************************/
70048 +#ifndef __FM_IPC_H
70049 +#define __FM_IPC_H
70050 +
70051 +#include "error_ext.h"
70052 +#include "std_ext.h"
70053 +
70054 +
70055 +/**************************************************************************//**
70056 + @Group FM_grp Frame Manager API
70057 +
70058 + @Description FM API functions, definitions and enums
70059 +
70060 + @{
70061 +*//***************************************************************************/
70062 +
70063 +/**************************************************************************//**
70064 + @Group FM_IPC_grp FM Inter-Partition messaging Unit
70065 +
70066 + @Description FM Inter-Partition messaging unit API definitions and enums.
70067 +
70068 + @{
70069 +*//***************************************************************************/
70070 +
70071 +#if defined(__MWERKS__) && !defined(__GNUC__)
70072 +#pragma pack(push,1)
70073 +#endif /* defined(__MWERKS__) && ... */
70074 +
70075 +/**************************************************************************//**
70076 + @Description enum for defining MAC types
70077 +*//***************************************************************************/
70078 +
70079 +/**************************************************************************//**
70080 + @Description A structure of parameters for specifying a MAC.
70081 +*//***************************************************************************/
70082 +typedef _Packed struct
70083 +{
70084 + uint8_t id;
70085 + uint32_t enumType;
70086 +} _PackedType t_FmIpcMacParams;
70087 +
70088 +/**************************************************************************//**
70089 + @Description A structure of parameters for specifying a MAC.
70090 +*//***************************************************************************/
70091 +typedef _Packed struct
70092 +{
70093 + t_FmIpcMacParams macParams;
70094 + uint16_t maxFrameLength;
70095 +} _PackedType t_FmIpcMacMaxFrameParams;
70096 +
70097 +/**************************************************************************//**
70098 + @Description FM physical Address
70099 +*//***************************************************************************/
70100 +typedef _Packed struct t_FmIpcPhysAddr
70101 +{
70102 + volatile uint8_t high;
70103 + volatile uint32_t low;
70104 +} _PackedType t_FmIpcPhysAddr;
70105 +
70106 +
70107 +typedef _Packed struct t_FmIpcPortOutInitParams {
70108 + uint8_t numOfTasks; /**< OUT */
70109 + uint8_t numOfExtraTasks; /**< OUT */
70110 + uint8_t numOfOpenDmas; /**< OUT */
70111 + uint8_t numOfExtraOpenDmas; /**< OUT */
70112 + uint32_t sizeOfFifo; /**< OUT */
70113 + uint32_t extraSizeOfFifo; /**< OUT */
70114 + t_FmIpcPhysAddr ipcPhysAddr; /**< OUT */
70115 +} _PackedType t_FmIpcPortOutInitParams;
70116 +
70117 +/**************************************************************************//**
70118 + @Description Structure for IPC communication during FM_PORT_Init.
70119 +*//***************************************************************************/
70120 +typedef _Packed struct t_FmIpcPortInInitParams {
70121 + uint8_t hardwarePortId; /**< IN. port Id */
70122 + uint32_t enumPortType; /**< IN. Port type */
70123 + uint8_t boolIndependentMode;/**< IN. TRUE if FM Port operates in independent mode */
70124 + uint16_t liodnOffset; /**< IN. Port's requested resource */
70125 + uint8_t numOfTasks; /**< IN. Port's requested resource */
70126 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
70127 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
70128 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
70129 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
70130 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
70131 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70132 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
70133 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
70134 + LIODN base for this port, to be
70135 + used together with LIODN offset. */
70136 +} _PackedType t_FmIpcPortInInitParams;
70137 +
70138 +
70139 +/**************************************************************************//**
70140 + @Description Structure for IPC communication between port and FM
70141 + regarding tasks and open DMA resources management.
70142 +*//***************************************************************************/
70143 +typedef _Packed struct t_FmIpcPortRsrcParams {
70144 + uint8_t hardwarePortId; /**< IN. port Id */
70145 + uint32_t val; /**< IN. Port's requested resource */
70146 + uint32_t extra; /**< IN. Port's requested resource */
70147 + uint8_t boolInitialConfig;
70148 +} _PackedType t_FmIpcPortRsrcParams;
70149 +
70150 +
70151 +/**************************************************************************//**
70152 + @Description Structure for IPC communication between port and FM
70153 + regarding tasks and open DMA resources management.
70154 +*//***************************************************************************/
70155 +typedef _Packed struct t_FmIpcPortFifoParams {
70156 + t_FmIpcPortRsrcParams rsrcParams;
70157 + uint32_t enumPortType;
70158 + uint8_t boolIndependentMode;
70159 + uint8_t deqPipelineDepth;
70160 + uint8_t numOfPools;
70161 + uint16_t secondLargestBufSize;
70162 + uint16_t largestBufSize;
70163 + uint8_t boolInitialConfig;
70164 +} _PackedType t_FmIpcPortFifoParams;
70165 +
70166 +/**************************************************************************//**
70167 + @Description Structure for port-FM communication during FM_PORT_Free.
70168 +*//***************************************************************************/
70169 +typedef _Packed struct t_FmIpcPortFreeParams {
70170 + uint8_t hardwarePortId; /**< IN. port Id */
70171 + uint32_t enumPortType; /**< IN. Port type */
70172 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70173 +} _PackedType t_FmIpcPortFreeParams;
70174 +
70175 +/**************************************************************************//**
70176 + @Description Structure for defining DMA status
70177 +*//***************************************************************************/
70178 +typedef _Packed struct t_FmIpcDmaStatus {
70179 + uint8_t boolCmqNotEmpty; /**< Command queue is not empty */
70180 + uint8_t boolBusError; /**< Bus error occurred */
70181 + uint8_t boolReadBufEccError; /**< Double ECC error on buffer Read */
70182 + uint8_t boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
70183 + uint8_t boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
70184 + uint8_t boolSinglePortEccError; /**< Single port ECC error from FM side */
70185 +} _PackedType t_FmIpcDmaStatus;
70186 +
70187 +typedef _Packed struct t_FmIpcRegisterIntr
70188 +{
70189 + uint8_t guestId; /* IN */
70190 + uint32_t event; /* IN */
70191 +} _PackedType t_FmIpcRegisterIntr;
70192 +
70193 +typedef _Packed struct t_FmIpcIsr
70194 +{
70195 + uint8_t boolErr; /* IN */
70196 + uint32_t pendingReg; /* IN */
70197 +} _PackedType t_FmIpcIsr;
70198 +
70199 +/**************************************************************************//**
70200 + @Description structure for returning FM parameters
70201 +*//***************************************************************************/
70202 +typedef _Packed struct t_FmIpcParams {
70203 + uint16_t fmClkFreq; /**< OUT: FM Clock frequency */
70204 + uint16_t fmMacClkFreq; /**< OUT: FM MAC clock frequence */
70205 + uint8_t majorRev; /**< OUT: FM Major revision */
70206 + uint8_t minorRev; /**< OUT: FM Minor revision */
70207 +} _PackedType t_FmIpcParams;
70208 +
70209 +
70210 +/**************************************************************************//**
70211 + @Description structure for returning Fman Ctrl Code revision information
70212 +*//***************************************************************************/
70213 +typedef _Packed struct t_FmIpcFmanCtrlCodeRevisionInfo {
70214 + uint16_t packageRev; /**< OUT: Package revision */
70215 + uint8_t majorRev; /**< OUT: Major revision */
70216 + uint8_t minorRev; /**< OUT: Minor revision */
70217 +} _PackedType t_FmIpcFmanCtrlCodeRevisionInfo;
70218 +
70219 +/**************************************************************************//**
70220 + @Description Structure for defining Fm number of Fman controlers
70221 +*//***************************************************************************/
70222 +typedef _Packed struct t_FmIpcPortNumOfFmanCtrls {
70223 + uint8_t hardwarePortId; /**< IN. port Id */
70224 + uint8_t numOfFmanCtrls; /**< IN. Port type */
70225 + t_FmFmanCtrl orFmanCtrl; /**< IN. fman controller for order restoration*/
70226 +} t_FmIpcPortNumOfFmanCtrls;
70227 +
70228 +/**************************************************************************//**
70229 + @Description structure for setting Fman contriller events
70230 +*//***************************************************************************/
70231 +typedef _Packed struct t_FmIpcFmanEvents {
70232 + uint8_t eventRegId; /**< IN: Fman controller event register id */
70233 + uint32_t enableEvents; /**< IN/OUT: required enabled events mask */
70234 +} _PackedType t_FmIpcFmanEvents;
70235 +
70236 +typedef _Packed struct t_FmIpcResourceAllocParams {
70237 + uint8_t guestId;
70238 + uint16_t base;
70239 + uint16_t num;
70240 +}_PackedType t_FmIpcResourceAllocParams;
70241 +
70242 +typedef _Packed struct t_FmIpcVspSetPortWindow {
70243 + uint8_t hardwarePortId;
70244 + uint8_t baseStorageProfile;
70245 + uint8_t log2NumOfProfiles;
70246 +}_PackedType t_FmIpcVspSetPortWindow;
70247 +
70248 +typedef _Packed struct t_FmIpcSetCongestionGroupPfcPriority {
70249 + uint32_t congestionGroupId;
70250 + uint8_t priorityBitMap;
70251 +}_PackedType t_FmIpcSetCongestionGroupPfcPriority;
70252 +
70253 +#define FM_IPC_MAX_REPLY_BODY_SIZE 20
70254 +#define FM_IPC_MAX_REPLY_SIZE (FM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t))
70255 +#define FM_IPC_MAX_MSG_SIZE 30
70256 +
70257 +typedef _Packed struct t_FmIpcMsg
70258 +{
70259 + uint32_t msgId;
70260 + uint8_t msgBody[FM_IPC_MAX_MSG_SIZE];
70261 +} _PackedType t_FmIpcMsg;
70262 +
70263 +typedef _Packed struct t_FmIpcReply
70264 +{
70265 + uint32_t error;
70266 + uint8_t replyBody[FM_IPC_MAX_REPLY_BODY_SIZE];
70267 +} _PackedType t_FmIpcReply;
70268 +
70269 +#if defined(__MWERKS__) && !defined(__GNUC__)
70270 +#pragma pack(pop)
70271 +#endif /* defined(__MWERKS__) && ... */
70272 +
70273 +
70274 +/***************************************************************************/
70275 +/************************ FRONT-END-TO-BACK-END*****************************/
70276 +/***************************************************************************/
70277 +
70278 +/**************************************************************************//**
70279 + @Function FM_GET_TIMESTAMP_SCALE
70280 +
70281 + @Description Used by FM front-end.
70282 +
70283 + @Param[out] uint32_t Pointer
70284 +*//***************************************************************************/
70285 +#define FM_GET_TIMESTAMP_SCALE 1
70286 +
70287 +/**************************************************************************//**
70288 + @Function FM_GET_COUNTER
70289 +
70290 + @Description Used by FM front-end.
70291 +
70292 + @Param[in/out] t_FmIpcGetCounter Pointer
70293 +*//***************************************************************************/
70294 +#define FM_GET_COUNTER 2
70295 +
70296 +/**************************************************************************//**
70297 + @Function FM_GET_SET_PORT_PARAMS
70298 +
70299 + @Description Used by FM front-end for the PORT module in order to set and get
70300 + parameters in/from master FM module on FM PORT initialization time.
70301 +
70302 + @Param[in/out] t_FmIcPortInitParams Pointer
70303 +*//***************************************************************************/
70304 +#define FM_GET_SET_PORT_PARAMS 4
70305 +
70306 +/**************************************************************************//**
70307 + @Function FM_FREE_PORT
70308 +
70309 + @Description Used by FM front-end for the PORT module when a port is freed
70310 + to free all FM PORT resources.
70311 +
70312 + @Param[in] uint8_t Pointer
70313 +*//***************************************************************************/
70314 +#define FM_FREE_PORT 5
70315 +
70316 +/**************************************************************************//**
70317 + @Function FM_RESET_MAC
70318 +
70319 + @Description Used by front-end for the MAC module to reset the MAC registers
70320 +
70321 + @Param[in] t_FmIpcMacParams Pointer .
70322 +*//***************************************************************************/
70323 +#define FM_RESET_MAC 6
70324 +
70325 +/**************************************************************************//**
70326 + @Function FM_RESUME_STALLED_PORT
70327 +
70328 + @Description Used by FM front-end for the PORT module in order to
70329 + release a stalled FM Port.
70330 +
70331 + @Param[in] uint8_t Pointer
70332 +*//***************************************************************************/
70333 +#define FM_RESUME_STALLED_PORT 7
70334 +
70335 +/**************************************************************************//**
70336 + @Function FM_IS_PORT_STALLED
70337 +
70338 + @Description Used by FM front-end for the PORT module in order to check whether
70339 + an FM port is stalled.
70340 +
70341 + @Param[in/out] t_FmIcPortIsStalled Pointer
70342 +*//***************************************************************************/
70343 +#define FM_IS_PORT_STALLED 8
70344 +
70345 +/**************************************************************************//**
70346 + @Function FM_GET_PARAMS
70347 +
70348 + @Description Used by FM front-end for the PORT module in order to dump
70349 + return FM parameters.
70350 +
70351 + @Param[in] uint8_t Pointer
70352 +*//***************************************************************************/
70353 +#define FM_GET_PARAMS 10
70354 +
70355 +/**************************************************************************//**
70356 + @Function FM_REGISTER_INTR
70357 +
70358 + @Description Used by FM front-end to register an interrupt handler to
70359 + be called upon interrupt for guest.
70360 +
70361 + @Param[out] t_FmIpcRegisterIntr Pointer
70362 +*//***************************************************************************/
70363 +#define FM_REGISTER_INTR 11
70364 +
70365 +/**************************************************************************//**
70366 + @Function FM_DMA_STAT
70367 +
70368 + @Description Used by FM front-end to read the FM DMA status.
70369 +
70370 + @Param[out] t_FmIpcDmaStatus Pointer
70371 +*//***************************************************************************/
70372 +#define FM_DMA_STAT 13
70373 +
70374 +/**************************************************************************//**
70375 + @Function FM_ALLOC_FMAN_CTRL_EVENT_REG
70376 +
70377 + @Description Used by FM front-end to allocate event register.
70378 +
70379 + @Param[out] Event register id Pointer
70380 +*//***************************************************************************/
70381 +#define FM_ALLOC_FMAN_CTRL_EVENT_REG 14
70382 +
70383 +/**************************************************************************//**
70384 + @Function FM_FREE_FMAN_CTRL_EVENT_REG
70385 +
70386 + @Description Used by FM front-end to free locate event register.
70387 +
70388 + @Param[in] uint8_t Pointer - Event register id
70389 +*//***************************************************************************/
70390 +#define FM_FREE_FMAN_CTRL_EVENT_REG 15
70391 +
70392 +/**************************************************************************//**
70393 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70394 +
70395 + @Description Used by FM front-end to enable events in the FPM
70396 + Fman controller event register.
70397 +
70398 + @Param[in] t_FmIpcFmanEvents Pointer
70399 +*//***************************************************************************/
70400 +#define FM_SET_FMAN_CTRL_EVENTS_ENABLE 16
70401 +
70402 +/**************************************************************************//**
70403 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70404 +
70405 + @Description Used by FM front-end to enable events in the FPM
70406 + Fman controller event register.
70407 +
70408 + @Param[in/out] t_FmIpcFmanEvents Pointer
70409 +*//***************************************************************************/
70410 +#define FM_GET_FMAN_CTRL_EVENTS_ENABLE 17
70411 +
70412 +/**************************************************************************//**
70413 + @Function FM_SET_MAC_MAX_FRAME
70414 +
70415 + @Description Used by FM front-end to set MAC's MTU/RTU's in
70416 + back-end.
70417 +
70418 + @Param[in/out] t_FmIpcMacMaxFrameParams Pointer
70419 +*//***************************************************************************/
70420 +#define FM_SET_MAC_MAX_FRAME 18
70421 +
70422 +/**************************************************************************//**
70423 + @Function FM_GET_PHYS_MURAM_BASE
70424 +
70425 + @Description Used by FM front-end in order to get MURAM base address
70426 +
70427 + @Param[in/out] t_FmIpcPhysAddr Pointer
70428 +*//***************************************************************************/
70429 +#define FM_GET_PHYS_MURAM_BASE 19
70430 +
70431 +/**************************************************************************//**
70432 + @Function FM_MASTER_IS_ALIVE
70433 +
70434 + @Description Used by FM front-end in order to verify Master is up
70435 +
70436 + @Param[in/out] bool
70437 +*//***************************************************************************/
70438 +#define FM_MASTER_IS_ALIVE 20
70439 +
70440 +#define FM_ENABLE_RAM_ECC 21
70441 +#define FM_DISABLE_RAM_ECC 22
70442 +#define FM_SET_NUM_OF_FMAN_CTRL 23
70443 +#define FM_SET_SIZE_OF_FIFO 24
70444 +#define FM_SET_NUM_OF_TASKS 25
70445 +#define FM_SET_NUM_OF_OPEN_DMAS 26
70446 +#define FM_VSP_ALLOC 27
70447 +#define FM_VSP_FREE 28
70448 +#define FM_VSP_SET_PORT_WINDOW 29
70449 +#define FM_GET_FMAN_CTRL_CODE_REV 30
70450 +#define FM_SET_CONG_GRP_PFC_PRIO 31
70451 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
70452 +#define FM_10G_TX_ECC_WA 100
70453 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
70454 +
70455 +/***************************************************************************/
70456 +/************************ BACK-END-TO-FRONT-END*****************************/
70457 +/***************************************************************************/
70458 +
70459 +/**************************************************************************//**
70460 + @Function FM_GUEST_ISR
70461 +
70462 + @Description Used by FM back-end to report an interrupt to the front-end.
70463 +
70464 + @Param[out] t_FmIpcIsr Pointer
70465 +*//***************************************************************************/
70466 +#define FM_GUEST_ISR 1
70467 +
70468 +
70469 +
70470 +/** @} */ /* end of FM_IPC_grp group */
70471 +/** @} */ /* end of FM_grp group */
70472 +
70473 +
70474 +#endif /* __FM_IPC_H */
70475 --- /dev/null
70476 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
70477 @@ -0,0 +1,174 @@
70478 +/*
70479 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70480 + *
70481 + * Redistribution and use in source and binary forms, with or without
70482 + * modification, are permitted provided that the following conditions are met:
70483 + * * Redistributions of source code must retain the above copyright
70484 + * notice, this list of conditions and the following disclaimer.
70485 + * * Redistributions in binary form must reproduce the above copyright
70486 + * notice, this list of conditions and the following disclaimer in the
70487 + * documentation and/or other materials provided with the distribution.
70488 + * * Neither the name of Freescale Semiconductor nor the
70489 + * names of its contributors may be used to endorse or promote products
70490 + * derived from this software without specific prior written permission.
70491 + *
70492 + *
70493 + * ALTERNATIVELY, this software may be distributed under the terms of the
70494 + * GNU General Public License ("GPL") as published by the Free Software
70495 + * Foundation, either version 2 of that License or (at your option) any
70496 + * later version.
70497 + *
70498 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70499 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70500 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70501 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70502 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70503 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70504 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70505 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70506 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70507 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70508 + */
70509 +
70510 +
70511 +/******************************************************************************
70512 + @File FM_muram.c
70513 +
70514 + @Description FM MURAM ...
70515 +*//***************************************************************************/
70516 +#include "error_ext.h"
70517 +#include "std_ext.h"
70518 +#include "mm_ext.h"
70519 +#include "string_ext.h"
70520 +#include "sprint_ext.h"
70521 +#include "fm_muram_ext.h"
70522 +#include "fm_common.h"
70523 +
70524 +#define __ERR_MODULE__ MODULE_FM_MURAM
70525 +
70526 +
70527 +typedef struct
70528 +{
70529 + t_Handle h_Mem;
70530 + uintptr_t baseAddr;
70531 + uint32_t size;
70532 +} t_FmMuram;
70533 +
70534 +
70535 +void FmMuramClear(t_Handle h_FmMuram)
70536 +{
70537 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70538 +
70539 + SANITY_CHECK_RETURN(h_FmMuram, E_INVALID_HANDLE);
70540 + IOMemSet32(UINT_TO_PTR(p_FmMuram->baseAddr), 0, p_FmMuram->size);
70541 +}
70542 +
70543 +
70544 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size)
70545 +{
70546 + t_Handle h_Mem;
70547 + t_FmMuram *p_FmMuram;
70548 +
70549 + if (!baseAddress)
70550 + {
70551 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress 0 is not supported"));
70552 + return NULL;
70553 + }
70554 +
70555 + if (baseAddress%4)
70556 + {
70557 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress not 4 bytes aligned!"));
70558 + return NULL;
70559 + }
70560 +
70561 + /* Allocate FM MURAM structure */
70562 + p_FmMuram = (t_FmMuram *) XX_Malloc(sizeof(t_FmMuram));
70563 + if (!p_FmMuram)
70564 + {
70565 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MURAM driver structure"));
70566 + return NULL;
70567 + }
70568 + memset(p_FmMuram, 0, sizeof(t_FmMuram));
70569 +
70570 +
70571 + if ((MM_Init(&h_Mem, baseAddress, size) != E_OK) || (!h_Mem))
70572 + {
70573 + XX_Free(p_FmMuram);
70574 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM partition!!!"));
70575 + return NULL;
70576 + }
70577 +
70578 + /* Initialize FM MURAM parameters which will be kept by the driver */
70579 + p_FmMuram->baseAddr = baseAddress;
70580 + p_FmMuram->size = size;
70581 + p_FmMuram->h_Mem = h_Mem;
70582 +
70583 + return p_FmMuram;
70584 +}
70585 +
70586 +t_Error FM_MURAM_Free(t_Handle h_FmMuram)
70587 +{
70588 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70589 +
70590 + if (p_FmMuram->h_Mem)
70591 + MM_Free(p_FmMuram->h_Mem);
70592 +
70593 + XX_Free(h_FmMuram);
70594 +
70595 + return E_OK;
70596 +}
70597 +
70598 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align)
70599 +{
70600 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70601 + uintptr_t addr;
70602 +
70603 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70604 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70605 +
70606 + addr = (uintptr_t)MM_Get(p_FmMuram->h_Mem, size, align ,"FM MURAM");
70607 +
70608 + if (addr == ILLEGAL_BASE)
70609 + return NULL;
70610 +
70611 + return UINT_TO_PTR(addr);
70612 +}
70613 +
70614 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size)
70615 +{
70616 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70617 + uintptr_t addr;
70618 +
70619 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70620 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70621 +
70622 + addr = (uintptr_t)MM_GetForce(p_FmMuram->h_Mem, base, size, "FM MURAM");
70623 +
70624 + if (addr == ILLEGAL_BASE)
70625 + return NULL;
70626 +
70627 + return UINT_TO_PTR(addr);
70628 +}
70629 +
70630 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr)
70631 +{
70632 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70633 +
70634 + SANITY_CHECK_RETURN_ERROR(h_FmMuram, E_INVALID_HANDLE);
70635 + SANITY_CHECK_RETURN_ERROR(p_FmMuram->h_Mem, E_INVALID_HANDLE);
70636 +
70637 + if (MM_Put(p_FmMuram->h_Mem, PTR_TO_UINT(ptr)) == 0)
70638 + RETURN_ERROR(MINOR, E_INVALID_ADDRESS, ("memory pointer!!!"));
70639 +
70640 + return E_OK;
70641 +}
70642 +
70643 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram)
70644 +{
70645 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70646 +
70647 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, 0);
70648 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, 0);
70649 +
70650 + return MM_GetFreeMemSize(p_FmMuram->h_Mem);
70651 +}
70652 --- /dev/null
70653 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
70654 @@ -0,0 +1,1398 @@
70655 +/*
70656 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70657 + *
70658 + * Redistribution and use in source and binary forms, with or without
70659 + * modification, are permitted provided that the following conditions are met:
70660 + * * Redistributions of source code must retain the above copyright
70661 + * notice, this list of conditions and the following disclaimer.
70662 + * * Redistributions in binary form must reproduce the above copyright
70663 + * notice, this list of conditions and the following disclaimer in the
70664 + * documentation and/or other materials provided with the distribution.
70665 + * * Neither the name of Freescale Semiconductor nor the
70666 + * names of its contributors may be used to endorse or promote products
70667 + * derived from this software without specific prior written permission.
70668 + *
70669 + *
70670 + * ALTERNATIVELY, this software may be distributed under the terms of the
70671 + * GNU General Public License ("GPL") as published by the Free Software
70672 + * Foundation, either version 2 of that License or (at your option) any
70673 + * later version.
70674 + *
70675 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70676 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70677 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70678 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70679 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70680 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70681 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70682 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70683 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70684 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70685 + */
70686 +
70687 +
70688 +#include <linux/math64.h>
70689 +#include "fsl_fman.h"
70690 +#include "dpaa_integration_ext.h"
70691 +
70692 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg)
70693 +{
70694 + uint32_t event, mask, force;
70695 +
70696 + event = ioread32be(&bmi_rg->fmbm_ievr);
70697 + mask = ioread32be(&bmi_rg->fmbm_ier);
70698 + event &= mask;
70699 + /* clear the forced events */
70700 + force = ioread32be(&bmi_rg->fmbm_ifr);
70701 + if (force & event)
70702 + iowrite32be(force & ~event, &bmi_rg->fmbm_ifr);
70703 + /* clear the acknowledged events */
70704 + iowrite32be(event, &bmi_rg->fmbm_ievr);
70705 + return event;
70706 +}
70707 +
70708 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg)
70709 +{
70710 + uint32_t event, mask, force;
70711 +
70712 + event = ioread32be(&qmi_rg->fmqm_eie);
70713 + mask = ioread32be(&qmi_rg->fmqm_eien);
70714 + event &= mask;
70715 +
70716 + /* clear the forced events */
70717 + force = ioread32be(&qmi_rg->fmqm_eif);
70718 + if (force & event)
70719 + iowrite32be(force & ~event, &qmi_rg->fmqm_eif);
70720 + /* clear the acknowledged events */
70721 + iowrite32be(event, &qmi_rg->fmqm_eie);
70722 + return event;
70723 +}
70724 +
70725 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg)
70726 +{
70727 + return ioread32be(&dma_rg->fmdmtcid);
70728 +}
70729 +
70730 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg)
70731 +{
70732 + uint64_t addr;
70733 +
70734 + addr = (uint64_t)ioread32be(&dma_rg->fmdmtal);
70735 + addr |= ((uint64_t)(ioread32be(&dma_rg->fmdmtah)) << 32);
70736 +
70737 + return addr;
70738 +}
70739 +
70740 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg)
70741 +{
70742 + uint32_t status, mask;
70743 +
70744 + status = ioread32be(&dma_rg->fmdmsr);
70745 + mask = ioread32be(&dma_rg->fmdmmr);
70746 +
70747 + /* clear DMA_STATUS_BUS_ERR if mask has no DMA_MODE_BER */
70748 + if ((mask & DMA_MODE_BER) != DMA_MODE_BER)
70749 + status &= ~DMA_STATUS_BUS_ERR;
70750 +
70751 + /* clear relevant bits if mask has no DMA_MODE_ECC */
70752 + if ((mask & DMA_MODE_ECC) != DMA_MODE_ECC)
70753 + status &= ~(DMA_STATUS_FM_SPDAT_ECC |
70754 + DMA_STATUS_READ_ECC |
70755 + DMA_STATUS_SYSTEM_WRITE_ECC |
70756 + DMA_STATUS_FM_WRITE_ECC);
70757 +
70758 + /* clear set events */
70759 + iowrite32be(status, &dma_rg->fmdmsr);
70760 +
70761 + return status;
70762 +}
70763 +
70764 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg)
70765 +{
70766 + uint32_t event;
70767 +
70768 + event = ioread32be(&fpm_rg->fmfp_ee);
70769 + /* clear the all occurred events */
70770 + iowrite32be(event, &fpm_rg->fmfp_ee);
70771 + return event;
70772 +}
70773 +
70774 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg)
70775 +{
70776 + uint32_t event, mask;
70777 +
70778 + event = ioread32be(&fpm_rg->fm_rcr);
70779 + mask = ioread32be(&fpm_rg->fm_rie);
70780 +
70781 + /* clear MURAM event bit (do not clear IRAM event) */
70782 + iowrite32be(event & ~FPM_RAM_IRAM_ECC, &fpm_rg->fm_rcr);
70783 +
70784 + if ((mask & FPM_MURAM_ECC_ERR_EX_EN))
70785 + return event;
70786 + else
70787 + return 0;
70788 +}
70789 +
70790 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg)
70791 +{
70792 + uint32_t event, mask;
70793 +
70794 + event = ioread32be(&fpm_rg->fm_rcr) ;
70795 + mask = ioread32be(&fpm_rg->fm_rie);
70796 + /* clear IRAM event bit (do not clear MURAM event) */
70797 + iowrite32be(event & ~FPM_RAM_MURAM_ECC,
70798 + &fpm_rg->fm_rcr);
70799 +
70800 + if ((mask & FPM_IRAM_ECC_ERR_EX_EN))
70801 + return event;
70802 + else
70803 + return 0;
70804 +}
70805 +
70806 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg)
70807 +{
70808 + uint32_t event, mask, force;
70809 +
70810 + event = ioread32be(&qmi_rg->fmqm_ie);
70811 + mask = ioread32be(&qmi_rg->fmqm_ien);
70812 + event &= mask;
70813 + /* clear the forced events */
70814 + force = ioread32be(&qmi_rg->fmqm_if);
70815 + if (force & event)
70816 + iowrite32be(force & ~event, &qmi_rg->fmqm_if);
70817 + /* clear the acknowledged events */
70818 + iowrite32be(event, &qmi_rg->fmqm_ie);
70819 + return event;
70820 +}
70821 +
70822 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
70823 + uint8_t count1ubit,
70824 + uint16_t fm_clk_freq)
70825 +{
70826 + uint32_t tmp;
70827 + uint64_t frac;
70828 + uint32_t intgr;
70829 + uint32_t ts_freq = (uint32_t)(1 << count1ubit); /* in Mhz */
70830 +
70831 + /* configure timestamp so that bit 8 will count 1 microsecond
70832 + * Find effective count rate at TIMESTAMP least significant bits:
70833 + * Effective_Count_Rate = 1MHz x 2^8 = 256MHz
70834 + * Find frequency ratio between effective count rate and the clock:
70835 + * Effective_Count_Rate / CLK e.g. for 600 MHz clock:
70836 + * 256/600 = 0.4266666... */
70837 +
70838 + intgr = ts_freq / fm_clk_freq;
70839 + /* we multiply by 2^16 to keep the fraction of the division
70840 + * we do not div back, since we write this value as a fraction
70841 + * see spec */
70842 +
70843 + frac = ((uint64_t)ts_freq << 16) - ((uint64_t)intgr << 16) * fm_clk_freq;
70844 + /* we check remainder of the division in order to round up if not int */
70845 + if (do_div(frac, fm_clk_freq))
70846 + frac++;
70847 +
70848 + tmp = (intgr << FPM_TS_INT_SHIFT) | (uint16_t)frac;
70849 + iowrite32be(tmp, &fpm_rg->fmfp_tsc2);
70850 +
70851 + /* enable timestamp with original clock */
70852 + iowrite32be(FPM_TS_CTL_EN, &fpm_rg->fmfp_tsc1);
70853 +}
70854 +
70855 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg)
70856 +{
70857 + return ioread32be(&fpm_rg->fm_epi);
70858 +}
70859 +
70860 +
70861 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg)
70862 +{
70863 + int timeout = 100;
70864 +
70865 + iowrite32be(0x40000000, &fpm_rg->fmfp_extc);
70866 +
70867 + while ((ioread32be(&fpm_rg->fmfp_extc) & 0x40000000) && --timeout)
70868 + udelay(10);
70869 +
70870 + if (!timeout)
70871 + return -EBUSY;
70872 + return 0;
70873 +}
70874 +
70875 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg,
70876 + uint8_t event_reg_id,
70877 + uint32_t enable_events)
70878 +{
70879 + iowrite32be(enable_events, &fpm_rg->fmfp_cee[event_reg_id]);
70880 +}
70881 +
70882 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id)
70883 +{
70884 + return ioread32be(&fpm_rg->fmfp_cee[event_reg_id]);
70885 +}
70886 +
70887 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
70888 + uint8_t port_id,
70889 + uint8_t num_fman_ctrls,
70890 + uint32_t or_fman_ctrl)
70891 +{
70892 + uint32_t tmp = 0;
70893 +
70894 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
70895 + /*TODO - maybe to put CTL# according to another criteria*/
70896 + if (num_fman_ctrls == 2)
70897 + tmp = FPM_PRT_FM_CTL2 | FPM_PRT_FM_CTL1;
70898 + /* order restoration */
70899 + tmp |= (or_fman_ctrl << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | or_fman_ctrl;
70900 +
70901 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
70902 +}
70903 +
70904 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
70905 + uint8_t port_id,
70906 + bool independent_mode,
70907 + bool is_rx_port)
70908 +{
70909 + uint32_t tmp = 0;
70910 +
70911 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
70912 + if (independent_mode) {
70913 + if (is_rx_port)
70914 + tmp |= (FPM_PRT_FM_CTL1 <<
70915 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL1;
70916 + else
70917 + tmp |= (FPM_PRT_FM_CTL2 <<
70918 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL2;
70919 + } else {
70920 + tmp |= (FPM_PRT_FM_CTL2|FPM_PRT_FM_CTL1);
70921 +
70922 + /* order restoration */
70923 + if (port_id % 2)
70924 + tmp |= (FPM_PRT_FM_CTL1 <<
70925 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
70926 + else
70927 + tmp |= (FPM_PRT_FM_CTL2 <<
70928 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
70929 + }
70930 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
70931 +}
70932 +
70933 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg)
70934 +{
70935 + return (uint8_t)ioread32be(&qmi_rg->fmqm_gc);
70936 +}
70937 +
70938 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg)
70939 +{
70940 + return (uint8_t)(ioread32be(&qmi_rg->fmqm_gc) >> 8);
70941 +}
70942 +
70943 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
70944 +{
70945 + uint32_t tmp_reg;
70946 +
70947 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
70948 + tmp_reg &= ~QMI_CFG_ENQ_MASK;
70949 + tmp_reg |= ((uint32_t)val << 8);
70950 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
70951 +}
70952 +
70953 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
70954 +{
70955 + uint32_t tmp_reg;
70956 +
70957 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
70958 + tmp_reg &= ~QMI_CFG_DEQ_MASK;
70959 + tmp_reg |= (uint32_t)val;
70960 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
70961 +}
70962 +
70963 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg)
70964 +{
70965 + iowrite32be(0, &fpm_rg->fmfp_mxd);
70966 +}
70967 +
70968 +void fman_set_liodn_per_port(struct fman_rg *fman_rg, uint8_t port_id,
70969 + uint16_t liodn_base,
70970 + uint16_t liodn_ofst)
70971 +{
70972 + uint32_t tmp;
70973 +
70974 + if ((port_id > 63) || (port_id < 1))
70975 + return;
70976 +
70977 + /* set LIODN base for this port */
70978 + tmp = ioread32be(&fman_rg->dma_rg->fmdmplr[port_id / 2]);
70979 + if (port_id % 2) {
70980 + tmp &= ~FM_LIODN_BASE_MASK;
70981 + tmp |= (uint32_t)liodn_base;
70982 + } else {
70983 + tmp &= ~(FM_LIODN_BASE_MASK << DMA_LIODN_SHIFT);
70984 + tmp |= (uint32_t)liodn_base << DMA_LIODN_SHIFT;
70985 + }
70986 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmplr[port_id / 2]);
70987 + iowrite32be((uint32_t)liodn_ofst,
70988 + &fman_rg->bmi_rg->fmbm_spliodn[port_id - 1]);
70989 +}
70990 +
70991 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
70992 +{
70993 + return (bool)!!(ioread32be(&fpm_rg->fmfp_ps[port_id]) & FPM_PS_STALLED);
70994 +}
70995 +
70996 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
70997 +{
70998 + uint32_t tmp;
70999 +
71000 + tmp = (uint32_t)((port_id << FPM_PORT_FM_CTL_PORTID_SHIFT) |
71001 + FPM_PRC_REALSE_STALLED);
71002 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
71003 +}
71004 +
71005 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t mac_id, bool is_10g)
71006 +{
71007 + uint32_t msk, timeout = 100;
71008 +
71009 + /* Get the relevant bit mask */
71010 + if (is_10g) {
71011 + switch (mac_id) {
71012 + case(0):
71013 + msk = FPM_RSTC_10G0_RESET;
71014 + break;
71015 + case(1):
71016 + msk = FPM_RSTC_10G1_RESET;
71017 + break;
71018 + default:
71019 + return -EINVAL;
71020 + }
71021 + } else {
71022 + switch (mac_id) {
71023 + case(0):
71024 + msk = FPM_RSTC_1G0_RESET;
71025 + break;
71026 + case(1):
71027 + msk = FPM_RSTC_1G1_RESET;
71028 + break;
71029 + case(2):
71030 + msk = FPM_RSTC_1G2_RESET;
71031 + break;
71032 + case(3):
71033 + msk = FPM_RSTC_1G3_RESET;
71034 + break;
71035 + case(4):
71036 + msk = FPM_RSTC_1G4_RESET;
71037 + break;
71038 + case (5):
71039 + msk = FPM_RSTC_1G5_RESET;
71040 + break;
71041 + case (6):
71042 + msk = FPM_RSTC_1G6_RESET;
71043 + break;
71044 + case (7):
71045 + msk = FPM_RSTC_1G7_RESET;
71046 + break;
71047 + default:
71048 + return -EINVAL;
71049 + }
71050 + }
71051 + /* reset */
71052 + iowrite32be(msk, &fpm_rg->fm_rstc);
71053 + while ((ioread32be(&fpm_rg->fm_rstc) & msk) && --timeout)
71054 + udelay(10);
71055 +
71056 + if (!timeout)
71057 + return -EBUSY;
71058 + return 0;
71059 +}
71060 +
71061 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71062 +{
71063 + uint32_t tmp_reg;
71064 +
71065 + if ((port_id > 63) || (port_id < 1))
71066 + return 0;
71067 +
71068 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id - 1]);
71069 + return (uint16_t)((tmp_reg & BMI_FIFO_SIZE_MASK) + 1);
71070 +}
71071 +
71072 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg)
71073 +{
71074 + uint32_t reg, res;
71075 +
71076 + reg = ioread32be(&bmi_rg->fmbm_cfg1);
71077 + res = (reg >> BMI_CFG1_FIFO_SIZE_SHIFT) & 0x3ff;
71078 + return res * FMAN_BMI_FIFO_UNITS;
71079 +}
71080 +
71081 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
71082 + uint8_t port_id)
71083 +{
71084 + uint32_t tmp_reg;
71085 +
71086 + if ((port_id > 63) || (port_id < 1))
71087 + return 0;
71088 +
71089 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id-1]);
71090 + return (uint16_t)((tmp_reg & BMI_EXTRA_FIFO_SIZE_MASK) >>
71091 + BMI_EXTRA_FIFO_SIZE_SHIFT);
71092 +}
71093 +
71094 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
71095 + uint8_t port_id,
71096 + uint32_t sz_fifo,
71097 + uint32_t extra_sz_fifo)
71098 +{
71099 + uint32_t tmp;
71100 +
71101 + if ((port_id > 63) || (port_id < 1))
71102 + return;
71103 +
71104 + /* calculate reg */
71105 + tmp = (uint32_t)((sz_fifo / FMAN_BMI_FIFO_UNITS - 1) |
71106 + ((extra_sz_fifo / FMAN_BMI_FIFO_UNITS) <<
71107 + BMI_EXTRA_FIFO_SIZE_SHIFT));
71108 + iowrite32be(tmp, &bmi_rg->fmbm_pfs[port_id - 1]);
71109 +}
71110 +
71111 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71112 +{
71113 + uint32_t tmp;
71114 +
71115 + if ((port_id > 63) || (port_id < 1))
71116 + return 0;
71117 +
71118 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71119 + return (uint8_t)(((tmp & BMI_NUM_OF_TASKS_MASK) >>
71120 + BMI_NUM_OF_TASKS_SHIFT) + 1);
71121 +}
71122 +
71123 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71124 +{
71125 + uint32_t tmp;
71126 +
71127 + if ((port_id > 63) || (port_id < 1))
71128 + return 0;
71129 +
71130 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71131 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_TASKS_MASK) >>
71132 + BMI_EXTRA_NUM_OF_TASKS_SHIFT);
71133 +}
71134 +
71135 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
71136 + uint8_t port_id,
71137 + uint8_t num_tasks,
71138 + uint8_t num_extra_tasks)
71139 +{
71140 + uint32_t tmp;
71141 +
71142 + if ((port_id > 63) || (port_id < 1))
71143 + return;
71144 +
71145 + /* calculate reg */
71146 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71147 + ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
71148 + tmp |= (uint32_t)(((num_tasks - 1) << BMI_NUM_OF_TASKS_SHIFT) |
71149 + (num_extra_tasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
71150 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71151 +}
71152 +
71153 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71154 +{
71155 + uint32_t tmp;
71156 +
71157 + if ((port_id > 63) || (port_id < 1))
71158 + return 0;
71159 +
71160 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71161 + return (uint8_t)(((tmp & BMI_NUM_OF_DMAS_MASK) >>
71162 + BMI_NUM_OF_DMAS_SHIFT) + 1);
71163 +}
71164 +
71165 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71166 +{
71167 + uint32_t tmp;
71168 +
71169 + if ((port_id > 63) || (port_id < 1))
71170 + return 0;
71171 +
71172 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71173 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_DMAS_MASK) >>
71174 + BMI_EXTRA_NUM_OF_DMAS_SHIFT);
71175 +}
71176 +
71177 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
71178 + uint8_t port_id,
71179 + uint8_t num_open_dmas,
71180 + uint8_t num_extra_open_dmas,
71181 + uint8_t total_num_dmas)
71182 +{
71183 + uint32_t tmp = 0;
71184 +
71185 + if ((port_id > 63) || (port_id < 1))
71186 + return;
71187 +
71188 + /* calculate reg */
71189 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71190 + ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
71191 + tmp |= (uint32_t)(((num_open_dmas-1) << BMI_NUM_OF_DMAS_SHIFT) |
71192 + (num_extra_open_dmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
71193 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71194 +
71195 + /* update total num of DMA's with committed number of open DMAS,
71196 + * and max uncommitted pool. */
71197 + if (total_num_dmas)
71198 + {
71199 + tmp = ioread32be(&bmi_rg->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
71200 + tmp |= (uint32_t)(total_num_dmas - 1) << BMI_CFG2_DMAS_SHIFT;
71201 + iowrite32be(tmp, &bmi_rg->fmbm_cfg2);
71202 + }
71203 +}
71204 +
71205 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
71206 + uint8_t port_id,
71207 + uint8_t base_storage_profile,
71208 + uint8_t log2_num_of_profiles)
71209 +{
71210 + uint32_t tmp = 0;
71211 + if ((port_id > 63) || (port_id < 1))
71212 + return;
71213 +
71214 + tmp = ioread32be(&bmi_rg->fmbm_spliodn[port_id-1]);
71215 + tmp |= (uint32_t)((uint32_t)base_storage_profile & 0x3f) << 16;
71216 + tmp |= (uint32_t)log2_num_of_profiles << 28;
71217 + iowrite32be(tmp, &bmi_rg->fmbm_spliodn[port_id-1]);
71218 +}
71219 +
71220 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
71221 + uint32_t congestion_group_id,
71222 + uint8_t priority_bit_map,
71223 + uint32_t reg_num)
71224 +{
71225 + uint32_t offset, tmp = 0;
71226 +
71227 + offset = (congestion_group_id%4)*8;
71228 +
71229 + tmp = ioread32be(&cpg_rg[reg_num]);
71230 + tmp &= ~(0xFF<<offset);
71231 + tmp |= (uint32_t)priority_bit_map << offset;
71232 +
71233 + iowrite32be(tmp,&cpg_rg[reg_num]);
71234 +}
71235 +
71236 +/*****************************************************************************/
71237 +/* API Init unit functions */
71238 +/*****************************************************************************/
71239 +void fman_defconfig(struct fman_cfg *cfg, bool is_master)
71240 +{
71241 + memset(cfg, 0, sizeof(struct fman_cfg));
71242 +
71243 + cfg->catastrophic_err = DEFAULT_CATASTROPHIC_ERR;
71244 + cfg->dma_err = DEFAULT_DMA_ERR;
71245 + cfg->halt_on_external_activ = DEFAULT_HALT_ON_EXTERNAL_ACTIVATION;
71246 + cfg->halt_on_unrecov_ecc_err = DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR;
71247 + cfg->en_iram_test_mode = FALSE;
71248 + cfg->en_muram_test_mode = FALSE;
71249 + cfg->external_ecc_rams_enable = DEFAULT_EXTERNAL_ECC_RAMS_ENABLE;
71250 +
71251 + if (!is_master)
71252 + return;
71253 +
71254 + cfg->dma_aid_override = DEFAULT_AID_OVERRIDE;
71255 + cfg->dma_aid_mode = DEFAULT_AID_MODE;
71256 + cfg->dma_comm_qtsh_clr_emer = DEFAULT_DMA_COMM_Q_LOW;
71257 + cfg->dma_comm_qtsh_asrt_emer = DEFAULT_DMA_COMM_Q_HIGH;
71258 + cfg->dma_cache_override = DEFAULT_CACHE_OVERRIDE;
71259 + cfg->dma_cam_num_of_entries = DEFAULT_DMA_CAM_NUM_OF_ENTRIES;
71260 + cfg->dma_dbg_cnt_mode = DEFAULT_DMA_DBG_CNT_MODE;
71261 + cfg->dma_en_emergency = DEFAULT_DMA_EN_EMERGENCY;
71262 + cfg->dma_sos_emergency = DEFAULT_DMA_SOS_EMERGENCY;
71263 + cfg->dma_watchdog = DEFAULT_DMA_WATCHDOG;
71264 + cfg->dma_en_emergency_smoother = DEFAULT_DMA_EN_EMERGENCY_SMOOTHER;
71265 + cfg->dma_emergency_switch_counter = DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER;
71266 + cfg->disp_limit_tsh = DEFAULT_DISP_LIMIT;
71267 + cfg->prs_disp_tsh = DEFAULT_PRS_DISP_TH;
71268 + cfg->plcr_disp_tsh = DEFAULT_PLCR_DISP_TH;
71269 + cfg->kg_disp_tsh = DEFAULT_KG_DISP_TH;
71270 + cfg->bmi_disp_tsh = DEFAULT_BMI_DISP_TH;
71271 + cfg->qmi_enq_disp_tsh = DEFAULT_QMI_ENQ_DISP_TH;
71272 + cfg->qmi_deq_disp_tsh = DEFAULT_QMI_DEQ_DISP_TH;
71273 + cfg->fm_ctl1_disp_tsh = DEFAULT_FM_CTL1_DISP_TH;
71274 + cfg->fm_ctl2_disp_tsh = DEFAULT_FM_CTL2_DISP_TH;
71275 +
71276 + cfg->pedantic_dma = FALSE;
71277 + cfg->tnum_aging_period = DEFAULT_TNUM_AGING_PERIOD;
71278 + cfg->dma_stop_on_bus_error = FALSE;
71279 + cfg->qmi_deq_option_support = FALSE;
71280 +}
71281 +
71282 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71283 +{
71284 + uint32_t tmp_reg;
71285 +
71286 + /* read the values from the registers as they are initialized by the HW with
71287 + * the required values.
71288 + */
71289 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg1);
71290 + cfg->total_fifo_size =
71291 + (((tmp_reg & BMI_TOTAL_FIFO_SIZE_MASK) >> BMI_CFG1_FIFO_SIZE_SHIFT) + 1) * FMAN_BMI_FIFO_UNITS;
71292 +
71293 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg2);
71294 + cfg->total_num_of_tasks =
71295 + (uint8_t)(((tmp_reg & BMI_TOTAL_NUM_OF_TASKS_MASK) >> BMI_CFG2_TASKS_SHIFT) + 1);
71296 +
71297 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmtr);
71298 + cfg->dma_comm_qtsh_asrt_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71299 +
71300 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmhy);
71301 + cfg->dma_comm_qtsh_clr_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71302 +
71303 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmmr);
71304 + cfg->dma_cache_override = (enum fman_dma_cache_override)((tmp_reg & DMA_MODE_CACHE_OR_MASK) >> DMA_MODE_CACHE_OR_SHIFT);
71305 + cfg->dma_cam_num_of_entries = (uint8_t)((((tmp_reg & DMA_MODE_CEN_MASK) >> DMA_MODE_CEN_SHIFT) +1)*DMA_CAM_UNITS);
71306 + cfg->dma_aid_override = (bool)((tmp_reg & DMA_MODE_AID_OR)? TRUE:FALSE);
71307 + cfg->dma_dbg_cnt_mode = (enum fman_dma_dbg_cnt_mode)((tmp_reg & DMA_MODE_DBG_MASK) >> DMA_MODE_DBG_SHIFT);
71308 + cfg->dma_en_emergency = (bool)((tmp_reg & DMA_MODE_EB)? TRUE : FALSE);
71309 +
71310 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_mxd);
71311 + cfg->disp_limit_tsh = (uint8_t)((tmp_reg & FPM_DISP_LIMIT_MASK) >> FPM_DISP_LIMIT_SHIFT);
71312 +
71313 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist1);
71314 + cfg->prs_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PRS_MASK ) >> FPM_THR1_PRS_SHIFT);
71315 + cfg->plcr_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_KG_MASK ) >> FPM_THR1_KG_SHIFT);
71316 + cfg->kg_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PLCR_MASK ) >> FPM_THR1_PLCR_SHIFT);
71317 + cfg->bmi_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_BMI_MASK ) >> FPM_THR1_BMI_SHIFT);
71318 +
71319 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist2);
71320 + cfg->qmi_enq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_ENQ_MASK ) >> FPM_THR2_QMI_ENQ_SHIFT);
71321 + cfg->qmi_deq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_DEQ_MASK ) >> FPM_THR2_QMI_DEQ_SHIFT);
71322 + cfg->fm_ctl1_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL1_MASK ) >> FPM_THR2_FM_CTL1_SHIFT);
71323 + cfg->fm_ctl2_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL2_MASK ) >> FPM_THR2_FM_CTL2_SHIFT);
71324 +
71325 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmsetr);
71326 + cfg->dma_sos_emergency = tmp_reg;
71327 +
71328 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmwcr);
71329 + cfg->dma_watchdog = tmp_reg/cfg->clk_freq;
71330 +
71331 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmemsr);
71332 + cfg->dma_en_emergency_smoother = (bool)((tmp_reg & DMA_EMSR_EMSTR_MASK)? TRUE : FALSE);
71333 + cfg->dma_emergency_switch_counter = (tmp_reg & DMA_EMSR_EMSTR_MASK);
71334 +}
71335 +
71336 +void fman_reset(struct fman_fpm_regs *fpm_rg)
71337 +{
71338 + iowrite32be(FPM_RSTC_FM_RESET, &fpm_rg->fm_rstc);
71339 +}
71340 +
71341 +/**************************************************************************//**
71342 + @Function FM_Init
71343 +
71344 + @Description Initializes the FM module
71345 +
71346 + @Param[in] h_Fm - FM module descriptor
71347 +
71348 + @Return E_OK on success; Error code otherwise.
71349 +*//***************************************************************************/
71350 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg)
71351 +{
71352 + uint32_t tmp_reg;
71353 +
71354 + /**********************/
71355 + /* Init DMA Registers */
71356 + /**********************/
71357 + /* clear status reg events */
71358 + /* oren - check!!! */
71359 + tmp_reg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC |
71360 + DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
71361 + iowrite32be(ioread32be(&dma_rg->fmdmsr) | tmp_reg,
71362 + &dma_rg->fmdmsr);
71363 +
71364 + /* configure mode register */
71365 + tmp_reg = 0;
71366 + tmp_reg |= cfg->dma_cache_override << DMA_MODE_CACHE_OR_SHIFT;
71367 + if (cfg->dma_aid_override)
71368 + tmp_reg |= DMA_MODE_AID_OR;
71369 + if (cfg->exceptions & FMAN_EX_DMA_BUS_ERROR)
71370 + tmp_reg |= DMA_MODE_BER;
71371 + if ((cfg->exceptions & FMAN_EX_DMA_SYSTEM_WRITE_ECC) |
71372 + (cfg->exceptions & FMAN_EX_DMA_READ_ECC) |
71373 + (cfg->exceptions & FMAN_EX_DMA_FM_WRITE_ECC))
71374 + tmp_reg |= DMA_MODE_ECC;
71375 + if (cfg->dma_stop_on_bus_error)
71376 + tmp_reg |= DMA_MODE_SBER;
71377 + if(cfg->dma_axi_dbg_num_of_beats)
71378 + tmp_reg |= (uint32_t)(DMA_MODE_AXI_DBG_MASK &
71379 + ((cfg->dma_axi_dbg_num_of_beats - 1) << DMA_MODE_AXI_DBG_SHIFT));
71380 +
71381 + if (cfg->dma_en_emergency) {
71382 + tmp_reg |= cfg->dma_emergency_bus_select;
71383 + tmp_reg |= cfg->dma_emergency_level << DMA_MODE_EMER_LVL_SHIFT;
71384 + if (cfg->dma_en_emergency_smoother)
71385 + iowrite32be(cfg->dma_emergency_switch_counter,
71386 + &dma_rg->fmdmemsr);
71387 + }
71388 + tmp_reg |= ((cfg->dma_cam_num_of_entries / DMA_CAM_UNITS) - 1) <<
71389 + DMA_MODE_CEN_SHIFT;
71390 + tmp_reg |= DMA_MODE_SECURE_PROT;
71391 + tmp_reg |= cfg->dma_dbg_cnt_mode << DMA_MODE_DBG_SHIFT;
71392 + tmp_reg |= cfg->dma_aid_mode << DMA_MODE_AID_MODE_SHIFT;
71393 +
71394 + if (cfg->pedantic_dma)
71395 + tmp_reg |= DMA_MODE_EMER_READ;
71396 +
71397 + iowrite32be(tmp_reg, &dma_rg->fmdmmr);
71398 +
71399 + /* configure thresholds register */
71400 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_asrt_emer <<
71401 + DMA_THRESH_COMMQ_SHIFT) |
71402 + ((uint32_t)cfg->dma_read_buf_tsh_asrt_emer <<
71403 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71404 + ((uint32_t)cfg->dma_write_buf_tsh_asrt_emer);
71405 +
71406 + iowrite32be(tmp_reg, &dma_rg->fmdmtr);
71407 +
71408 + /* configure hysteresis register */
71409 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_clr_emer <<
71410 + DMA_THRESH_COMMQ_SHIFT) |
71411 + ((uint32_t)cfg->dma_read_buf_tsh_clr_emer <<
71412 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71413 + ((uint32_t)cfg->dma_write_buf_tsh_clr_emer);
71414 +
71415 + iowrite32be(tmp_reg, &dma_rg->fmdmhy);
71416 +
71417 + /* configure emergency threshold */
71418 + iowrite32be(cfg->dma_sos_emergency, &dma_rg->fmdmsetr);
71419 +
71420 + /* configure Watchdog */
71421 + iowrite32be((cfg->dma_watchdog * cfg->clk_freq),
71422 + &dma_rg->fmdmwcr);
71423 +
71424 + iowrite32be(cfg->cam_base_addr, &dma_rg->fmdmebcr);
71425 +
71426 + return 0;
71427 +}
71428 +
71429 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg)
71430 +{
71431 + uint32_t tmp_reg;
71432 + int i;
71433 +
71434 + /**********************/
71435 + /* Init FPM Registers */
71436 + /**********************/
71437 + tmp_reg = (uint32_t)(cfg->disp_limit_tsh << FPM_DISP_LIMIT_SHIFT);
71438 + iowrite32be(tmp_reg, &fpm_rg->fmfp_mxd);
71439 +
71440 + tmp_reg = (((uint32_t)cfg->prs_disp_tsh << FPM_THR1_PRS_SHIFT) |
71441 + ((uint32_t)cfg->kg_disp_tsh << FPM_THR1_KG_SHIFT) |
71442 + ((uint32_t)cfg->plcr_disp_tsh << FPM_THR1_PLCR_SHIFT) |
71443 + ((uint32_t)cfg->bmi_disp_tsh << FPM_THR1_BMI_SHIFT));
71444 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist1);
71445 +
71446 + tmp_reg = (((uint32_t)cfg->qmi_enq_disp_tsh << FPM_THR2_QMI_ENQ_SHIFT) |
71447 + ((uint32_t)cfg->qmi_deq_disp_tsh << FPM_THR2_QMI_DEQ_SHIFT) |
71448 + ((uint32_t)cfg->fm_ctl1_disp_tsh << FPM_THR2_FM_CTL1_SHIFT) |
71449 + ((uint32_t)cfg->fm_ctl2_disp_tsh << FPM_THR2_FM_CTL2_SHIFT));
71450 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist2);
71451 +
71452 + /* define exceptions and error behavior */
71453 + tmp_reg = 0;
71454 + /* Clear events */
71455 + tmp_reg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC |
71456 + FPM_EV_MASK_SINGLE_ECC);
71457 + /* enable interrupts */
71458 + if (cfg->exceptions & FMAN_EX_FPM_STALL_ON_TASKS)
71459 + tmp_reg |= FPM_EV_MASK_STALL_EN;
71460 + if (cfg->exceptions & FMAN_EX_FPM_SINGLE_ECC)
71461 + tmp_reg |= FPM_EV_MASK_SINGLE_ECC_EN;
71462 + if (cfg->exceptions & FMAN_EX_FPM_DOUBLE_ECC)
71463 + tmp_reg |= FPM_EV_MASK_DOUBLE_ECC_EN;
71464 + tmp_reg |= (cfg->catastrophic_err << FPM_EV_MASK_CAT_ERR_SHIFT);
71465 + tmp_reg |= (cfg->dma_err << FPM_EV_MASK_DMA_ERR_SHIFT);
71466 + if (!cfg->halt_on_external_activ)
71467 + tmp_reg |= FPM_EV_MASK_EXTERNAL_HALT;
71468 + if (!cfg->halt_on_unrecov_ecc_err)
71469 + tmp_reg |= FPM_EV_MASK_ECC_ERR_HALT;
71470 + iowrite32be(tmp_reg, &fpm_rg->fmfp_ee);
71471 +
71472 + /* clear all fmCtls event registers */
71473 + for (i = 0; i < cfg->num_of_fman_ctrl_evnt_regs; i++)
71474 + iowrite32be(0xFFFFFFFF, &fpm_rg->fmfp_cev[i]);
71475 +
71476 + /* RAM ECC - enable and clear events*/
71477 + /* first we need to clear all parser memory,
71478 + * as it is uninitialized and may cause ECC errors */
71479 + /* event bits */
71480 + tmp_reg = (FPM_RAM_MURAM_ECC | FPM_RAM_IRAM_ECC);
71481 + /* Rams enable not effected by RCR bit, but by a COP configuration */
71482 + if (cfg->external_ecc_rams_enable)
71483 + tmp_reg |= FPM_RAM_RAMS_ECC_EN_SRC_SEL;
71484 +
71485 + /* enable test mode */
71486 + if (cfg->en_muram_test_mode)
71487 + tmp_reg |= FPM_RAM_MURAM_TEST_ECC;
71488 + if (cfg->en_iram_test_mode)
71489 + tmp_reg |= FPM_RAM_IRAM_TEST_ECC;
71490 + iowrite32be(tmp_reg, &fpm_rg->fm_rcr);
71491 +
71492 + tmp_reg = 0;
71493 + if (cfg->exceptions & FMAN_EX_IRAM_ECC) {
71494 + tmp_reg |= FPM_IRAM_ECC_ERR_EX_EN;
71495 + fman_enable_rams_ecc(fpm_rg);
71496 + }
71497 + if (cfg->exceptions & FMAN_EX_NURAM_ECC) {
71498 + tmp_reg |= FPM_MURAM_ECC_ERR_EX_EN;
71499 + fman_enable_rams_ecc(fpm_rg);
71500 + }
71501 + iowrite32be(tmp_reg, &fpm_rg->fm_rie);
71502 +
71503 + return 0;
71504 +}
71505 +
71506 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg)
71507 +{
71508 + uint32_t tmp_reg;
71509 +
71510 + /**********************/
71511 + /* Init BMI Registers */
71512 + /**********************/
71513 +
71514 + /* define common resources */
71515 + tmp_reg = cfg->fifo_base_addr;
71516 + tmp_reg = tmp_reg / BMI_FIFO_ALIGN;
71517 +
71518 + tmp_reg |= ((cfg->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) <<
71519 + BMI_CFG1_FIFO_SIZE_SHIFT);
71520 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg1);
71521 +
71522 + tmp_reg = ((uint32_t)(cfg->total_num_of_tasks - 1) <<
71523 + BMI_CFG2_TASKS_SHIFT);
71524 + /* num of DMA's will be dynamically updated when each port is set */
71525 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg2);
71526 +
71527 + /* define unmaskable exceptions, enable and clear events */
71528 + tmp_reg = 0;
71529 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC |
71530 + BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC |
71531 + BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
71532 + BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
71533 + &bmi_rg->fmbm_ievr);
71534 +
71535 + if (cfg->exceptions & FMAN_EX_BMI_LIST_RAM_ECC)
71536 + tmp_reg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
71537 + if (cfg->exceptions & FMAN_EX_BMI_PIPELINE_ECC)
71538 + tmp_reg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71539 + if (cfg->exceptions & FMAN_EX_BMI_STATISTICS_RAM_ECC)
71540 + tmp_reg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71541 + if (cfg->exceptions & FMAN_EX_BMI_DISPATCH_RAM_ECC)
71542 + tmp_reg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71543 + iowrite32be(tmp_reg, &bmi_rg->fmbm_ier);
71544 +
71545 + return 0;
71546 +}
71547 +
71548 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg)
71549 +{
71550 + uint32_t tmp_reg;
71551 + uint16_t period_in_fm_clocks;
71552 + uint8_t remainder;
71553 + /**********************/
71554 + /* Init QMI Registers */
71555 + /**********************/
71556 + /* Clear error interrupt events */
71557 +
71558 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF,
71559 + &qmi_rg->fmqm_eie);
71560 + tmp_reg = 0;
71561 + if (cfg->exceptions & FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
71562 + tmp_reg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71563 + if (cfg->exceptions & FMAN_EX_QMI_DOUBLE_ECC)
71564 + tmp_reg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
71565 + /* enable events */
71566 + iowrite32be(tmp_reg, &qmi_rg->fmqm_eien);
71567 +
71568 + if (cfg->tnum_aging_period) {
71569 + /* tnum_aging_period is in units of usec, p_FmClockFreq in Mhz */
71570 + period_in_fm_clocks = (uint16_t)
71571 + (cfg->tnum_aging_period * cfg->clk_freq);
71572 + /* period_in_fm_clocks must be a 64 multiply */
71573 + remainder = (uint8_t)(period_in_fm_clocks % 64);
71574 + if (remainder)
71575 + tmp_reg = (uint32_t)((period_in_fm_clocks / 64) + 1);
71576 + else{
71577 + tmp_reg = (uint32_t)(period_in_fm_clocks / 64);
71578 + if (!tmp_reg)
71579 + tmp_reg = 1;
71580 + }
71581 + tmp_reg <<= QMI_TAPC_TAP;
71582 + iowrite32be(tmp_reg, &qmi_rg->fmqm_tapc);
71583 + }
71584 + tmp_reg = 0;
71585 + /* Clear interrupt events */
71586 + iowrite32be(QMI_INTR_EN_SINGLE_ECC, &qmi_rg->fmqm_ie);
71587 + if (cfg->exceptions & FMAN_EX_QMI_SINGLE_ECC)
71588 + tmp_reg |= QMI_INTR_EN_SINGLE_ECC;
71589 + /* enable events */
71590 + iowrite32be(tmp_reg, &qmi_rg->fmqm_ien);
71591 +
71592 + return 0;
71593 +}
71594 +
71595 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71596 +{
71597 + uint32_t cfg_reg = 0;
71598 +
71599 + /**********************/
71600 + /* Enable all modules */
71601 + /**********************/
71602 + /* clear & enable global counters - calculate reg and save for later,
71603 + because it's the same reg for QMI enable */
71604 + cfg_reg = QMI_CFG_EN_COUNTERS;
71605 + if (cfg->qmi_deq_option_support)
71606 + cfg_reg |= (uint32_t)(((cfg->qmi_def_tnums_thresh) << 8) |
71607 + (uint32_t)cfg->qmi_def_tnums_thresh);
71608 +
71609 + iowrite32be(BMI_INIT_START, &fman_rg->bmi_rg->fmbm_init);
71610 + iowrite32be(cfg_reg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN,
71611 + &fman_rg->qmi_rg->fmqm_gc);
71612 +
71613 + return 0;
71614 +}
71615 +
71616 +void fman_free_resources(struct fman_rg *fman_rg)
71617 +{
71618 + /* disable BMI and QMI */
71619 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_init);
71620 + iowrite32be(0, &fman_rg->qmi_rg->fmqm_gc);
71621 +
71622 + /* release BMI resources */
71623 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg2);
71624 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg1);
71625 +
71626 + /* disable ECC */
71627 + iowrite32be(0, &fman_rg->fpm_rg->fm_rcr);
71628 +}
71629 +
71630 +/****************************************************/
71631 +/* API Run-time Control uint functions */
71632 +/****************************************************/
71633 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg)
71634 +{
71635 + return ioread32be(&fpm_rg->fm_npi);
71636 +}
71637 +
71638 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, uint8_t reg_id)
71639 +{
71640 + uint32_t event;
71641 +
71642 + event = ioread32be(&fpm_rg->fmfp_fcev[reg_id]) &
71643 + ioread32be(&fpm_rg->fmfp_cee[reg_id]);
71644 + iowrite32be(event, &fpm_rg->fmfp_cev[reg_id]);
71645 +
71646 + return event;
71647 +}
71648 +
71649 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg)
71650 +{
71651 + return ioread32be(&fpm_rg->fm_epi);
71652 +}
71653 +
71654 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights)
71655 +{
71656 + int i;
71657 + uint8_t shift;
71658 + uint32_t tmp = 0;
71659 +
71660 + for (i = 0; i < 64; i++) {
71661 + if (weights[i] > 1) { /* no need to write 1 since it is 0 */
71662 + /* Add this port to tmp_reg */
71663 + /* (each 8 ports result in one register)*/
71664 + shift = (uint8_t)(32 - 4 * ((i % 8) + 1));
71665 + tmp |= ((weights[i] - 1) << shift);
71666 + }
71667 + if (i % 8 == 7) { /* last in this set */
71668 + iowrite32be(tmp, &bmi_rg->fmbm_arb[i / 8]);
71669 + tmp = 0;
71670 + }
71671 + }
71672 +}
71673 +
71674 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71675 +{
71676 + uint32_t tmp;
71677 +
71678 + tmp = ioread32be(&fpm_rg->fm_rcr);
71679 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71680 + iowrite32be(tmp | FPM_RAM_IRAM_ECC_EN,
71681 + &fpm_rg->fm_rcr);
71682 + else
71683 + iowrite32be(tmp | FPM_RAM_RAMS_ECC_EN |
71684 + FPM_RAM_IRAM_ECC_EN,
71685 + &fpm_rg->fm_rcr);
71686 +}
71687 +
71688 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71689 +{
71690 + uint32_t tmp;
71691 +
71692 + tmp = ioread32be(&fpm_rg->fm_rcr);
71693 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71694 + iowrite32be(tmp & ~FPM_RAM_IRAM_ECC_EN,
71695 + &fpm_rg->fm_rcr);
71696 + else
71697 + iowrite32be(tmp & ~(FPM_RAM_RAMS_ECC_EN | FPM_RAM_IRAM_ECC_EN),
71698 + &fpm_rg->fm_rcr);
71699 +}
71700 +
71701 +int fman_set_exception(struct fman_rg *fman_rg,
71702 + enum fman_exceptions exception,
71703 + bool enable)
71704 +{
71705 + uint32_t tmp;
71706 +
71707 + switch (exception) {
71708 + case(E_FMAN_EX_DMA_BUS_ERROR):
71709 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
71710 + if (enable)
71711 + tmp |= DMA_MODE_BER;
71712 + else
71713 + tmp &= ~DMA_MODE_BER;
71714 + /* disable bus error */
71715 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
71716 + break;
71717 + case(E_FMAN_EX_DMA_READ_ECC):
71718 + case(E_FMAN_EX_DMA_SYSTEM_WRITE_ECC):
71719 + case(E_FMAN_EX_DMA_FM_WRITE_ECC):
71720 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
71721 + if (enable)
71722 + tmp |= DMA_MODE_ECC;
71723 + else
71724 + tmp &= ~DMA_MODE_ECC;
71725 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
71726 + break;
71727 + case(E_FMAN_EX_FPM_STALL_ON_TASKS):
71728 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71729 + if (enable)
71730 + tmp |= FPM_EV_MASK_STALL_EN;
71731 + else
71732 + tmp &= ~FPM_EV_MASK_STALL_EN;
71733 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71734 + break;
71735 + case(E_FMAN_EX_FPM_SINGLE_ECC):
71736 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71737 + if (enable)
71738 + tmp |= FPM_EV_MASK_SINGLE_ECC_EN;
71739 + else
71740 + tmp &= ~FPM_EV_MASK_SINGLE_ECC_EN;
71741 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71742 + break;
71743 + case(E_FMAN_EX_FPM_DOUBLE_ECC):
71744 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71745 + if (enable)
71746 + tmp |= FPM_EV_MASK_DOUBLE_ECC_EN;
71747 + else
71748 + tmp &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
71749 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71750 + break;
71751 + case(E_FMAN_EX_QMI_SINGLE_ECC):
71752 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_ien);
71753 + if (enable)
71754 + tmp |= QMI_INTR_EN_SINGLE_ECC;
71755 + else
71756 + tmp &= ~QMI_INTR_EN_SINGLE_ECC;
71757 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_ien);
71758 + break;
71759 + case(E_FMAN_EX_QMI_DOUBLE_ECC):
71760 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
71761 + if (enable)
71762 + tmp |= QMI_ERR_INTR_EN_DOUBLE_ECC;
71763 + else
71764 + tmp &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
71765 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
71766 + break;
71767 + case(E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID):
71768 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
71769 + if (enable)
71770 + tmp |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71771 + else
71772 + tmp &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71773 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
71774 + break;
71775 + case(E_FMAN_EX_BMI_LIST_RAM_ECC):
71776 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71777 + if (enable)
71778 + tmp |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
71779 + else
71780 + tmp &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
71781 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71782 + break;
71783 + case(E_FMAN_EX_BMI_STORAGE_PROFILE_ECC):
71784 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71785 + if (enable)
71786 + tmp |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71787 + else
71788 + tmp &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71789 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71790 + break;
71791 + case(E_FMAN_EX_BMI_STATISTICS_RAM_ECC):
71792 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71793 + if (enable)
71794 + tmp |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71795 + else
71796 + tmp &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71797 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71798 + break;
71799 + case(E_FMAN_EX_BMI_DISPATCH_RAM_ECC):
71800 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71801 + if (enable)
71802 + tmp |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71803 + else
71804 + tmp &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71805 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71806 + break;
71807 + case(E_FMAN_EX_IRAM_ECC):
71808 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
71809 + if (enable) {
71810 + /* enable ECC if not enabled */
71811 + fman_enable_rams_ecc(fman_rg->fpm_rg);
71812 + /* enable ECC interrupts */
71813 + tmp |= FPM_IRAM_ECC_ERR_EX_EN;
71814 + } else {
71815 + /* ECC mechanism may be disabled,
71816 + * depending on driver status */
71817 + fman_disable_rams_ecc(fman_rg->fpm_rg);
71818 + tmp &= ~FPM_IRAM_ECC_ERR_EX_EN;
71819 + }
71820 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
71821 + break;
71822 + case(E_FMAN_EX_MURAM_ECC):
71823 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
71824 + if (enable) {
71825 + /* enable ECC if not enabled */
71826 + fman_enable_rams_ecc(fman_rg->fpm_rg);
71827 + /* enable ECC interrupts */
71828 + tmp |= FPM_MURAM_ECC_ERR_EX_EN;
71829 + } else {
71830 + /* ECC mechanism may be disabled,
71831 + * depending on driver status */
71832 + fman_disable_rams_ecc(fman_rg->fpm_rg);
71833 + tmp &= ~FPM_MURAM_ECC_ERR_EX_EN;
71834 + }
71835 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
71836 + break;
71837 + default:
71838 + return -EINVAL;
71839 + }
71840 + return 0;
71841 +}
71842 +
71843 +void fman_get_revision(struct fman_fpm_regs *fpm_rg,
71844 + uint8_t *major,
71845 + uint8_t *minor)
71846 +{
71847 + uint32_t tmp;
71848 +
71849 + tmp = ioread32be(&fpm_rg->fm_ip_rev_1);
71850 + *major = (uint8_t)((tmp & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT);
71851 + *minor = (uint8_t)((tmp & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT);
71852 +
71853 +}
71854 +
71855 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
71856 + enum fman_counters reg_name)
71857 +{
71858 + uint32_t ret_val;
71859 +
71860 + switch (reg_name) {
71861 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
71862 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_etfc);
71863 + break;
71864 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
71865 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dtfc);
71866 + break;
71867 + case(E_FMAN_COUNTERS_DEQ_0):
71868 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc0);
71869 + break;
71870 + case(E_FMAN_COUNTERS_DEQ_1):
71871 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc1);
71872 + break;
71873 + case(E_FMAN_COUNTERS_DEQ_2):
71874 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc2);
71875 + break;
71876 + case(E_FMAN_COUNTERS_DEQ_3):
71877 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc3);
71878 + break;
71879 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
71880 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfdc);
71881 + break;
71882 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
71883 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfcc);
71884 + break;
71885 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
71886 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dffc);
71887 + break;
71888 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
71889 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dcc);
71890 + break;
71891 + default:
71892 + ret_val = 0;
71893 + }
71894 + return ret_val;
71895 +}
71896 +
71897 +int fman_modify_counter(struct fman_rg *fman_rg,
71898 + enum fman_counters reg_name,
71899 + uint32_t val)
71900 +{
71901 + /* When applicable (when there is an 'enable counters' bit,
71902 + * check that counters are enabled */
71903 + switch (reg_name) {
71904 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
71905 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
71906 + case(E_FMAN_COUNTERS_DEQ_0):
71907 + case(E_FMAN_COUNTERS_DEQ_1):
71908 + case(E_FMAN_COUNTERS_DEQ_2):
71909 + case(E_FMAN_COUNTERS_DEQ_3):
71910 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
71911 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
71912 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
71913 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
71914 + if (!(ioread32be(&fman_rg->qmi_rg->fmqm_gc) &
71915 + QMI_CFG_EN_COUNTERS))
71916 + return -EINVAL;
71917 + break;
71918 + default:
71919 + break;
71920 + }
71921 + /* Set counter */
71922 + switch (reg_name) {
71923 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
71924 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_etfc);
71925 + break;
71926 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
71927 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dtfc);
71928 + break;
71929 + case(E_FMAN_COUNTERS_DEQ_0):
71930 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc0);
71931 + break;
71932 + case(E_FMAN_COUNTERS_DEQ_1):
71933 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc1);
71934 + break;
71935 + case(E_FMAN_COUNTERS_DEQ_2):
71936 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc2);
71937 + break;
71938 + case(E_FMAN_COUNTERS_DEQ_3):
71939 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc3);
71940 + break;
71941 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
71942 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfdc);
71943 + break;
71944 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
71945 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfcc);
71946 + break;
71947 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
71948 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dffc);
71949 + break;
71950 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
71951 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dcc);
71952 + break;
71953 + case(E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
71954 + iowrite32be(val, &fman_rg->dma_rg->fmdmsefrc);
71955 + break;
71956 + case(E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
71957 + iowrite32be(val, &fman_rg->dma_rg->fmdmsqfrc);
71958 + break;
71959 + case(E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT):
71960 + iowrite32be(val, &fman_rg->dma_rg->fmdmssrc);
71961 + break;
71962 + default:
71963 + break;
71964 + }
71965 + return 0;
71966 +}
71967 +
71968 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg,
71969 + bool is_write,
71970 + bool enable)
71971 +{
71972 + uint32_t msk;
71973 +
71974 + msk = (uint32_t)(is_write ? DMA_MODE_EMER_WRITE : DMA_MODE_EMER_READ);
71975 +
71976 + if (enable)
71977 + iowrite32be(ioread32be(&dma_rg->fmdmmr) | msk,
71978 + &dma_rg->fmdmmr);
71979 + else /* disable */
71980 + iowrite32be(ioread32be(&dma_rg->fmdmmr) & ~msk,
71981 + &dma_rg->fmdmmr);
71982 +}
71983 +
71984 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri)
71985 +{
71986 + uint32_t tmp;
71987 +
71988 + tmp = ioread32be(&dma_rg->fmdmmr) |
71989 + (pri << DMA_MODE_BUS_PRI_SHIFT);
71990 +
71991 + iowrite32be(tmp, &dma_rg->fmdmmr);
71992 +}
71993 +
71994 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg)
71995 +{
71996 + return ioread32be(&dma_rg->fmdmsr);
71997 +}
71998 +
71999 +void fman_force_intr(struct fman_rg *fman_rg,
72000 + enum fman_exceptions exception)
72001 +{
72002 + switch (exception) {
72003 + case E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
72004 + iowrite32be(QMI_ERR_INTR_EN_DEQ_FROM_DEF,
72005 + &fman_rg->qmi_rg->fmqm_eif);
72006 + break;
72007 + case E_FMAN_EX_QMI_SINGLE_ECC:
72008 + iowrite32be(QMI_INTR_EN_SINGLE_ECC,
72009 + &fman_rg->qmi_rg->fmqm_if);
72010 + break;
72011 + case E_FMAN_EX_QMI_DOUBLE_ECC:
72012 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC,
72013 + &fman_rg->qmi_rg->fmqm_eif);
72014 + break;
72015 + case E_FMAN_EX_BMI_LIST_RAM_ECC:
72016 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC,
72017 + &fman_rg->bmi_rg->fmbm_ifr);
72018 + break;
72019 + case E_FMAN_EX_BMI_STORAGE_PROFILE_ECC:
72020 + iowrite32be(BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC,
72021 + &fman_rg->bmi_rg->fmbm_ifr);
72022 + break;
72023 + case E_FMAN_EX_BMI_STATISTICS_RAM_ECC:
72024 + iowrite32be(BMI_ERR_INTR_EN_STATISTICS_RAM_ECC,
72025 + &fman_rg->bmi_rg->fmbm_ifr);
72026 + break;
72027 + case E_FMAN_EX_BMI_DISPATCH_RAM_ECC:
72028 + iowrite32be(BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
72029 + &fman_rg->bmi_rg->fmbm_ifr);
72030 + break;
72031 + default:
72032 + break;
72033 + }
72034 +}
72035 +
72036 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg)
72037 +{
72038 + return (bool)!!(ioread32be(&qmi_rg->fmqm_gs) & QMI_GS_HALT_NOT_BUSY);
72039 +}
72040 +void fman_resume(struct fman_fpm_regs *fpm_rg)
72041 +{
72042 + uint32_t tmp;
72043 +
72044 + tmp = ioread32be(&fpm_rg->fmfp_ee);
72045 + /* clear tmp_reg event bits in order not to clear standing events */
72046 + tmp &= ~(FPM_EV_MASK_DOUBLE_ECC |
72047 + FPM_EV_MASK_STALL |
72048 + FPM_EV_MASK_SINGLE_ECC);
72049 + tmp |= FPM_EV_MASK_RELEASE_FM;
72050 +
72051 + iowrite32be(tmp, &fpm_rg->fmfp_ee);
72052 +}
72053 --- /dev/null
72054 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
72055 @@ -0,0 +1,1214 @@
72056 +/*
72057 + * Copyright 2008-2012 Freescale Semiconductor Inc.
72058 + *
72059 + * Redistribution and use in source and binary forms, with or without
72060 + * modification, are permitted provided that the following conditions are met:
72061 + * * Redistributions of source code must retain the above copyright
72062 + * notice, this list of conditions and the following disclaimer.
72063 + * * Redistributions in binary form must reproduce the above copyright
72064 + * notice, this list of conditions and the following disclaimer in the
72065 + * documentation and/or other materials provided with the distribution.
72066 + * * Neither the name of Freescale Semiconductor nor the
72067 + * names of its contributors may be used to endorse or promote products
72068 + * derived from this software without specific prior written permission.
72069 + *
72070 + *
72071 + * ALTERNATIVELY, this software may be distributed under the terms of the
72072 + * GNU General Public License ("GPL") as published by the Free Software
72073 + * Foundation, either version 2 of that License or (at your option) any
72074 + * later version.
72075 + *
72076 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
72077 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72078 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72079 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
72080 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72081 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72082 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
72083 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72084 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72085 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72086 + */
72087 +
72088 +
72089 +/******************************************************************************
72090 + @File fm_common.h
72091 +
72092 + @Description FM internal structures and definitions.
72093 +*//***************************************************************************/
72094 +#ifndef __FM_COMMON_H
72095 +#define __FM_COMMON_H
72096 +
72097 +#include "error_ext.h"
72098 +#include "std_ext.h"
72099 +#include "fm_pcd_ext.h"
72100 +#include "fm_ext.h"
72101 +#include "fm_port_ext.h"
72102 +
72103 +
72104 +#define e_FM_PORT_TYPE_OH_HOST_COMMAND e_FM_PORT_TYPE_DUMMY
72105 +
72106 +#define CLS_PLAN_NUM_PER_GRP 8
72107 +
72108 +#define IP_OFFLOAD_PACKAGE_NUMBER 106
72109 +#define CAPWAP_OFFLOAD_PACKAGE_NUMBER 108
72110 +#define IS_OFFLOAD_PACKAGE(num) ((num == IP_OFFLOAD_PACKAGE_NUMBER) || (num == CAPWAP_OFFLOAD_PACKAGE_NUMBER))
72111 +
72112 +
72113 +
72114 +/**************************************************************************//**
72115 + @Description Modules registers offsets
72116 +*//***************************************************************************/
72117 +#define FM_MM_MURAM 0x00000000
72118 +#define FM_MM_BMI 0x00080000
72119 +#define FM_MM_QMI 0x00080400
72120 +#define FM_MM_PRS 0x000c7000
72121 +#define FM_MM_KG 0x000C1000
72122 +#define FM_MM_DMA 0x000C2000
72123 +#define FM_MM_FPM 0x000C3000
72124 +#define FM_MM_PLCR 0x000C0000
72125 +#define FM_MM_IMEM 0x000C4000
72126 +#define FM_MM_CGP 0x000DB000
72127 +#define FM_MM_TRB(i) (0x000D0200 + 0x400 * (i))
72128 +#if (DPAA_VERSION >= 11)
72129 +#define FM_MM_SP 0x000dc000
72130 +#endif /* (DPAA_VERSION >= 11) */
72131 +
72132 +
72133 +/**************************************************************************//**
72134 + @Description Enum for inter-module interrupts registration
72135 +*//***************************************************************************/
72136 +typedef enum e_FmEventModules{
72137 + e_FM_MOD_PRS, /**< Parser event */
72138 + e_FM_MOD_KG, /**< Keygen event */
72139 + e_FM_MOD_PLCR, /**< Policer event */
72140 + e_FM_MOD_10G_MAC, /**< 10G MAC event */
72141 + e_FM_MOD_1G_MAC, /**< 1G MAC event */
72142 + e_FM_MOD_TMR, /**< Timer event */
72143 + e_FM_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
72144 + e_FM_MOD_MACSEC,
72145 + e_FM_MOD_DUMMY_LAST
72146 +} e_FmEventModules;
72147 +
72148 +/**************************************************************************//**
72149 + @Description Enum for interrupts types
72150 +*//***************************************************************************/
72151 +typedef enum e_FmIntrType {
72152 + e_FM_INTR_TYPE_ERR,
72153 + e_FM_INTR_TYPE_NORMAL
72154 +} e_FmIntrType;
72155 +
72156 +/**************************************************************************//**
72157 + @Description Enum for inter-module interrupts registration
72158 +*//***************************************************************************/
72159 +typedef enum e_FmInterModuleEvent
72160 +{
72161 + e_FM_EV_PRS = 0, /**< Parser event */
72162 + e_FM_EV_ERR_PRS, /**< Parser error event */
72163 + e_FM_EV_KG, /**< Keygen event */
72164 + e_FM_EV_ERR_KG, /**< Keygen error event */
72165 + e_FM_EV_PLCR, /**< Policer event */
72166 + e_FM_EV_ERR_PLCR, /**< Policer error event */
72167 + e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */
72168 + e_FM_EV_ERR_10G_MAC1, /**< 10G MAC 1 error event */
72169 + e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */
72170 + e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */
72171 + e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */
72172 + e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */
72173 + e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */
72174 + e_FM_EV_ERR_1G_MAC5, /**< 1G MAC 5 error event */
72175 + e_FM_EV_ERR_1G_MAC6, /**< 1G MAC 6 error event */
72176 + e_FM_EV_ERR_1G_MAC7, /**< 1G MAC 7 error event */
72177 + e_FM_EV_ERR_MACSEC_MAC0,
72178 + e_FM_EV_TMR, /**< Timer event */
72179 + e_FM_EV_10G_MAC0, /**< 10G MAC 0 event (Magic packet detection)*/
72180 + e_FM_EV_10G_MAC1, /**< 10G MAC 1 event (Magic packet detection)*/
72181 + e_FM_EV_1G_MAC0, /**< 1G MAC 0 event (Magic packet detection)*/
72182 + e_FM_EV_1G_MAC1, /**< 1G MAC 1 event (Magic packet detection)*/
72183 + e_FM_EV_1G_MAC2, /**< 1G MAC 2 (Magic packet detection)*/
72184 + e_FM_EV_1G_MAC3, /**< 1G MAC 3 (Magic packet detection)*/
72185 + e_FM_EV_1G_MAC4, /**< 1G MAC 4 (Magic packet detection)*/
72186 + e_FM_EV_1G_MAC5, /**< 1G MAC 5 (Magic packet detection)*/
72187 + e_FM_EV_1G_MAC6, /**< 1G MAC 6 (Magic packet detection)*/
72188 + e_FM_EV_1G_MAC7, /**< 1G MAC 7 (Magic packet detection)*/
72189 + e_FM_EV_MACSEC_MAC0, /**< MACSEC MAC 0 event */
72190 + e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */
72191 + e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */
72192 + e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */
72193 + e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */
72194 + e_FM_EV_DUMMY_LAST
72195 +} e_FmInterModuleEvent;
72196 +
72197 +
72198 +#if defined(__MWERKS__) && !defined(__GNUC__)
72199 +#pragma pack(push,1)
72200 +#endif /* defined(__MWERKS__) && ... */
72201 +
72202 +/**************************************************************************//**
72203 + @Description PCD KG scheme registers
72204 +*//***************************************************************************/
72205 +typedef _Packed struct t_FmPcdPlcrProfileRegs {
72206 + volatile uint32_t fmpl_pemode; /* 0x090 FMPL_PEMODE - FM Policer Profile Entry Mode*/
72207 + volatile uint32_t fmpl_pegnia; /* 0x094 FMPL_PEGNIA - FM Policer Profile Entry GREEN Next Invoked Action*/
72208 + volatile uint32_t fmpl_peynia; /* 0x098 FMPL_PEYNIA - FM Policer Profile Entry YELLOW Next Invoked Action*/
72209 + volatile uint32_t fmpl_pernia; /* 0x09C FMPL_PERNIA - FM Policer Profile Entry RED Next Invoked Action*/
72210 + volatile uint32_t fmpl_pecir; /* 0x0A0 FMPL_PECIR - FM Policer Profile Entry Committed Information Rate*/
72211 + volatile uint32_t fmpl_pecbs; /* 0x0A4 FMPL_PECBS - FM Policer Profile Entry Committed Burst Size*/
72212 + volatile uint32_t fmpl_pepepir_eir; /* 0x0A8 FMPL_PEPIR_EIR - FM Policer Profile Entry Peak/Excess Information Rate*/
72213 + volatile uint32_t fmpl_pepbs_ebs; /* 0x0AC FMPL_PEPBS_EBS - FM Policer Profile Entry Peak/Excess Information Rate*/
72214 + volatile uint32_t fmpl_pelts; /* 0x0B0 FMPL_PELTS - FM Policer Profile Entry Last TimeStamp*/
72215 + volatile uint32_t fmpl_pects; /* 0x0B4 FMPL_PECTS - FM Policer Profile Entry Committed Token Status*/
72216 + volatile uint32_t fmpl_pepts_ets; /* 0x0B8 FMPL_PEPTS_ETS - FM Policer Profile Entry Peak/Excess Token Status*/
72217 + volatile uint32_t fmpl_pegpc; /* 0x0BC FMPL_PEGPC - FM Policer Profile Entry GREEN Packet Counter*/
72218 + volatile uint32_t fmpl_peypc; /* 0x0C0 FMPL_PEYPC - FM Policer Profile Entry YELLOW Packet Counter*/
72219 + volatile uint32_t fmpl_perpc; /* 0x0C4 FMPL_PERPC - FM Policer Profile Entry RED Packet Counter */
72220 + volatile uint32_t fmpl_perypc; /* 0x0C8 FMPL_PERYPC - FM Policer Profile Entry Recolored YELLOW Packet Counter*/
72221 + volatile uint32_t fmpl_perrpc; /* 0x0CC FMPL_PERRPC - FM Policer Profile Entry Recolored RED Packet Counter*/
72222 + volatile uint32_t fmpl_res1[12]; /* 0x0D0-0x0FF Reserved */
72223 +} _PackedType t_FmPcdPlcrProfileRegs;
72224 +
72225 +
72226 +typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams {
72227 + volatile uint32_t portIdAndCapwapReassmTbl;
72228 + volatile uint32_t fqidForTimeOutFrames;
72229 + volatile uint32_t timeoutRequestTime;
72230 +}_PackedType t_FmPcdCcCapwapReassmTimeoutParams;
72231 +
72232 +/**************************************************************************//**
72233 + @Description PCD CTRL Parameters Page
72234 +*//***************************************************************************/
72235 +typedef _Packed struct t_FmPcdCtrlParamsPage {
72236 + volatile uint8_t reserved0[16];
72237 + volatile uint32_t iprIpv4Nia;
72238 + volatile uint32_t iprIpv6Nia;
72239 + volatile uint8_t reserved1[24];
72240 + volatile uint32_t ipfOptionsCounter;
72241 + volatile uint8_t reserved2[12];
72242 + volatile uint32_t misc;
72243 + volatile uint32_t errorsDiscardMask;
72244 + volatile uint32_t discardMask;
72245 + volatile uint8_t reserved3[4];
72246 + volatile uint32_t postBmiFetchNia;
72247 + volatile uint8_t reserved4[172];
72248 +} _PackedType t_FmPcdCtrlParamsPage;
72249 +
72250 +
72251 +
72252 +#if defined(__MWERKS__) && !defined(__GNUC__)
72253 +#pragma pack(pop)
72254 +#endif /* defined(__MWERKS__) && ... */
72255 +
72256 +
72257 +/*for UNDER_CONSTRUCTION_FM_RMU_USE_SEC its defined in fm_ext.h*/
72258 +typedef uint32_t t_FmFmanCtrl;
72259 +
72260 +#define FPM_PORT_FM_CTL1 0x00000001
72261 +#define FPM_PORT_FM_CTL2 0x00000002
72262 +
72263 +
72264 +
72265 +typedef struct t_FmPcdCcFragScratchPoolCmdParams {
72266 + uint32_t numOfBuffers;
72267 + uint8_t bufferPoolId;
72268 +} t_FmPcdCcFragScratchPoolCmdParams;
72269 +
72270 +typedef struct t_FmPcdCcReassmTimeoutParams {
72271 + bool activate;
72272 + uint8_t tsbs;
72273 + uint32_t iprcpt;
72274 +} t_FmPcdCcReassmTimeoutParams;
72275 +
72276 +typedef struct {
72277 + uint8_t baseEntry;
72278 + uint16_t numOfClsPlanEntries;
72279 + uint32_t vectors[FM_PCD_MAX_NUM_OF_CLS_PLANS];
72280 +} t_FmPcdKgInterModuleClsPlanSet;
72281 +
72282 +/**************************************************************************//**
72283 + @Description Structure for binding a port to keygen schemes.
72284 +*//***************************************************************************/
72285 +typedef struct t_FmPcdKgInterModuleBindPortToSchemes {
72286 + uint8_t hardwarePortId;
72287 + uint8_t netEnvId;
72288 + bool useClsPlan; /**< TRUE if this port uses the clsPlan mechanism */
72289 + uint8_t numOfSchemes;
72290 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
72291 +} t_FmPcdKgInterModuleBindPortToSchemes;
72292 +
72293 +typedef struct {
72294 + uint32_t nextCcNodeInfo;
72295 + t_List node;
72296 +} t_CcNodeInfo;
72297 +
72298 +typedef struct
72299 +{
72300 + t_Handle h_CcNode;
72301 + uint16_t index;
72302 + t_List node;
72303 +}t_CcNodeInformation;
72304 +#define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node)
72305 +
72306 +typedef enum e_ModifyState
72307 +{
72308 + e_MODIFY_STATE_ADD = 0,
72309 + e_MODIFY_STATE_REMOVE,
72310 + e_MODIFY_STATE_CHANGE
72311 +} e_ModifyState;
72312 +
72313 +typedef struct
72314 +{
72315 + t_Handle h_Manip;
72316 + t_List node;
72317 +}t_ManipInfo;
72318 +#define CC_NEXT_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInfo, node)
72319 +
72320 +typedef struct {
72321 + uint32_t type;
72322 + uint8_t prOffset;
72323 + uint16_t dataOffset;
72324 + uint8_t internalBufferOffset;
72325 + uint8_t numOfTasks;
72326 + uint8_t numOfExtraTasks;
72327 + uint8_t hardwarePortId;
72328 + t_FmRevisionInfo revInfo;
72329 + uint32_t nia;
72330 + uint32_t discardMask;
72331 +} t_GetCcParams;
72332 +
72333 +typedef struct {
72334 + uint32_t type;
72335 + int psoSize;
72336 + uint32_t nia;
72337 + t_FmFmanCtrl orFmanCtrl;
72338 + bool overwrite;
72339 + uint8_t ofpDpde;
72340 +} t_SetCcParams;
72341 +
72342 +typedef struct {
72343 + t_GetCcParams getCcParams;
72344 + t_SetCcParams setCcParams;
72345 +} t_FmPortGetSetCcParams;
72346 +
72347 +typedef struct {
72348 + uint32_t type;
72349 + bool sleep;
72350 +} t_FmSetParams;
72351 +
72352 +typedef struct {
72353 + uint32_t type;
72354 + uint32_t fmqm_gs;
72355 + uint32_t fm_npi;
72356 + uint32_t fm_cld;
72357 + uint32_t fmfp_extc;
72358 +} t_FmGetParams;
72359 +
72360 +typedef struct {
72361 + t_FmSetParams setParams;
72362 + t_FmGetParams getParams;
72363 +} t_FmGetSetParams;
72364 +
72365 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params);
72366 +
72367 +static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag)
72368 +{
72369 + uint32_t intFlags;
72370 + if (h_Spinlock)
72371 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
72372 + else
72373 + intFlags = XX_DisableAllIntr();
72374 +
72375 + if (*p_Flag)
72376 + {
72377 + if (h_Spinlock)
72378 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72379 + else
72380 + XX_RestoreAllIntr(intFlags);
72381 + return FALSE;
72382 + }
72383 + *p_Flag = TRUE;
72384 +
72385 + if (h_Spinlock)
72386 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72387 + else
72388 + XX_RestoreAllIntr(intFlags);
72389 +
72390 + return TRUE;
72391 +}
72392 +
72393 +#define RELEASE_LOCK(_flag) _flag = FALSE;
72394 +
72395 +/**************************************************************************//**
72396 + @Collection Defines used for manipulation CC and BMI
72397 + @{
72398 +*//***************************************************************************/
72399 +#define INTERNAL_CONTEXT_OFFSET 0x80000000
72400 +#define OFFSET_OF_PR 0x40000000
72401 +#define MANIP_EXTRA_SPACE 0x20000000
72402 +#define NUM_OF_TASKS 0x10000000
72403 +#define OFFSET_OF_DATA 0x08000000
72404 +#define HW_PORT_ID 0x04000000
72405 +#define FM_REV 0x02000000
72406 +#define GET_NIA_FPNE 0x01000000
72407 +#define GET_NIA_PNDN 0x00800000
72408 +#define NUM_OF_EXTRA_TASKS 0x00400000
72409 +#define DISCARD_MASK 0x00200000
72410 +
72411 +#define UPDATE_NIA_PNEN 0x80000000
72412 +#define UPDATE_PSO 0x40000000
72413 +#define UPDATE_NIA_PNDN 0x20000000
72414 +#define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000
72415 +#define UPDATE_OFP_DPTE 0x08000000
72416 +#define UPDATE_NIA_FENE 0x04000000
72417 +#define UPDATE_NIA_CMNE 0x02000000
72418 +#define UPDATE_NIA_FPNE 0x01000000
72419 +/* @} */
72420 +
72421 +/**************************************************************************//**
72422 + @Collection Defines used for manipulation CC and CC
72423 + @{
72424 +*//***************************************************************************/
72425 +#define UPDATE_NIA_ENQ_WITHOUT_DMA 0x80000000
72426 +#define UPDATE_CC_WITH_TREE 0x40000000
72427 +#define UPDATE_CC_WITH_DELETE_TREE 0x20000000
72428 +#define UPDATE_KG_NIA_CC_WA 0x10000000
72429 +#define UPDATE_KG_OPT_MODE 0x08000000
72430 +#define UPDATE_KG_NIA 0x04000000
72431 +#define UPDATE_CC_SHADOW_CLEAR 0x02000000
72432 +/* @} */
72433 +
72434 +#define UPDATE_FPM_BRKC_SLP 0x80000000
72435 +#define UPDATE_FPM_EXTC 0x40000000
72436 +#define UPDATE_FPM_EXTC_CLEAR 0x20000000
72437 +#define GET_FMQM_GS 0x10000000
72438 +#define GET_FM_NPI 0x08000000
72439 +#define GET_FMFP_EXTC 0x04000000
72440 +#define CLEAR_IRAM_READY 0x02000000
72441 +#define UPDATE_FM_CLD 0x01000000
72442 +#define GET_FM_CLD 0x00800000
72443 +#define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
72444 + FM_MAX_NUM_OF_1G_RX_PORTS + \
72445 + FM_MAX_NUM_OF_10G_RX_PORTS + \
72446 + FM_MAX_NUM_OF_1G_TX_PORTS + \
72447 + FM_MAX_NUM_OF_10G_TX_PORTS)
72448 +
72449 +#define MODULE_NAME_SIZE 30
72450 +#define DUMMY_PORT_ID 0
72451 +
72452 +#define FM_LIODN_OFFSET_MASK 0x3FF
72453 +
72454 +/**************************************************************************//**
72455 + @Description NIA Description
72456 +*//***************************************************************************/
72457 +#define NIA_ENG_MASK 0x007C0000
72458 +#define NIA_AC_MASK 0x0003ffff
72459 +
72460 +#define NIA_ORDER_RESTOR 0x00800000
72461 +#define NIA_ENG_FM_CTL 0x00000000
72462 +#define NIA_ENG_PRS 0x00440000
72463 +#define NIA_ENG_KG 0x00480000
72464 +#define NIA_ENG_PLCR 0x004C0000
72465 +#define NIA_ENG_BMI 0x00500000
72466 +#define NIA_ENG_QMI_ENQ 0x00540000
72467 +#define NIA_ENG_QMI_DEQ 0x00580000
72468 +
72469 +#define NIA_FM_CTL_AC_CC 0x00000006
72470 +#define NIA_FM_CTL_AC_HC 0x0000000C
72471 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
72472 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
72473 +#define NIA_FM_CTL_AC_POP_TO_N_STEP 0x0000000e
72474 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER 0x00000010
72475 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME 0x00000018
72476 +#define NIA_FM_CTL_AC_POST_BMI_FETCH 0x00000012
72477 +#define NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME 0x0000001A
72478 +#define NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME 0x0000001E
72479 +#define NIA_FM_CTL_AC_POST_BMI_ENQ_ORR 0x00000014
72480 +#define NIA_FM_CTL_AC_POST_BMI_ENQ 0x00000022
72481 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
72482 +#define NIA_FM_CTL_AC_POST_TX 0x00000024
72483 +/* V3 only */
72484 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
72485 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME 0x0000002A
72486 +#define NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP 0x0000002C
72487 +
72488 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
72489 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
72490 +#define NIA_BMI_AC_RELEASE 0x000000C0
72491 +#define NIA_BMI_AC_DISCARD 0x000000C1
72492 +#define NIA_BMI_AC_TX 0x00000274
72493 +#define NIA_BMI_AC_FETCH 0x00000208
72494 +#define NIA_BMI_AC_MASK 0x000003FF
72495 +
72496 +#define NIA_KG_DIRECT 0x00000100
72497 +#define NIA_KG_CC_EN 0x00000200
72498 +#define NIA_PLCR_ABSOLUTE 0x00008000
72499 +
72500 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
72501 +
72502 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
72503 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72504 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72505 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72506 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME))
72507 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72508 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72509 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72510 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME))
72511 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72512 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME)
72513 +#else
72514 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72515 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72516 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72517 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
72518 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72519 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72520 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72521 + (NIA_ENG_BMI | NIA_BMI_AC_DISCARD))
72522 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72523 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)
72524 +#endif /* defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || ... */
72525 +
72526 +/**************************************************************************//**
72527 + @Description CTRL Parameters Page defines
72528 +*//***************************************************************************/
72529 +#define FM_CTL_PARAMS_PAGE_OP_FIX_EN 0x80000000
72530 +#define FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN 0x40000000
72531 +#define FM_CTL_PARAMS_PAGE_ALWAYS_ON 0x00000100
72532 +
72533 +#define FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK 0x0000003f
72534 +
72535 +/**************************************************************************//**
72536 + @Description Port Id defines
72537 +*//***************************************************************************/
72538 +#if (DPAA_VERSION == 10)
72539 +#define BASE_OH_PORTID 1
72540 +#else
72541 +#define BASE_OH_PORTID 2
72542 +#endif /* (DPAA_VERSION == 10) */
72543 +#define BASE_1G_RX_PORTID 8
72544 +#define BASE_10G_RX_PORTID 0x10
72545 +#define BASE_1G_TX_PORTID 0x28
72546 +#define BASE_10G_TX_PORTID 0x30
72547 +
72548 +#define FM_PCD_PORT_OH_BASE_INDX 0
72549 +#define FM_PCD_PORT_1G_RX_BASE_INDX (FM_PCD_PORT_OH_BASE_INDX+FM_MAX_NUM_OF_OH_PORTS)
72550 +#define FM_PCD_PORT_10G_RX_BASE_INDX (FM_PCD_PORT_1G_RX_BASE_INDX+FM_MAX_NUM_OF_1G_RX_PORTS)
72551 +#define FM_PCD_PORT_1G_TX_BASE_INDX (FM_PCD_PORT_10G_RX_BASE_INDX+FM_MAX_NUM_OF_10G_RX_PORTS)
72552 +#define FM_PCD_PORT_10G_TX_BASE_INDX (FM_PCD_PORT_1G_TX_BASE_INDX+FM_MAX_NUM_OF_1G_TX_PORTS)
72553 +
72554 +#if (FM_MAX_NUM_OF_OH_PORTS > 0)
72555 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72556 + if ((_relativePortId) >= FM_MAX_NUM_OF_OH_PORTS) \
72557 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72558 +#else
72559 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72560 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72561 +#endif
72562 +#if (FM_MAX_NUM_OF_1G_RX_PORTS > 0)
72563 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72564 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \
72565 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72566 +#else
72567 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72568 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72569 +#endif
72570 +#if (FM_MAX_NUM_OF_10G_RX_PORTS > 0)
72571 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72572 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \
72573 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72574 +#else
72575 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72576 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72577 +#endif
72578 +#if (FM_MAX_NUM_OF_1G_TX_PORTS > 0)
72579 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72580 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \
72581 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72582 +#else
72583 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72584 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72585 +#endif
72586 +#if (FM_MAX_NUM_OF_10G_TX_PORTS > 0)
72587 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72588 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \
72589 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72590 +#else
72591 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72592 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72593 +#endif
72594 +
72595 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev);
72596 +
72597 +#define HW_PORT_ID_TO_SW_PORT_ID(_relativePortId, hardwarePortId) \
72598 +{ if (((hardwarePortId) >= BASE_OH_PORTID) && \
72599 + ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72600 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_OH_PORTID); \
72601 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72602 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72603 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID); \
72604 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72605 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72606 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID); \
72607 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72608 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72609 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID); \
72610 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72611 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72612 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID); \
72613 + else { \
72614 + _relativePortId = (uint8_t)DUMMY_PORT_ID; \
72615 + ASSERT_COND(TRUE); \
72616 + } \
72617 +}
72618 +
72619 +#define HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId) \
72620 +do { \
72621 + if (((hardwarePortId) >= BASE_OH_PORTID) && ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72622 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_OH_PORTID+FM_PCD_PORT_OH_BASE_INDX); \
72623 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72624 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72625 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID+FM_PCD_PORT_1G_RX_BASE_INDX); \
72626 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72627 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72628 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID+FM_PCD_PORT_10G_RX_BASE_INDX); \
72629 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72630 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72631 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID+FM_PCD_PORT_1G_TX_BASE_INDX); \
72632 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72633 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72634 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID+FM_PCD_PORT_10G_TX_BASE_INDX); \
72635 + else ASSERT_COND(FALSE); \
72636 +} while (0)
72637 +
72638 +#define SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, swPortIndex) \
72639 +do { \
72640 + if (((swPortIndex) >= FM_PCD_PORT_OH_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_1G_RX_BASE_INDX)) \
72641 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_OH_BASE_INDX+BASE_OH_PORTID); \
72642 + else if (((swPortIndex) >= FM_PCD_PORT_1G_RX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_RX_BASE_INDX)) \
72643 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_RX_BASE_INDX+BASE_1G_RX_PORTID); \
72644 + else if (((swPortIndex) >= FM_PCD_PORT_10G_RX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72645 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_RX_BASE_INDX+BASE_10G_RX_PORTID); \
72646 + else if (((swPortIndex) >= FM_PCD_PORT_1G_TX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_TX_BASE_INDX)) \
72647 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_TX_BASE_INDX+BASE_1G_TX_PORTID); \
72648 + else if (((swPortIndex) >= FM_PCD_PORT_10G_TX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72649 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_TX_BASE_INDX+BASE_10G_TX_PORTID); \
72650 + else ASSERT_COND(FALSE); \
72651 +} while (0)
72652 +
72653 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
72654 +#define BMI_FIFO_UNITS 0x100
72655 +
72656 +typedef struct {
72657 + void (*f_Isr) (t_Handle h_Arg);
72658 + t_Handle h_SrcHandle;
72659 + uint8_t guestId;
72660 +} t_FmIntrSrc;
72661 +
72662 +#define ILLEGAL_HDR_NUM 0xFF
72663 +#define NO_HDR_NUM FM_PCD_PRS_NUM_OF_HDRS
72664 +
72665 +#define IS_PRIVATE_HEADER(hdr) (((hdr) == HEADER_TYPE_USER_DEFINED_SHIM1) || \
72666 + ((hdr) == HEADER_TYPE_USER_DEFINED_SHIM2))
72667 +#define IS_SPECIAL_HEADER(hdr) ((hdr) == HEADER_TYPE_MACSEC)
72668 +
72669 +static __inline__ uint8_t GetPrsHdrNum(e_NetHeaderType hdr)
72670 +{
72671 + switch (hdr)
72672 + { case (HEADER_TYPE_ETH): return 0;
72673 + case (HEADER_TYPE_LLC_SNAP): return 1;
72674 + case (HEADER_TYPE_VLAN): return 2;
72675 + case (HEADER_TYPE_PPPoE): return 3;
72676 + case (HEADER_TYPE_PPP): return 3;
72677 + case (HEADER_TYPE_MPLS): return 4;
72678 + case (HEADER_TYPE_IPv4): return 5;
72679 + case (HEADER_TYPE_IPv6): return 6;
72680 + case (HEADER_TYPE_GRE): return 7;
72681 + case (HEADER_TYPE_MINENCAP): return 8;
72682 + case (HEADER_TYPE_USER_DEFINED_L3): return 9;
72683 + case (HEADER_TYPE_TCP): return 10;
72684 + case (HEADER_TYPE_UDP): return 11;
72685 + case (HEADER_TYPE_IPSEC_AH):
72686 + case (HEADER_TYPE_IPSEC_ESP): return 12;
72687 + case (HEADER_TYPE_SCTP): return 13;
72688 + case (HEADER_TYPE_DCCP): return 14;
72689 + case (HEADER_TYPE_USER_DEFINED_L4): return 15;
72690 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
72691 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
72692 + case (HEADER_TYPE_MACSEC): return NO_HDR_NUM;
72693 + default:
72694 + return ILLEGAL_HDR_NUM;
72695 + }
72696 +}
72697 +
72698 +#define FM_PCD_MAX_NUM_OF_OPTIONS(clsPlanEntries) ((clsPlanEntries==256)? 8:((clsPlanEntries==128)? 7: ((clsPlanEntries==64)? 6: ((clsPlanEntries==32)? 5:0))))
72699 +
72700 +
72701 +/**************************************************************************//**
72702 + @Description A structure for initializing a keygen classification plan group
72703 +*//***************************************************************************/
72704 +typedef struct t_FmPcdKgInterModuleClsPlanGrpParams {
72705 + uint8_t netEnvId; /* IN */
72706 + bool grpExists; /* OUT (unused in FmPcdKgBuildClsPlanGrp)*/
72707 + uint8_t clsPlanGrpId; /* OUT */
72708 + bool emptyClsPlanGrp; /* OUT */
72709 + uint8_t numOfOptions; /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72710 + protocolOpt_t options[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
72711 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72712 + uint32_t optVectors[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
72713 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72714 +} t_FmPcdKgInterModuleClsPlanGrpParams;
72715 +
72716 +typedef struct t_FmPcdLock {
72717 + t_Handle h_Spinlock;
72718 + volatile bool flag;
72719 + t_List node;
72720 +} t_FmPcdLock;
72721 +#define FM_PCD_LOCK_OBJ(ptr) LIST_OBJECT(ptr, t_FmPcdLock, node)
72722 +
72723 +
72724 +typedef t_Error (t_FmPortGetSetCcParamsCallback) (t_Handle h_FmPort,
72725 + t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
72726 +
72727 +
72728 +/***********************************************************************/
72729 +/* Common API for FM-PCD module */
72730 +/***********************************************************************/
72731 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd);
72732 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr);
72733 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum);
72734 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId);
72735 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
72736 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
72737 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv);
72738 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId);
72739 +uint32_t FmPcdLock(t_Handle h_FmPcd);
72740 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags);
72741 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
72742 +t_Error FmPcdFragHcScratchPoolInit(t_Handle h_FmPcd, uint8_t scratchBpid);
72743 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
72744 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
72745 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd);
72746 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd);
72747 +void FmPcdLockUnlockAll(t_Handle h_FmPcd);
72748 +t_Error FmPcdHcSync(t_Handle h_FmPcd);
72749 +t_Handle FmGetPcd(t_Handle h_Fm);
72750 +/***********************************************************************/
72751 +/* Common API for FM-PCD KG module */
72752 +/***********************************************************************/
72753 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp);
72754 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp);
72755 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet);
72756 +
72757 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme);
72758 +#if (DPAA_VERSION >= 11)
72759 +bool FmPcdKgGetVspe(t_Handle h_Scheme);
72760 +#endif /* (DPAA_VERSION >= 11) */
72761 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId);
72762 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId);
72763 +t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_Scheme);
72764 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPortToSchemes, uint32_t *p_SpReg, bool add);
72765 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg);
72766 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter);
72767 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId);
72768 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId);
72769 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId);
72770 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId);
72771 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId);
72772 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme);
72773 +
72774 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
72775 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
72776 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId);
72777 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId);
72778 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId);
72779 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId);
72780 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction);
72781 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId);
72782 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId);
72783 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId);
72784 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId);
72785 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme);
72786 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
72787 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp);
72788 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId);
72789 +
72790 +/***********************************************************************/
72791 +/* Common API for FM-PCD parser module */
72792 +/***********************************************************************/
72793 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle p_FmPcd, uint8_t hardwarePortId, bool include);
72794 +
72795 +/***********************************************************************/
72796 +/* Common API for FM-PCD policer module */
72797 +/***********************************************************************/
72798 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles);
72799 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
72800 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72801 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId);
72802 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
72803 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId);
72804 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter);
72805 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId);
72806 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId);
72807 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile);
72808 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
72809 + e_FmPcdProfileTypeSelection profileType,
72810 + t_Handle h_FmPort,
72811 + uint16_t relativeProfile,
72812 + uint16_t *p_AbsoluteId);
72813 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72814 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72815 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg);
72816 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72817 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72818 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red);
72819 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction);
72820 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction);
72821 +
72822 +/***********************************************************************/
72823 +/* Common API for FM-PCD CC module */
72824 +/***********************************************************************/
72825 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
72826 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
72827 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex);
72828 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams);
72829 +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);
72830 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams);
72831 +t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
72832 +t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
72833 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer);
72834 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree);
72835 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams);
72836 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
72837 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
72838 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort);
72839 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_CcTree);
72840 +
72841 +/***********************************************************************/
72842 +/* Common API for FM-PCD Manip module */
72843 +/***********************************************************************/
72844 +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);
72845 +
72846 +/***********************************************************************/
72847 +/* Common API for FM-Port module */
72848 +/***********************************************************************/
72849 +#if (DPAA_VERSION >= 11)
72850 +typedef enum e_FmPortGprFuncType
72851 +{
72852 + e_FM_PORT_GPR_EMPTY = 0,
72853 + e_FM_PORT_GPR_MURAM_PAGE
72854 +} e_FmPortGprFuncType;
72855 +
72856 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, void **p_Value);
72857 +#endif /* DPAA_VERSION >= 11) */
72858 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_FmGetSetParams);
72859 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
72860 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort);
72861 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort);
72862 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort);
72863 +void FmPortPcdKgSwUnbindClsPlanGrp (t_Handle h_FmPort);
72864 +
72865 +
72866 +#if (DPAA_VERSION >= 11)
72867 +t_Error FmPcdFrmReplicUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_FrmReplic);
72868 +#endif /* (DPAA_VERSION >= 11) */
72869 +
72870 +/**************************************************************************//**
72871 + @Function FmRegisterIntr
72872 +
72873 + @Description Used to register an inter-module event handler to be processed by FM
72874 +
72875 + @Param[in] h_Fm A handle to an FM Module.
72876 + @Param[in] mod The module that causes the event
72877 + @Param[in] modId Module id - if more than 1 instansiation of this
72878 + mode exists,0 otherwise.
72879 + @Param[in] intrType Interrupt type (error/normal) selection.
72880 + @Param[in] f_Isr The interrupt service routine.
72881 + @Param[in] h_Arg Argument to be passed to f_Isr.
72882 +
72883 + @Return None.
72884 +*//***************************************************************************/
72885 +void FmRegisterIntr(t_Handle h_Fm,
72886 + e_FmEventModules mod,
72887 + uint8_t modId,
72888 + e_FmIntrType intrType,
72889 + void (*f_Isr) (t_Handle h_Arg),
72890 + t_Handle h_Arg);
72891 +
72892 +/**************************************************************************//**
72893 + @Function FmUnregisterIntr
72894 +
72895 + @Description Used to un-register an inter-module event handler that was processed by FM
72896 +
72897 + @Param[in] h_Fm A handle to an FM Module.
72898 + @Param[in] mod The module that causes the event
72899 + @Param[in] modId Module id - if more than 1 instansiation of this
72900 + mode exists,0 otherwise.
72901 + @Param[in] intrType Interrupt type (error/normal) selection.
72902 +
72903 + @Return None.
72904 +*//***************************************************************************/
72905 +void FmUnregisterIntr(t_Handle h_Fm,
72906 + e_FmEventModules mod,
72907 + uint8_t modId,
72908 + e_FmIntrType intrType);
72909 +
72910 +/**************************************************************************//**
72911 + @Function FmRegisterFmCtlIntr
72912 +
72913 + @Description Used to register to one of the fmCtl events in the FM module
72914 +
72915 + @Param[in] h_Fm A handle to an FM Module.
72916 + @Param[in] eventRegId FmCtl event id (0-7).
72917 + @Param[in] f_Isr The interrupt service routine.
72918 +
72919 + @Return E_OK on success; Error code otherwise.
72920 +
72921 + @Cautions Allowed only following FM_Init().
72922 +*//***************************************************************************/
72923 +void FmRegisterFmCtlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event));
72924 +
72925 +
72926 +/**************************************************************************//**
72927 + @Description enum for defining MAC types
72928 +*//***************************************************************************/
72929 +typedef enum e_FmMacType {
72930 + e_FM_MAC_10G = 0, /**< 10G MAC */
72931 + e_FM_MAC_1G /**< 1G MAC */
72932 +} e_FmMacType;
72933 +
72934 +/**************************************************************************//**
72935 + @Description Structure for port-FM communication during FM_PORT_Init.
72936 + Fields commented 'IN' are passed by the port module to be used
72937 + by the FM module.
72938 + Fields commented 'OUT' will be filled by FM before returning to port.
72939 + Some fields are optional (depending on configuration) and
72940 + will be analized by the port and FM modules accordingly.
72941 +*//***************************************************************************/
72942 +typedef struct t_FmInterModulePortInitParams {
72943 + uint8_t hardwarePortId; /**< IN. port Id */
72944 + e_FmPortType portType; /**< IN. Port type */
72945 + bool independentMode; /**< IN. TRUE if FM Port operates in independent mode */
72946 + uint16_t liodnOffset; /**< IN. Port's requested resource */
72947 + uint8_t numOfTasks; /**< IN. Port's requested resource */
72948 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
72949 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
72950 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
72951 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
72952 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
72953 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
72954 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
72955 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
72956 + LIODN base for this port, to be
72957 + used together with LIODN offset. */
72958 + t_FmPhysAddr fmMuramPhysBaseAddr;/**< OUT. FM-MURAM physical address*/
72959 +} t_FmInterModulePortInitParams;
72960 +
72961 +/**************************************************************************//**
72962 + @Description Structure for port-FM communication during FM_PORT_Free.
72963 +*//***************************************************************************/
72964 +typedef struct t_FmInterModulePortFreeParams {
72965 + uint8_t hardwarePortId; /**< IN. port Id */
72966 + e_FmPortType portType; /**< IN. Port type */
72967 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
72968 +} t_FmInterModulePortFreeParams;
72969 +
72970 +/**************************************************************************//**
72971 + @Function FmGetPcdPrsBaseAddr
72972 +
72973 + @Description Get the base address of the Parser from the FM module
72974 +
72975 + @Param[in] h_Fm A handle to an FM Module.
72976 +
72977 + @Return Base address.
72978 +*//***************************************************************************/
72979 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm);
72980 +
72981 +/**************************************************************************//**
72982 + @Function FmGetPcdKgBaseAddr
72983 +
72984 + @Description Get the base address of the Keygen from the FM module
72985 +
72986 + @Param[in] h_Fm A handle to an FM Module.
72987 +
72988 + @Return Base address.
72989 +*//***************************************************************************/
72990 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm);
72991 +
72992 +/**************************************************************************//**
72993 + @Function FmGetPcdPlcrBaseAddr
72994 +
72995 + @Description Get the base address of the Policer from the FM module
72996 +
72997 + @Param[in] h_Fm A handle to an FM Module.
72998 +
72999 + @Return Base address.
73000 +*//***************************************************************************/
73001 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm);
73002 +
73003 +/**************************************************************************//**
73004 + @Function FmGetMuramHandle
73005 +
73006 + @Description Get the handle of the MURAM from the FM module
73007 +
73008 + @Param[in] h_Fm A handle to an FM Module.
73009 +
73010 + @Return MURAM module handle.
73011 +*//***************************************************************************/
73012 +t_Handle FmGetMuramHandle(t_Handle h_Fm);
73013 +
73014 +/**************************************************************************//**
73015 + @Function FmGetPhysicalMuramBase
73016 +
73017 + @Description Get the physical base address of the MURAM from the FM module
73018 +
73019 + @Param[in] h_Fm A handle to an FM Module.
73020 + @Param[in] fmPhysAddr Physical MURAM base
73021 +
73022 + @Return Physical base address.
73023 +*//***************************************************************************/
73024 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *fmPhysAddr);
73025 +
73026 +/**************************************************************************//**
73027 + @Function FmGetTimeStampScale
73028 +
73029 + @Description Used internally by other modules in order to get the timeStamp
73030 + period as requested by the application.
73031 +
73032 + This function returns bit number that is incremented every 1 usec.
73033 + To calculate timestamp period in nsec, use
73034 + 1000 / (1 << FmGetTimeStampScale()).
73035 +
73036 + @Param[in] h_Fm A handle to an FM Module.
73037 +
73038 + @Return Bit that counts 1 usec.
73039 +
73040 + @Cautions Allowed only following FM_Init().
73041 +*//***************************************************************************/
73042 +uint32_t FmGetTimeStampScale(t_Handle h_Fm);
73043 +
73044 +/**************************************************************************//**
73045 + @Function FmResumeStalledPort
73046 +
73047 + @Description Used internally by FM port to release a stalled port.
73048 +
73049 + @Param[in] h_Fm A handle to an FM Module.
73050 + @Param[in] hardwarePortId HW port id.
73051 +
73052 + @Return E_OK on success; Error code otherwise.
73053 +
73054 + @Cautions Allowed only following FM_Init().
73055 +*//***************************************************************************/
73056 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId);
73057 +
73058 +/**************************************************************************//**
73059 + @Function FmIsPortStalled
73060 +
73061 + @Description Used internally by FM port to read the port's status.
73062 +
73063 + @Param[in] h_Fm A handle to an FM Module.
73064 + @Param[in] hardwarePortId HW port id.
73065 + @Param[in] p_IsStalled A pointer to the boolean port stalled state
73066 +
73067 + @Return E_OK on success; Error code otherwise.
73068 +
73069 + @Cautions Allowed only following FM_Init().
73070 +*//***************************************************************************/
73071 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled);
73072 +
73073 +/**************************************************************************//**
73074 + @Function FmResetMac
73075 +
73076 + @Description Used by MAC driver to reset the MAC registers
73077 +
73078 + @Param[in] h_Fm A handle to an FM Module.
73079 + @Param[in] type MAC type.
73080 + @Param[in] macId MAC id - according to type.
73081 +
73082 + @Return E_OK on success; Error code otherwise.
73083 +
73084 + @Cautions Allowed only following FM_Init().
73085 +*//***************************************************************************/
73086 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId);
73087 +
73088 +/**************************************************************************//**
73089 + @Function FmGetClockFreq
73090 +
73091 + @Description Used by MAC driver to get the FM clock frequency
73092 +
73093 + @Param[in] h_Fm A handle to an FM Module.
73094 +
73095 + @Return clock-freq on success; 0 otherwise.
73096 +
73097 + @Cautions Allowed only following FM_Init().
73098 +*//***************************************************************************/
73099 +uint16_t FmGetClockFreq(t_Handle h_Fm);
73100 +
73101 +/**************************************************************************//**
73102 + @Function FmGetMacClockFreq
73103 +
73104 + @Description Used by MAC driver to get the MAC clock frequency
73105 +
73106 + @Param[in] h_Fm A handle to an FM Module.
73107 +
73108 + @Return clock-freq on success; 0 otherwise.
73109 +
73110 + @Cautions Allowed only following FM_Init().
73111 +*//***************************************************************************/
73112 +uint16_t FmGetMacClockFreq(t_Handle h_Fm);
73113 +
73114 +/**************************************************************************//**
73115 + @Function FmGetId
73116 +
73117 + @Description Used by PCD driver to read rhe FM id
73118 +
73119 + @Param[in] h_Fm A handle to an FM Module.
73120 +
73121 + @Return E_OK on success; Error code otherwise.
73122 +
73123 + @Cautions Allowed only following FM_Init().
73124 +*//***************************************************************************/
73125 +uint8_t FmGetId(t_Handle h_Fm);
73126 +
73127 +/**************************************************************************//**
73128 + @Function FmReset
73129 +
73130 + @Description Used to reset the FM
73131 +
73132 + @Param[in] h_Fm A handle to an FM Module.
73133 +
73134 + @Return E_OK on success; Error code otherwise.
73135 +*//***************************************************************************/
73136 +t_Error FmReset(t_Handle h_Fm);
73137 +
73138 +/**************************************************************************//**
73139 + @Function FmGetSetPortParams
73140 +
73141 + @Description Used by FM-PORT driver to pass and receive parameters between
73142 + PORT and FM modules.
73143 +
73144 + @Param[in] h_Fm A handle to an FM Module.
73145 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73146 +
73147 + @Return E_OK on success; Error code otherwise.
73148 +
73149 + @Cautions Allowed only following FM_Init().
73150 +*//***************************************************************************/
73151 +t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams);
73152 +
73153 +/**************************************************************************//**
73154 + @Function FmFreePortParams
73155 +
73156 + @Description Used by FM-PORT driver to free port's resources within the FM.
73157 +
73158 + @Param[in] h_Fm A handle to an FM Module.
73159 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73160 +
73161 + @Return None.
73162 +
73163 + @Cautions Allowed only following FM_Init().
73164 +*//***************************************************************************/
73165 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams);
73166 +
73167 +/**************************************************************************//**
73168 + @Function FmSetNumOfRiscsPerPort
73169 +
73170 + @Description Used by FM-PORT driver to pass parameter between
73171 + PORT and FM modules for working with number of RISC..
73172 +
73173 + @Param[in] h_Fm A handle to an FM Module.
73174 + @Param[in] hardwarePortId hardware port Id.
73175 + @Param[in] numOfFmanCtrls number of Fman Controllers.
73176 + @Param[in] orFmanCtrl Fman Controller for order restoration.
73177 +
73178 + @Return None.
73179 +
73180 + @Cautions Allowed only following FM_Init().
73181 +*//***************************************************************************/
73182 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls, t_FmFmanCtrl orFmanCtrl);
73183 +
73184 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73185 +/**************************************************************************//*
73186 + @Function FmDumpPortRegs
73187 +
73188 + @Description Dumps FM port registers which are part of FM common registers
73189 +
73190 + @Param[in] h_Fm A handle to an FM Module.
73191 + @Param[in] hardwarePortId HW port id.
73192 +
73193 + @Return E_OK on success; Error code otherwise.
73194 +
73195 + @Cautions Allowed only FM_Init().
73196 +*//***************************************************************************/
73197 +t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId);
73198 +#endif /* (defined(DEBUG_ERRORS) && ... */
73199 +
73200 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd);
73201 +void FmUnregisterPcd(t_Handle h_Fm);
73202 +t_Handle FmGetPcdHandle(t_Handle h_Fm);
73203 +t_Error FmEnableRamsEcc(t_Handle h_Fm);
73204 +t_Error FmDisableRamsEcc(t_Handle h_Fm);
73205 +void FmGetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
73206 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId);
73207 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId);
73208 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents);
73209 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73210 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event), t_Handle h_Arg);
73211 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73212 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu);
73213 +bool FmIsMaster(t_Handle h_Fm);
73214 +uint8_t FmGetGuestId(t_Handle h_Fm);
73215 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm);
73216 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool preFetchConfigured);
73217 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool *p_PortConfigured, bool *p_PreFetchConfigured);
73218 +
73219 +
73220 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
73221 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId);
73222 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
73223 +
73224 +void FmMuramClear(t_Handle h_FmMuram);
73225 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
73226 + uint8_t hardwarePortId,
73227 + uint8_t *p_NumOfOpenDmas,
73228 + uint8_t *p_NumOfExtraOpenDmas,
73229 + bool initialConfig);
73230 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
73231 + uint8_t hardwarePortId,
73232 + uint8_t *p_NumOfTasks,
73233 + uint8_t *p_NumOfExtraTasks,
73234 + bool initialConfig);
73235 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
73236 + uint8_t hardwarePortId,
73237 + uint32_t *p_SizeOfFifo,
73238 + uint32_t *p_ExtraSizeOfFifo,
73239 + bool initialConfig);
73240 +
73241 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
73242 + uint32_t congestionGroupId,
73243 + uint8_t priorityBitMap);
73244 +
73245 +#if (DPAA_VERSION >= 11)
73246 +t_Error FmVSPAllocForPort(t_Handle h_Fm,
73247 + e_FmPortType portType,
73248 + uint8_t portId,
73249 + uint8_t numOfStorageProfiles);
73250 +
73251 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
73252 + e_FmPortType portType,
73253 + uint8_t portId);
73254 +
73255 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
73256 + e_FmPortType portType,
73257 + uint8_t portId,
73258 + uint16_t relativeProfile,
73259 + uint16_t *p_AbsoluteId);
73260 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
73261 + e_FmPortType portType,
73262 + uint8_t portId,
73263 + uint16_t relativeProfile);
73264 +
73265 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm);
73266 +#endif /* (DPAA_VERSION >= 11) */
73267 +
73268 +
73269 +#endif /* __FM_COMMON_H */
73270 --- /dev/null
73271 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
73272 @@ -0,0 +1,93 @@
73273 +/*
73274 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73275 + *
73276 + * Redistribution and use in source and binary forms, with or without
73277 + * modification, are permitted provided that the following conditions are met:
73278 + * * Redistributions of source code must retain the above copyright
73279 + * notice, this list of conditions and the following disclaimer.
73280 + * * Redistributions in binary form must reproduce the above copyright
73281 + * notice, this list of conditions and the following disclaimer in the
73282 + * documentation and/or other materials provided with the distribution.
73283 + * * Neither the name of Freescale Semiconductor nor the
73284 + * names of its contributors may be used to endorse or promote products
73285 + * derived from this software without specific prior written permission.
73286 + *
73287 + *
73288 + * ALTERNATIVELY, this software may be distributed under the terms of the
73289 + * GNU General Public License ("GPL") as published by the Free Software
73290 + * Foundation, either version 2 of that License or (at your option) any
73291 + * later version.
73292 + *
73293 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73294 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73295 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73296 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73297 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73298 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73299 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73300 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73301 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73302 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73303 + */
73304 +
73305 +
73306 +#ifndef __FM_HC_H
73307 +#define __FM_HC_H
73308 +
73309 +#include "std_ext.h"
73310 +#include "error_ext.h"
73311 +#include "fsl_fman_kg.h"
73312 +
73313 +#define __ERR_MODULE__ MODULE_FM_PCD
73314 +
73315 +
73316 +typedef struct t_FmHcParams {
73317 + t_Handle h_Fm;
73318 + t_Handle h_FmPcd;
73319 + t_FmPcdHcParams params;
73320 +} t_FmHcParams;
73321 +
73322 +
73323 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams);
73324 +void FmHcFree(t_Handle h_FmHc);
73325 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
73326 + uint8_t memId);
73327 +t_Error FmHcDumpRegs(t_Handle h_FmHc);
73328 +
73329 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd);
73330 +
73331 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
73332 + t_Handle h_Scheme,
73333 + struct fman_kg_scheme_regs *p_SchemeRegs,
73334 + bool updateCounter);
73335 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme);
73336 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams );
73337 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams);
73338 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result);
73339 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set);
73340 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t clsPlanGrpId);
73341 +
73342 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value);
73343 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme);
73344 +
73345 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset);
73346 +
73347 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs);
73348 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile);
73349 +
73350 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value);
73351 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter);
73352 +
73353 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add);
73354 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg);
73355 +
73356 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
73357 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction);
73358 +
73359 +t_Error FmHcPcdSync(t_Handle h_FmHc);
73360 +t_Handle FmHcGetPort(t_Handle h_FmHc);
73361 +
73362 +
73363 +
73364 +
73365 +#endif /* __FM_HC_H */
73366 --- /dev/null
73367 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
73368 @@ -0,0 +1,117 @@
73369 +/*
73370 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73371 + *
73372 + * Redistribution and use in source and binary forms, with or without
73373 + * modification, are permitted provided that the following conditions are met:
73374 + * * Redistributions of source code must retain the above copyright
73375 + * notice, this list of conditions and the following disclaimer.
73376 + * * Redistributions in binary form must reproduce the above copyright
73377 + * notice, this list of conditions and the following disclaimer in the
73378 + * documentation and/or other materials provided with the distribution.
73379 + * * Neither the name of Freescale Semiconductor nor the
73380 + * names of its contributors may be used to endorse or promote products
73381 + * derived from this software without specific prior written permission.
73382 + *
73383 + *
73384 + * ALTERNATIVELY, this software may be distributed under the terms of the
73385 + * GNU General Public License ("GPL") as published by the Free Software
73386 + * Foundation, either version 2 of that License or (at your option) any
73387 + * later version.
73388 + *
73389 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73390 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73391 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73392 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73393 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73394 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73395 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73396 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73397 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73398 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73399 + */
73400 +
73401 +
73402 +/******************************************************************************
73403 + @File fm_sp_common.h
73404 +
73405 + @Description FM SP ...
73406 +*//***************************************************************************/
73407 +#ifndef __FM_SP_COMMON_H
73408 +#define __FM_SP_COMMON_H
73409 +
73410 +#include "std_ext.h"
73411 +#include "error_ext.h"
73412 +#include "list_ext.h"
73413 +
73414 +#include "fm_ext.h"
73415 +#include "fm_pcd_ext.h"
73416 +#include "fsl_fman.h"
73417 +
73418 +/**************************************************************************//**
73419 + @Description defaults
73420 +*//***************************************************************************/
73421 +#define DEFAULT_FM_SP_bufferPrefixContent_privDataSize 0
73422 +#define DEFAULT_FM_SP_bufferPrefixContent_passPrsResult FALSE
73423 +#define DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp FALSE
73424 +#define DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo FALSE
73425 +#define DEFAULT_FM_SP_bufferPrefixContent_dataAlign 64
73426 +
73427 +/**************************************************************************//**
73428 + @Description structure for defining internal context copying
73429 +*//***************************************************************************/
73430 +typedef struct
73431 +{
73432 + uint16_t extBufOffset; /**< Offset in External buffer to which internal
73433 + context is copied to (Rx) or taken from (Tx, Op). */
73434 + uint8_t intContextOffset; /**< Offset within internal context to copy from
73435 + (Rx) or to copy to (Tx, Op). */
73436 + uint16_t size; /**< Internal offset size to be copied */
73437 +} t_FmSpIntContextDataCopy;
73438 +
73439 +/**************************************************************************//**
73440 + @Description struct for defining external buffer margins
73441 +*//***************************************************************************/
73442 +typedef struct {
73443 + uint16_t startMargins; /**< Number of bytes to be left at the beginning
73444 + of the external buffer (must be divisible by 16) */
73445 + uint16_t endMargins; /**< number of bytes to be left at the end
73446 + of the external buffer(must be divisible by 16) */
73447 +} t_FmSpBufMargins;
73448 +
73449 +typedef struct {
73450 + uint32_t dataOffset;
73451 + uint32_t prsResultOffset;
73452 + uint32_t timeStampOffset;
73453 + uint32_t hashResultOffset;
73454 + uint32_t pcdInfoOffset;
73455 + uint32_t manipOffset;
73456 +} t_FmSpBufferOffsets;
73457 +
73458 +
73459 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmPortIntContextDataCopy,
73460 + t_FmBufferPrefixContent *p_BufferPrefixContent,
73461 + t_FmSpBufMargins *p_FmPortBufMargins,
73462 + t_FmSpBufferOffsets *p_FmPortBufferOffsets,
73463 + uint8_t *internalBufferOffset);
73464 +
73465 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy);
73466 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
73467 + t_FmBackupBmPools *p_FmBackupBmPools,
73468 + t_FmBufPoolDepletion *p_FmBufPoolDepletion);
73469 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins);
73470 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, uint8_t *orderedArray, uint16_t *sizesArray);
73471 +
73472 +t_Error FmPcdSpAllocProfiles(t_Handle h_FmPcd,
73473 + uint8_t hardwarePortId,
73474 + uint16_t numOfStorageProfiles,
73475 + uint16_t *base,
73476 + uint8_t *log2Num);
73477 +t_Error FmPcdSpGetAbsoluteProfileId(t_Handle h_FmPcd,
73478 + t_Handle h_FmPort,
73479 + uint16_t relativeProfile,
73480 + uint16_t *p_AbsoluteId);
73481 +void SpInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73482 +void SpValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73483 +
73484 +
73485 +#endif /* __FM_SP_COMMON_H */
73486 --- /dev/null
73487 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
73488 @@ -0,0 +1,12 @@
73489 +#
73490 +# Makefile for the Freescale Ethernet controllers
73491 +#
73492 +ccflags-y += -DVERSION=\"\"
73493 +#
73494 +#Include netcomm SW specific definitions
73495 +
73496 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
73497 +
73498 +obj-y += fsl-ncsw-etc.o
73499 +
73500 +fsl-ncsw-etc-objs := mm.o memcpy.o sprint.o list.o error.o
73501 --- /dev/null
73502 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/error.c
73503 @@ -0,0 +1,95 @@
73504 +/*
73505 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73506 + *
73507 + * Redistribution and use in source and binary forms, with or without
73508 + * modification, are permitted provided that the following conditions are met:
73509 + * * Redistributions of source code must retain the above copyright
73510 + * notice, this list of conditions and the following disclaimer.
73511 + * * Redistributions in binary form must reproduce the above copyright
73512 + * notice, this list of conditions and the following disclaimer in the
73513 + * documentation and/or other materials provided with the distribution.
73514 + * * Neither the name of Freescale Semiconductor nor the
73515 + * names of its contributors may be used to endorse or promote products
73516 + * derived from this software without specific prior written permission.
73517 + *
73518 + *
73519 + * ALTERNATIVELY, this software may be distributed under the terms of the
73520 + * GNU General Public License ("GPL") as published by the Free Software
73521 + * Foundation, either version 2 of that License or (at your option) any
73522 + * later version.
73523 + *
73524 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73525 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73526 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73527 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73528 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73529 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73530 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73531 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73532 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73533 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73534 + */
73535 +
73536 +
73537 +/*
73538 +
73539 + @File error.c
73540 +
73541 + @Description General errors and events reporting utilities.
73542 +*//***************************************************************************/
73543 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73544 +#include "error_ext.h"
73545 +
73546 +
73547 +const char *dbgLevelStrings[] =
73548 +{
73549 + "CRITICAL"
73550 + ,"MAJOR"
73551 + ,"MINOR"
73552 + ,"WARNING"
73553 + ,"INFO"
73554 + ,"TRACE"
73555 +};
73556 +
73557 +
73558 +char * ErrTypeStrings (e_ErrorType err)
73559 +{
73560 + switch (err)
73561 + {
73562 + case (E_OK): return "OK";
73563 + case (E_WRITE_FAILED): return "Write Access Failed";
73564 + case (E_NO_DEVICE): return "No Device";
73565 + case (E_NOT_AVAILABLE): return "Resource Is Unavailable";
73566 + case (E_NO_MEMORY): return "Memory Allocation Failed";
73567 + case (E_INVALID_ADDRESS): return "Invalid Address";
73568 + case (E_BUSY): return "Resource Is Busy";
73569 + case (E_ALREADY_EXISTS): return "Resource Already Exists";
73570 + case (E_INVALID_OPERATION): return "Invalid Operation";
73571 + case (E_INVALID_VALUE): return "Invalid Value";
73572 + case (E_NOT_IN_RANGE): return "Value Out Of Range";
73573 + case (E_NOT_SUPPORTED): return "Unsupported Operation";
73574 + case (E_INVALID_STATE): return "Invalid State";
73575 + case (E_INVALID_HANDLE): return "Invalid Handle";
73576 + case (E_INVALID_ID): return "Invalid ID";
73577 + case (E_NULL_POINTER): return "Unexpected NULL Pointer";
73578 + case (E_INVALID_SELECTION): return "Invalid Selection";
73579 + case (E_INVALID_COMM_MODE): return "Invalid Communication Mode";
73580 + case (E_INVALID_MEMORY_TYPE): return "Invalid Memory Type";
73581 + case (E_INVALID_CLOCK): return "Invalid Clock";
73582 + case (E_CONFLICT): return "Conflict In Settings";
73583 + case (E_NOT_ALIGNED): return "Incorrect Alignment";
73584 + case (E_NOT_FOUND): return "Resource Not Found";
73585 + case (E_FULL): return "Resource Is Full";
73586 + case (E_EMPTY): return "Resource Is Empty";
73587 + case (E_ALREADY_FREE): return "Resource Already Free";
73588 + case (E_READ_FAILED): return "Read Access Failed";
73589 + case (E_INVALID_FRAME): return "Invalid Frame";
73590 + case (E_SEND_FAILED): return "Send Operation Failed";
73591 + case (E_RECEIVE_FAILED): return "Receive Operation Failed";
73592 + case (E_TIMEOUT): return "Operation Timed Out";
73593 + default:
73594 + break;
73595 + }
73596 + return NULL;
73597 +}
73598 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
73599 --- /dev/null
73600 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/list.c
73601 @@ -0,0 +1,71 @@
73602 +/*
73603 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73604 + *
73605 + * Redistribution and use in source and binary forms, with or without
73606 + * modification, are permitted provided that the following conditions are met:
73607 + * * Redistributions of source code must retain the above copyright
73608 + * notice, this list of conditions and the following disclaimer.
73609 + * * Redistributions in binary form must reproduce the above copyright
73610 + * notice, this list of conditions and the following disclaimer in the
73611 + * documentation and/or other materials provided with the distribution.
73612 + * * Neither the name of Freescale Semiconductor nor the
73613 + * names of its contributors may be used to endorse or promote products
73614 + * derived from this software without specific prior written permission.
73615 + *
73616 + *
73617 + * ALTERNATIVELY, this software may be distributed under the terms of the
73618 + * GNU General Public License ("GPL") as published by the Free Software
73619 + * Foundation, either version 2 of that License or (at your option) any
73620 + * later version.
73621 + *
73622 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73623 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73624 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73625 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73626 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73627 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73628 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73629 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73630 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73631 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73632 + */
73633 +
73634 +
73635 +/**************************************************************************//**
73636 +
73637 + @File list.c
73638 +
73639 + @Description Implementation of list.
73640 +*//***************************************************************************/
73641 +#include "std_ext.h"
73642 +#include "list_ext.h"
73643 +
73644 +
73645 +void LIST_Append(t_List *p_NewList, t_List *p_Head)
73646 +{
73647 + t_List *p_First = LIST_FIRST(p_NewList);
73648 +
73649 + if (p_First != p_NewList)
73650 + {
73651 + t_List *p_Last = LIST_LAST(p_NewList);
73652 + t_List *p_Cur = LIST_NEXT(p_Head);
73653 +
73654 + LIST_PREV(p_First) = p_Head;
73655 + LIST_FIRST(p_Head) = p_First;
73656 + LIST_NEXT(p_Last) = p_Cur;
73657 + LIST_LAST(p_Cur) = p_Last;
73658 + }
73659 +}
73660 +
73661 +
73662 +int LIST_NumOfObjs(t_List *p_List)
73663 +{
73664 + t_List *p_Tmp;
73665 + int numOfObjs = 0;
73666 +
73667 + if (!LIST_IsEmpty(p_List))
73668 + LIST_FOR_EACH(p_Tmp, p_List)
73669 + numOfObjs++;
73670 +
73671 + return numOfObjs;
73672 +}
73673 --- /dev/null
73674 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
73675 @@ -0,0 +1,620 @@
73676 +/*
73677 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73678 + *
73679 + * Redistribution and use in source and binary forms, with or without
73680 + * modification, are permitted provided that the following conditions are met:
73681 + * * Redistributions of source code must retain the above copyright
73682 + * notice, this list of conditions and the following disclaimer.
73683 + * * Redistributions in binary form must reproduce the above copyright
73684 + * notice, this list of conditions and the following disclaimer in the
73685 + * documentation and/or other materials provided with the distribution.
73686 + * * Neither the name of Freescale Semiconductor nor the
73687 + * names of its contributors may be used to endorse or promote products
73688 + * derived from this software without specific prior written permission.
73689 + *
73690 + *
73691 + * ALTERNATIVELY, this software may be distributed under the terms of the
73692 + * GNU General Public License ("GPL") as published by the Free Software
73693 + * Foundation, either version 2 of that License or (at your option) any
73694 + * later version.
73695 + *
73696 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73697 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73698 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73699 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73700 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73701 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73702 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73703 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73704 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73705 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73706 + */
73707 +
73708 +
73709 +
73710 +#include "std_ext.h"
73711 +#include "xx_ext.h"
73712 +#include "memcpy_ext.h"
73713 +
73714 +void * MemCpy8(void* pDst, void* pSrc, uint32_t size)
73715 +{
73716 + int i;
73717 +
73718 + for(i = 0; i < size; ++i)
73719 + *(((uint8_t*)(pDst)) + i) = *(((uint8_t*)(pSrc)) + i);
73720 +
73721 + return pDst;
73722 +}
73723 +
73724 +void * MemSet8(void* pDst, int c, uint32_t size)
73725 +{
73726 + int i;
73727 +
73728 + for(i = 0; i < size; ++i)
73729 + *(((uint8_t*)(pDst)) + i) = (uint8_t)(c);
73730 +
73731 + return pDst;
73732 +}
73733 +
73734 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size)
73735 +{
73736 + uint32_t leftAlign;
73737 + uint32_t rightAlign;
73738 + uint32_t lastWord;
73739 + uint32_t currWord;
73740 + uint32_t *p_Src32;
73741 + uint32_t *p_Dst32;
73742 + uint8_t *p_Src8;
73743 + uint8_t *p_Dst8;
73744 +
73745 + p_Src8 = (uint8_t*)(pSrc);
73746 + p_Dst8 = (uint8_t*)(pDst);
73747 + /* first copy byte by byte till the source first alignment
73748 + * this step is necessary to ensure we do not even try to access
73749 + * data which is before the source buffer, hence it is not ours.
73750 + */
73751 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73752 + {
73753 + *p_Dst8++ = *p_Src8++;
73754 + size--;
73755 + }
73756 +
73757 + /* align destination (possibly disaligning source)*/
73758 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73759 + {
73760 + *p_Dst8++ = *p_Src8++;
73761 + size--;
73762 + }
73763 +
73764 + /* dest is aligned and source is not necessarily aligned */
73765 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73766 + rightAlign = 32 - leftAlign;
73767 +
73768 +
73769 + if (leftAlign == 0)
73770 + {
73771 + /* source is also aligned */
73772 + p_Src32 = (uint32_t*)(p_Src8);
73773 + p_Dst32 = (uint32_t*)(p_Dst8);
73774 + while (size >> 2) /* size >= 4 */
73775 + {
73776 + *p_Dst32++ = *p_Src32++;
73777 + size -= 4;
73778 + }
73779 + p_Src8 = (uint8_t*)(p_Src32);
73780 + p_Dst8 = (uint8_t*)(p_Dst32);
73781 + }
73782 + else
73783 + {
73784 + /* source is not aligned (destination is aligned)*/
73785 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
73786 + p_Dst32 = (uint32_t*)(p_Dst8);
73787 + lastWord = *p_Src32++;
73788 + while(size >> 3) /* size >= 8 */
73789 + {
73790 + currWord = *p_Src32;
73791 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
73792 + lastWord = currWord;
73793 + p_Src32++;
73794 + p_Dst32++;
73795 + size -= 4;
73796 + }
73797 + p_Dst8 = (uint8_t*)(p_Dst32);
73798 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
73799 + }
73800 +
73801 + /* complete the left overs */
73802 + while (size--)
73803 + *p_Dst8++ = *p_Src8++;
73804 +
73805 + return pDst;
73806 +}
73807 +
73808 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size)
73809 +{
73810 + uint32_t leftAlign;
73811 + uint32_t rightAlign;
73812 + uint32_t lastWord;
73813 + uint32_t currWord;
73814 + uint32_t *p_Src32;
73815 + uint32_t *p_Dst32;
73816 + uint8_t *p_Src8;
73817 + uint8_t *p_Dst8;
73818 +
73819 + p_Src8 = (uint8_t*)(pSrc);
73820 + p_Dst8 = (uint8_t*)(pDst);
73821 + /* first copy byte by byte till the source first alignment
73822 + * this step is necessary to ensure we do not even try to access
73823 + * data which is before the source buffer, hence it is not ours.
73824 + */
73825 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73826 + {
73827 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
73828 + p_Dst8++;p_Src8++;
73829 + size--;
73830 + }
73831 +
73832 + /* align destination (possibly disaligning source)*/
73833 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73834 + {
73835 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
73836 + p_Dst8++;p_Src8++;
73837 + size--;
73838 + }
73839 +
73840 + /* dest is aligned and source is not necessarily aligned */
73841 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73842 + rightAlign = 32 - leftAlign;
73843 +
73844 + if (leftAlign == 0)
73845 + {
73846 + /* source is also aligned */
73847 + p_Src32 = (uint32_t*)(p_Src8);
73848 + p_Dst32 = (uint32_t*)(p_Dst8);
73849 + while (size >> 2) /* size >= 4 */
73850 + {
73851 + WRITE_UINT32(*p_Dst32, GET_UINT32(*p_Src32));
73852 + p_Dst32++;p_Src32++;
73853 + size -= 4;
73854 + }
73855 + p_Src8 = (uint8_t*)(p_Src32);
73856 + p_Dst8 = (uint8_t*)(p_Dst32);
73857 + }
73858 + else
73859 + {
73860 + /* source is not aligned (destination is aligned)*/
73861 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
73862 + p_Dst32 = (uint32_t*)(p_Dst8);
73863 + lastWord = GET_UINT32(*p_Src32);
73864 + p_Src32++;
73865 + while(size >> 3) /* size >= 8 */
73866 + {
73867 + currWord = GET_UINT32(*p_Src32);
73868 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
73869 + lastWord = currWord;
73870 + p_Src32++;p_Dst32++;
73871 + size -= 4;
73872 + }
73873 + p_Dst8 = (uint8_t*)(p_Dst32);
73874 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
73875 + }
73876 +
73877 + /* complete the left overs */
73878 + while (size--)
73879 + {
73880 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
73881 + p_Dst8++;p_Src8++;
73882 + }
73883 +
73884 + return pDst;
73885 +}
73886 +
73887 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size)
73888 +{
73889 + uint32_t leftAlign;
73890 + uint32_t rightAlign;
73891 + uint32_t lastWord;
73892 + uint32_t currWord;
73893 + uint32_t *p_Src32;
73894 + uint32_t *p_Dst32;
73895 + uint8_t *p_Src8;
73896 + uint8_t *p_Dst8;
73897 +
73898 + p_Src8 = (uint8_t*)(pSrc);
73899 + p_Dst8 = (uint8_t*)(pDst);
73900 + /* first copy byte by byte till the source first alignment
73901 + * this step is necessary to ensure we do not even try to access
73902 + * data which is before the source buffer, hence it is not ours.
73903 + */
73904 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73905 + {
73906 + WRITE_UINT8(*p_Dst8, *p_Src8);
73907 + p_Dst8++;p_Src8++;
73908 + size--;
73909 + }
73910 +
73911 + /* align destination (possibly disaligning source)*/
73912 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73913 + {
73914 + WRITE_UINT8(*p_Dst8, *p_Src8);
73915 + p_Dst8++;p_Src8++;
73916 + size--;
73917 + }
73918 +
73919 + /* dest is aligned and source is not necessarily aligned */
73920 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73921 + rightAlign = 32 - leftAlign;
73922 +
73923 + if (leftAlign == 0)
73924 + {
73925 + /* source is also aligned */
73926 + p_Src32 = (uint32_t*)(p_Src8);
73927 + p_Dst32 = (uint32_t*)(p_Dst8);
73928 + while (size >> 2) /* size >= 4 */
73929 + {
73930 + WRITE_UINT32(*p_Dst32, *p_Src32);
73931 + p_Dst32++;p_Src32++;
73932 + size -= 4;
73933 + }
73934 + p_Src8 = (uint8_t*)(p_Src32);
73935 + p_Dst8 = (uint8_t*)(p_Dst32);
73936 + }
73937 + else
73938 + {
73939 + /* source is not aligned (destination is aligned)*/
73940 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
73941 + p_Dst32 = (uint32_t*)(p_Dst8);
73942 + lastWord = *p_Src32++;
73943 + while(size >> 3) /* size >= 8 */
73944 + {
73945 + currWord = *p_Src32;
73946 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
73947 + lastWord = currWord;
73948 + p_Src32++;p_Dst32++;
73949 + size -= 4;
73950 + }
73951 + p_Dst8 = (uint8_t*)(p_Dst32);
73952 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
73953 + }
73954 +
73955 + /* complete the left overs */
73956 + while (size--)
73957 + {
73958 + WRITE_UINT8(*p_Dst8, *p_Src8);
73959 + p_Dst8++;p_Src8++;
73960 + }
73961 +
73962 + return pDst;
73963 +}
73964 +
73965 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size)
73966 +{
73967 + uint32_t leftAlign;
73968 + uint32_t rightAlign;
73969 + uint32_t lastWord;
73970 + uint32_t currWord;
73971 + uint32_t *p_Src32;
73972 + uint32_t *p_Dst32;
73973 + uint8_t *p_Src8;
73974 + uint8_t *p_Dst8;
73975 +
73976 + p_Src8 = (uint8_t*)(pSrc);
73977 + p_Dst8 = (uint8_t*)(pDst);
73978 + /* first copy byte by byte till the source first alignment
73979 + * this step is necessary to ensure we do not even try to access
73980 + * data which is before the source buffer, hence it is not ours.
73981 + */
73982 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73983 + {
73984 + *p_Dst8 = GET_UINT8(*p_Src8);
73985 + p_Dst8++;p_Src8++;
73986 + size--;
73987 + }
73988 +
73989 + /* align destination (possibly disaligning source)*/
73990 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73991 + {
73992 + *p_Dst8 = GET_UINT8(*p_Src8);
73993 + p_Dst8++;p_Src8++;
73994 + size--;
73995 + }
73996 +
73997 + /* dest is aligned and source is not necessarily aligned */
73998 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73999 + rightAlign = 32 - leftAlign;
74000 +
74001 + if (leftAlign == 0)
74002 + {
74003 + /* source is also aligned */
74004 + p_Src32 = (uint32_t*)(p_Src8);
74005 + p_Dst32 = (uint32_t*)(p_Dst8);
74006 + while (size >> 2) /* size >= 4 */
74007 + {
74008 + *p_Dst32 = GET_UINT32(*p_Src32);
74009 + p_Dst32++;p_Src32++;
74010 + size -= 4;
74011 + }
74012 + p_Src8 = (uint8_t*)(p_Src32);
74013 + p_Dst8 = (uint8_t*)(p_Dst32);
74014 + }
74015 + else
74016 + {
74017 + /* source is not aligned (destination is aligned)*/
74018 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74019 + p_Dst32 = (uint32_t*)(p_Dst8);
74020 + lastWord = GET_UINT32(*p_Src32);
74021 + p_Src32++;
74022 + while(size >> 3) /* size >= 8 */
74023 + {
74024 + currWord = GET_UINT32(*p_Src32);
74025 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
74026 + lastWord = currWord;
74027 + p_Src32++;p_Dst32++;
74028 + size -= 4;
74029 + }
74030 + p_Dst8 = (uint8_t*)(p_Dst32);
74031 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74032 + }
74033 +
74034 + /* complete the left overs */
74035 + while (size--)
74036 + {
74037 + *p_Dst8 = GET_UINT8(*p_Src8);
74038 + p_Dst8++;p_Src8++;
74039 + }
74040 +
74041 + return pDst;
74042 +}
74043 +
74044 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size)
74045 +{
74046 + uint32_t leftAlign;
74047 + uint32_t rightAlign;
74048 + uint64_t lastWord;
74049 + uint64_t currWord;
74050 + uint64_t *pSrc64;
74051 + uint64_t *pDst64;
74052 + uint8_t *p_Src8;
74053 + uint8_t *p_Dst8;
74054 +
74055 + p_Src8 = (uint8_t*)(pSrc);
74056 + p_Dst8 = (uint8_t*)(pDst);
74057 + /* first copy byte by byte till the source first alignment
74058 + * this step is necessarily to ensure we do not even try to access
74059 + * data which is before the source buffer, hence it is not ours.
74060 + */
74061 + while((PTR_TO_UINT(p_Src8) & 7) && size) /* (pSrc mod 8) > 0 and size > 0 */
74062 + {
74063 + *p_Dst8++ = *p_Src8++;
74064 + size--;
74065 + }
74066 +
74067 + /* align destination (possibly disaligning source)*/
74068 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
74069 + {
74070 + *p_Dst8++ = *p_Src8++;
74071 + size--;
74072 + }
74073 +
74074 + /* dest is aligned and source is not necessarily aligned */
74075 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 7) << 3); /* leftAlign = (pSrc mod 8)*8 */
74076 + rightAlign = 64 - leftAlign;
74077 +
74078 +
74079 + if (leftAlign == 0)
74080 + {
74081 + /* source is also aligned */
74082 + pSrc64 = (uint64_t*)(p_Src8);
74083 + pDst64 = (uint64_t*)(p_Dst8);
74084 + while (size >> 3) /* size >= 8 */
74085 + {
74086 + *pDst64++ = *pSrc64++;
74087 + size -= 8;
74088 + }
74089 + p_Src8 = (uint8_t*)(pSrc64);
74090 + p_Dst8 = (uint8_t*)(pDst64);
74091 + }
74092 + else
74093 + {
74094 + /* source is not aligned (destination is aligned)*/
74095 + pSrc64 = (uint64_t*)(p_Src8 - (leftAlign >> 3));
74096 + pDst64 = (uint64_t*)(p_Dst8);
74097 + lastWord = *pSrc64++;
74098 + while(size >> 4) /* size >= 16 */
74099 + {
74100 + currWord = *pSrc64;
74101 + *pDst64 = (lastWord << leftAlign) | (currWord >> rightAlign);
74102 + lastWord = currWord;
74103 + pSrc64++;
74104 + pDst64++;
74105 + size -= 8;
74106 + }
74107 + p_Dst8 = (uint8_t*)(pDst64);
74108 + p_Src8 = (uint8_t*)(pSrc64) - 8 + (leftAlign >> 3);
74109 + }
74110 +
74111 + /* complete the left overs */
74112 + while (size--)
74113 + *p_Dst8++ = *p_Src8++;
74114 +
74115 + return pDst;
74116 +}
74117 +
74118 +void * MemSet32(void* pDst, uint8_t val, uint32_t size)
74119 +{
74120 + uint32_t val32;
74121 + uint32_t *p_Dst32;
74122 + uint8_t *p_Dst8;
74123 +
74124 + p_Dst8 = (uint8_t*)(pDst);
74125 +
74126 + /* generate four 8-bit val's in 32-bit container */
74127 + val32 = (uint32_t) val;
74128 + val32 |= (val32 << 8);
74129 + val32 |= (val32 << 16);
74130 +
74131 + /* align destination to 32 */
74132 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74133 + {
74134 + *p_Dst8++ = val;
74135 + size--;
74136 + }
74137 +
74138 + /* 32-bit chunks */
74139 + p_Dst32 = (uint32_t*)(p_Dst8);
74140 + while (size >> 2) /* size >= 4 */
74141 + {
74142 + *p_Dst32++ = val32;
74143 + size -= 4;
74144 + }
74145 +
74146 + /* complete the leftovers */
74147 + p_Dst8 = (uint8_t*)(p_Dst32);
74148 + while (size--)
74149 + *p_Dst8++ = val;
74150 +
74151 + return pDst;
74152 +}
74153 +
74154 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size)
74155 +{
74156 + uint32_t val32;
74157 + uint32_t *p_Dst32;
74158 + uint8_t *p_Dst8;
74159 +
74160 + p_Dst8 = (uint8_t*)(pDst);
74161 +
74162 + /* generate four 8-bit val's in 32-bit container */
74163 + val32 = (uint32_t) val;
74164 + val32 |= (val32 << 8);
74165 + val32 |= (val32 << 16);
74166 +
74167 + /* align destination to 32 */
74168 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74169 + {
74170 + WRITE_UINT8(*p_Dst8, val);
74171 + p_Dst8++;
74172 + size--;
74173 + }
74174 +
74175 + /* 32-bit chunks */
74176 + p_Dst32 = (uint32_t*)(p_Dst8);
74177 + while (size >> 2) /* size >= 4 */
74178 + {
74179 + WRITE_UINT32(*p_Dst32, val32);
74180 + p_Dst32++;
74181 + size -= 4;
74182 + }
74183 +
74184 + /* complete the leftovers */
74185 + p_Dst8 = (uint8_t*)(p_Dst32);
74186 + while (size--)
74187 + {
74188 + WRITE_UINT8(*p_Dst8, val);
74189 + p_Dst8++;
74190 + }
74191 +
74192 + return pDst;
74193 +}
74194 +
74195 +void * MemSet64(void* pDst, uint8_t val, uint32_t size)
74196 +{
74197 + uint64_t val64;
74198 + uint64_t *pDst64;
74199 + uint8_t *p_Dst8;
74200 +
74201 + p_Dst8 = (uint8_t*)(pDst);
74202 +
74203 + /* generate four 8-bit val's in 32-bit container */
74204 + val64 = (uint64_t) val;
74205 + val64 |= (val64 << 8);
74206 + val64 |= (val64 << 16);
74207 + val64 |= (val64 << 24);
74208 + val64 |= (val64 << 32);
74209 +
74210 + /* align destination to 64 */
74211 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
74212 + {
74213 + *p_Dst8++ = val;
74214 + size--;
74215 + }
74216 +
74217 + /* 64-bit chunks */
74218 + pDst64 = (uint64_t*)(p_Dst8);
74219 + while (size >> 4) /* size >= 8 */
74220 + {
74221 + *pDst64++ = val64;
74222 + size -= 8;
74223 + }
74224 +
74225 + /* complete the leftovers */
74226 + p_Dst8 = (uint8_t*)(pDst64);
74227 + while (size--)
74228 + *p_Dst8++ = val;
74229 +
74230 + return pDst;
74231 +}
74232 +
74233 +void MemDisp(uint8_t *p, int size)
74234 +{
74235 + uint32_t space = (uint32_t)(PTR_TO_UINT(p) & 0x3);
74236 + uint8_t *p_Limit;
74237 +
74238 + if (space)
74239 + {
74240 + p_Limit = (p - space + 4);
74241 +
74242 + XX_Print("0x%08X: ", (p - space));
74243 +
74244 + while (space--)
74245 + {
74246 + XX_Print("--");
74247 + }
74248 + while (size && (p < p_Limit))
74249 + {
74250 + XX_Print("%02x", *(uint8_t*)p);
74251 + size--;
74252 + p++;
74253 + }
74254 +
74255 + XX_Print(" ");
74256 + p_Limit += 12;
74257 +
74258 + while ((size > 3) && (p < p_Limit))
74259 + {
74260 + XX_Print("%08x ", *(uint32_t*)p);
74261 + size -= 4;
74262 + p += 4;
74263 + }
74264 + XX_Print("\r\n");
74265 + }
74266 +
74267 + while (size > 15)
74268 + {
74269 + XX_Print("0x%08X: %08x %08x %08x %08x\r\n",
74270 + p, *(uint32_t *)p, *(uint32_t *)(p + 4),
74271 + *(uint32_t *)(p + 8), *(uint32_t *)(p + 12));
74272 + size -= 16;
74273 + p += 16;
74274 + }
74275 +
74276 + if (size)
74277 + {
74278 + XX_Print("0x%08X: ", p);
74279 +
74280 + while (size > 3)
74281 + {
74282 + XX_Print("%08x ", *(uint32_t *)p);
74283 + size -= 4;
74284 + p += 4;
74285 + }
74286 + while (size)
74287 + {
74288 + XX_Print("%02x", *(uint8_t *)p);
74289 + size--;
74290 + p++;
74291 + }
74292 +
74293 + XX_Print("\r\n");
74294 + }
74295 +}
74296 --- /dev/null
74297 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
74298 @@ -0,0 +1,1155 @@
74299 +/*
74300 + * Copyright 2008-2012 Freescale Semiconductor Inc.
74301 + *
74302 + * Redistribution and use in source and binary forms, with or without
74303 + * modification, are permitted provided that the following conditions are met:
74304 + * * Redistributions of source code must retain the above copyright
74305 + * notice, this list of conditions and the following disclaimer.
74306 + * * Redistributions in binary form must reproduce the above copyright
74307 + * notice, this list of conditions and the following disclaimer in the
74308 + * documentation and/or other materials provided with the distribution.
74309 + * * Neither the name of Freescale Semiconductor nor the
74310 + * names of its contributors may be used to endorse or promote products
74311 + * derived from this software without specific prior written permission.
74312 + *
74313 + *
74314 + * ALTERNATIVELY, this software may be distributed under the terms of the
74315 + * GNU General Public License ("GPL") as published by the Free Software
74316 + * Foundation, either version 2 of that License or (at your option) any
74317 + * later version.
74318 + *
74319 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
74320 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74321 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74322 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
74323 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
74324 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
74325 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
74326 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74327 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74328 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74329 + */
74330 +
74331 +
74332 +#include "string_ext.h"
74333 +#include "error_ext.h"
74334 +#include "std_ext.h"
74335 +#include "part_ext.h"
74336 +#include "xx_ext.h"
74337 +
74338 +#include "mm.h"
74339 +
74340 +
74341 +
74342 +
74343 +/**********************************************************************
74344 + * MM internal routines set *
74345 + **********************************************************************/
74346 +
74347 +/****************************************************************
74348 + * Routine: CreateBusyBlock
74349 + *
74350 + * Description:
74351 + * Initializes a new busy block of "size" bytes and started
74352 + * rom "base" address. Each busy block has a name that
74353 + * specified the purpose of the memory allocation.
74354 + *
74355 + * Arguments:
74356 + * base - base address of the busy block
74357 + * size - size of the busy block
74358 + * name - name that specified the busy block
74359 + *
74360 + * Return value:
74361 + * A pointer to new created structure returned on success;
74362 + * Otherwise, NULL.
74363 + ****************************************************************/
74364 +static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name)
74365 +{
74366 + t_BusyBlock *p_BusyBlock;
74367 + uint32_t n;
74368 +
74369 + p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock));
74370 + if ( !p_BusyBlock )
74371 + {
74372 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74373 + return NULL;
74374 + }
74375 +
74376 + p_BusyBlock->base = base;
74377 + p_BusyBlock->end = base + size;
74378 +
74379 + n = strlen(name);
74380 + if (n >= MM_MAX_NAME_LEN)
74381 + n = MM_MAX_NAME_LEN - 1;
74382 + strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1);
74383 + p_BusyBlock->name[n] = '\0';
74384 + p_BusyBlock->p_Next = 0;
74385 +
74386 + return p_BusyBlock;
74387 +}
74388 +
74389 +/****************************************************************
74390 + * Routine: CreateNewBlock
74391 + *
74392 + * Description:
74393 + * Initializes a new memory block of "size" bytes and started
74394 + * from "base" address.
74395 + *
74396 + * Arguments:
74397 + * base - base address of the memory block
74398 + * size - size of the memory block
74399 + *
74400 + * Return value:
74401 + * A pointer to new created structure returned on success;
74402 + * Otherwise, NULL.
74403 + ****************************************************************/
74404 +static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size)
74405 +{
74406 + t_MemBlock *p_MemBlock;
74407 +
74408 + p_MemBlock = (t_MemBlock *)XX_Malloc(sizeof(t_MemBlock));
74409 + if ( !p_MemBlock )
74410 + {
74411 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74412 + return NULL;
74413 + }
74414 +
74415 + p_MemBlock->base = base;
74416 + p_MemBlock->end = base+size;
74417 + p_MemBlock->p_Next = 0;
74418 +
74419 + return p_MemBlock;
74420 +}
74421 +
74422 +/****************************************************************
74423 + * Routine: CreateFreeBlock
74424 + *
74425 + * Description:
74426 + * Initializes a new free block of of "size" bytes and
74427 + * started from "base" address.
74428 + *
74429 + * Arguments:
74430 + * base - base address of the free block
74431 + * size - size of the free block
74432 + *
74433 + * Return value:
74434 + * A pointer to new created structure returned on success;
74435 + * Otherwise, NULL.
74436 + ****************************************************************/
74437 +static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size)
74438 +{
74439 + t_FreeBlock *p_FreeBlock;
74440 +
74441 + p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock));
74442 + if ( !p_FreeBlock )
74443 + {
74444 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74445 + return NULL;
74446 + }
74447 +
74448 + p_FreeBlock->base = base;
74449 + p_FreeBlock->end = base + size;
74450 + p_FreeBlock->p_Next = 0;
74451 +
74452 + return p_FreeBlock;
74453 +}
74454 +
74455 +/****************************************************************
74456 + * Routine: AddFree
74457 + *
74458 + * Description:
74459 + * Adds a new free block to the free lists. It updates each
74460 + * free list to include a new free block.
74461 + * Note, that all free block in each free list are ordered
74462 + * by their base address.
74463 + *
74464 + * Arguments:
74465 + * p_MM - pointer to the MM object
74466 + * base - base address of a given free block
74467 + * end - end address of a given free block
74468 + *
74469 + * Return value:
74470 + *
74471 + *
74472 + ****************************************************************/
74473 +static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end)
74474 +{
74475 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74476 + uint64_t alignment;
74477 + uint64_t alignBase;
74478 + int i;
74479 +
74480 + /* Updates free lists to include a just released block */
74481 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74482 + {
74483 + p_PrevB = p_NewB = 0;
74484 + p_CurrB = p_MM->freeBlocks[i];
74485 +
74486 + alignment = (uint64_t)(0x1 << i);
74487 + alignBase = MAKE_ALIGNED(base, alignment);
74488 +
74489 + /* Goes to the next free list if there is no block to free */
74490 + if (alignBase >= end)
74491 + continue;
74492 +
74493 + /* Looks for a free block that should be updated */
74494 + while ( p_CurrB )
74495 + {
74496 + if ( alignBase <= p_CurrB->end )
74497 + {
74498 + if ( end > p_CurrB->end )
74499 + {
74500 + t_FreeBlock *p_NextB;
74501 + while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end )
74502 + {
74503 + p_NextB = p_CurrB->p_Next;
74504 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
74505 + XX_Free(p_NextB);
74506 + }
74507 +
74508 + p_NextB = p_CurrB->p_Next;
74509 + if ( !p_NextB || (p_NextB && end < p_NextB->base) )
74510 + {
74511 + p_CurrB->end = end;
74512 + }
74513 + else
74514 + {
74515 + p_CurrB->end = p_NextB->end;
74516 + p_CurrB->p_Next = p_NextB->p_Next;
74517 + XX_Free(p_NextB);
74518 + }
74519 + }
74520 + else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) )
74521 + {
74522 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74523 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74524 +
74525 + p_NewB->p_Next = p_CurrB;
74526 + if (p_PrevB)
74527 + p_PrevB->p_Next = p_NewB;
74528 + else
74529 + p_MM->freeBlocks[i] = p_NewB;
74530 + break;
74531 + }
74532 +
74533 + if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base))
74534 + {
74535 + p_CurrB->base = alignBase;
74536 + }
74537 +
74538 + /* if size of the free block is less then alignment
74539 + * deletes that free block from the free list. */
74540 + if ( (p_CurrB->end - p_CurrB->base) < alignment)
74541 + {
74542 + if ( p_PrevB )
74543 + p_PrevB->p_Next = p_CurrB->p_Next;
74544 + else
74545 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74546 + XX_Free(p_CurrB);
74547 + p_CurrB = NULL;
74548 + }
74549 + break;
74550 + }
74551 + else
74552 + {
74553 + p_PrevB = p_CurrB;
74554 + p_CurrB = p_CurrB->p_Next;
74555 + }
74556 + }
74557 +
74558 + /* If no free block found to be updated, insert a new free block
74559 + * to the end of the free list.
74560 + */
74561 + if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) )
74562 + {
74563 + if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL)
74564 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74565 +
74566 + if (p_PrevB)
74567 + p_PrevB->p_Next = p_NewB;
74568 + else
74569 + p_MM->freeBlocks[i] = p_NewB;
74570 + }
74571 +
74572 + /* Update boundaries of the new free block */
74573 + if ((alignment == 1) && !p_NewB)
74574 + {
74575 + if ( p_CurrB && base > p_CurrB->base )
74576 + base = p_CurrB->base;
74577 + if ( p_CurrB && end < p_CurrB->end )
74578 + end = p_CurrB->end;
74579 + }
74580 + }
74581 +
74582 + return (E_OK);
74583 +}
74584 +
74585 +/****************************************************************
74586 + * Routine: CutFree
74587 + *
74588 + * Description:
74589 + * Cuts a free block from holdBase to holdEnd from the free lists.
74590 + * That is, it updates all free lists of the MM object do
74591 + * not include a block of memory from holdBase to holdEnd.
74592 + * For each free lists it seek for a free block that holds
74593 + * either holdBase or holdEnd. If such block is found it updates it.
74594 + *
74595 + * Arguments:
74596 + * p_MM - pointer to the MM object
74597 + * holdBase - base address of the allocated block
74598 + * holdEnd - end address of the allocated block
74599 + *
74600 + * Return value:
74601 + * E_OK is returned on success,
74602 + * otherwise returns an error code.
74603 + *
74604 + ****************************************************************/
74605 +static t_Error CutFree(t_MM *p_MM, uint64_t holdBase, uint64_t holdEnd)
74606 +{
74607 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74608 + uint64_t alignBase, base, end;
74609 + uint64_t alignment;
74610 + int i;
74611 +
74612 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74613 + {
74614 + p_PrevB = p_NewB = 0;
74615 + p_CurrB = p_MM->freeBlocks[i];
74616 +
74617 + alignment = (uint64_t)(0x1 << i);
74618 + alignBase = MAKE_ALIGNED(holdEnd, alignment);
74619 +
74620 + while ( p_CurrB )
74621 + {
74622 + base = p_CurrB->base;
74623 + end = p_CurrB->end;
74624 +
74625 + if ( (holdBase <= base) && (holdEnd <= end) && (holdEnd > base) )
74626 + {
74627 + if ( alignBase >= end ||
74628 + (alignBase < end && ((end-alignBase) < alignment)) )
74629 + {
74630 + if (p_PrevB)
74631 + p_PrevB->p_Next = p_CurrB->p_Next;
74632 + else
74633 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74634 + XX_Free(p_CurrB);
74635 + }
74636 + else
74637 + {
74638 + p_CurrB->base = alignBase;
74639 + }
74640 + break;
74641 + }
74642 + else if ( (holdBase > base) && (holdEnd <= end) )
74643 + {
74644 + if ( (holdBase-base) >= alignment )
74645 + {
74646 + if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74647 + {
74648 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74649 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74650 + p_NewB->p_Next = p_CurrB->p_Next;
74651 + p_CurrB->p_Next = p_NewB;
74652 + }
74653 + p_CurrB->end = holdBase;
74654 + }
74655 + else if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74656 + {
74657 + p_CurrB->base = alignBase;
74658 + }
74659 + else
74660 + {
74661 + if (p_PrevB)
74662 + p_PrevB->p_Next = p_CurrB->p_Next;
74663 + else
74664 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74665 + XX_Free(p_CurrB);
74666 + }
74667 + break;
74668 + }
74669 + else
74670 + {
74671 + p_PrevB = p_CurrB;
74672 + p_CurrB = p_CurrB->p_Next;
74673 + }
74674 + }
74675 + }
74676 +
74677 + return (E_OK);
74678 +}
74679 +
74680 +/****************************************************************
74681 + * Routine: AddBusy
74682 + *
74683 + * Description:
74684 + * Adds a new busy block to the list of busy blocks. Note,
74685 + * that all busy blocks are ordered by their base address in
74686 + * the busy list.
74687 + *
74688 + * Arguments:
74689 + * MM - handler to the MM object
74690 + * p_NewBusyB - pointer to the a busy block
74691 + *
74692 + * Return value:
74693 + * None.
74694 + *
74695 + ****************************************************************/
74696 +static void AddBusy(t_MM *p_MM, t_BusyBlock *p_NewBusyB)
74697 +{
74698 + t_BusyBlock *p_CurrBusyB, *p_PrevBusyB;
74699 +
74700 + /* finds a place of a new busy block in the list of busy blocks */
74701 + p_PrevBusyB = 0;
74702 + p_CurrBusyB = p_MM->busyBlocks;
74703 +
74704 + while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base )
74705 + {
74706 + p_PrevBusyB = p_CurrBusyB;
74707 + p_CurrBusyB = p_CurrBusyB->p_Next;
74708 + }
74709 +
74710 + /* insert the new busy block into the list of busy blocks */
74711 + if ( p_CurrBusyB )
74712 + p_NewBusyB->p_Next = p_CurrBusyB;
74713 + if ( p_PrevBusyB )
74714 + p_PrevBusyB->p_Next = p_NewBusyB;
74715 + else
74716 + p_MM->busyBlocks = p_NewBusyB;
74717 +}
74718 +
74719 +/****************************************************************
74720 + * Routine: CutBusy
74721 + *
74722 + * Description:
74723 + * Cuts a block from base to end from the list of busy blocks.
74724 + * This is done by updating the list of busy blocks do not
74725 + * include a given block, that block is going to be free. If a
74726 + * given block is a part of some other busy block, so that
74727 + * busy block is updated. If there are number of busy blocks
74728 + * included in the given block, so all that blocks are removed
74729 + * from the busy list and the end blocks are updated.
74730 + * If the given block devides some block into two parts, a new
74731 + * busy block is added to the busy list.
74732 + *
74733 + * Arguments:
74734 + * p_MM - pointer to the MM object
74735 + * base - base address of a given busy block
74736 + * end - end address of a given busy block
74737 + *
74738 + * Return value:
74739 + * E_OK on success, E_NOMEMORY otherwise.
74740 + *
74741 + ****************************************************************/
74742 +static t_Error CutBusy(t_MM *p_MM, uint64_t base, uint64_t end)
74743 +{
74744 + t_BusyBlock *p_CurrB, *p_PrevB, *p_NewB;
74745 +
74746 + p_CurrB = p_MM->busyBlocks;
74747 + p_PrevB = p_NewB = 0;
74748 +
74749 + while ( p_CurrB )
74750 + {
74751 + if ( base < p_CurrB->end )
74752 + {
74753 + if ( end > p_CurrB->end )
74754 + {
74755 + t_BusyBlock *p_NextB;
74756 + while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end )
74757 + {
74758 + p_NextB = p_CurrB->p_Next;
74759 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
74760 + XX_Free(p_NextB);
74761 + }
74762 +
74763 + p_NextB = p_CurrB->p_Next;
74764 + if ( p_NextB && end > p_NextB->base )
74765 + {
74766 + p_NextB->base = end;
74767 + }
74768 + }
74769 +
74770 + if ( base <= p_CurrB->base )
74771 + {
74772 + if ( end < p_CurrB->end && end > p_CurrB->base )
74773 + {
74774 + p_CurrB->base = end;
74775 + }
74776 + else if ( end >= p_CurrB->end )
74777 + {
74778 + if ( p_PrevB )
74779 + p_PrevB->p_Next = p_CurrB->p_Next;
74780 + else
74781 + p_MM->busyBlocks = p_CurrB->p_Next;
74782 + XX_Free(p_CurrB);
74783 + }
74784 + }
74785 + else
74786 + {
74787 + if ( end < p_CurrB->end && end > p_CurrB->base )
74788 + {
74789 + if ((p_NewB = CreateBusyBlock(end,
74790 + p_CurrB->end-end,
74791 + p_CurrB->name)) == NULL)
74792 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74793 + p_NewB->p_Next = p_CurrB->p_Next;
74794 + p_CurrB->p_Next = p_NewB;
74795 + }
74796 + p_CurrB->end = base;
74797 + }
74798 + break;
74799 + }
74800 + else
74801 + {
74802 + p_PrevB = p_CurrB;
74803 + p_CurrB = p_CurrB->p_Next;
74804 + }
74805 + }
74806 +
74807 + return (E_OK);
74808 +}
74809 +
74810 +/****************************************************************
74811 + * Routine: MmGetGreaterAlignment
74812 + *
74813 + * Description:
74814 + * Allocates a block of memory according to the given size
74815 + * and the alignment. That routine is called from the MM_Get
74816 + * routine if the required alignment is greater then MM_MAX_ALIGNMENT.
74817 + * In that case, it goes over free blocks of 64 byte align list
74818 + * and checks if it has the required size of bytes of the required
74819 + * alignment. If no blocks found returns ILLEGAL_BASE.
74820 + * After the block is found and data is allocated, it calls
74821 + * the internal CutFree routine to update all free lists
74822 + * do not include a just allocated block. Of course, each
74823 + * free list contains a free blocks with the same alignment.
74824 + * It is also creates a busy block that holds
74825 + * information about an allocated block.
74826 + *
74827 + * Arguments:
74828 + * MM - handle to the MM object
74829 + * size - size of the MM
74830 + * alignment - index as a power of two defines
74831 + * a required alignment that is greater then 64.
74832 + * name - the name that specifies an allocated block.
74833 + *
74834 + * Return value:
74835 + * base address of an allocated block.
74836 + * ILLEGAL_BASE if can't allocate a block
74837 + *
74838 + ****************************************************************/
74839 +static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name)
74840 +{
74841 + t_FreeBlock *p_FreeB;
74842 + t_BusyBlock *p_NewBusyB;
74843 + uint64_t holdBase, holdEnd, alignBase = 0;
74844 +
74845 + /* goes over free blocks of the 64 byte alignment list
74846 + and look for a block of the suitable size and
74847 + base address according to the alignment. */
74848 + p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT];
74849 +
74850 + while ( p_FreeB )
74851 + {
74852 + alignBase = MAKE_ALIGNED(p_FreeB->base, alignment);
74853 +
74854 + /* the block is found if the aligned base inside the block
74855 + * and has the anough size. */
74856 + if ( alignBase >= p_FreeB->base &&
74857 + alignBase < p_FreeB->end &&
74858 + size <= (p_FreeB->end - alignBase) )
74859 + break;
74860 + else
74861 + p_FreeB = p_FreeB->p_Next;
74862 + }
74863 +
74864 + /* If such block isn't found */
74865 + if ( !p_FreeB )
74866 + return (uint64_t)(ILLEGAL_BASE);
74867 +
74868 + holdBase = alignBase;
74869 + holdEnd = alignBase + size;
74870 +
74871 + /* init a new busy block */
74872 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
74873 + return (uint64_t)(ILLEGAL_BASE);
74874 +
74875 + /* calls Update routine to update a lists of free blocks */
74876 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
74877 + {
74878 + XX_Free(p_NewBusyB);
74879 + return (uint64_t)(ILLEGAL_BASE);
74880 + }
74881 +
74882 + /* insert the new busy block into the list of busy blocks */
74883 + AddBusy ( p_MM, p_NewBusyB );
74884 +
74885 + return (holdBase);
74886 +}
74887 +
74888 +
74889 +/**********************************************************************
74890 + * MM API routines set *
74891 + **********************************************************************/
74892 +
74893 +/*****************************************************************************/
74894 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size)
74895 +{
74896 + t_MM *p_MM;
74897 + uint64_t newBase, newSize;
74898 + int i;
74899 +
74900 + if (!size)
74901 + {
74902 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)"));
74903 + }
74904 +
74905 + /* Initializes a new MM object */
74906 + p_MM = (t_MM *)XX_Malloc(sizeof(t_MM));
74907 + if (!p_MM)
74908 + {
74909 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74910 + }
74911 +
74912 + p_MM->h_Spinlock = XX_InitSpinlock();
74913 + if (!p_MM->h_Spinlock)
74914 + {
74915 + XX_Free(p_MM);
74916 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!"));
74917 + }
74918 +
74919 + /* Initializes counter of free memory to total size */
74920 + p_MM->freeMemSize = size;
74921 +
74922 + /* A busy list is empty */
74923 + p_MM->busyBlocks = 0;
74924 +
74925 + /* Initializes a new memory block */
74926 + if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL)
74927 + {
74928 + MM_Free(p_MM);
74929 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74930 + }
74931 +
74932 + /* Initializes a new free block for each free list*/
74933 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74934 + {
74935 + newBase = MAKE_ALIGNED( base, (0x1 << i) );
74936 + newSize = size - (newBase - base);
74937 +
74938 + if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL)
74939 + {
74940 + MM_Free(p_MM);
74941 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74942 + }
74943 + }
74944 +
74945 + *h_MM = p_MM;
74946 +
74947 + return (E_OK);
74948 +}
74949 +
74950 +/*****************************************************************************/
74951 +void MM_Free(t_Handle h_MM)
74952 +{
74953 + t_MM *p_MM = (t_MM *)h_MM;
74954 + t_MemBlock *p_MemBlock;
74955 + t_BusyBlock *p_BusyBlock;
74956 + t_FreeBlock *p_FreeBlock;
74957 + void *p_Block;
74958 + int i;
74959 +
74960 + ASSERT_COND(p_MM);
74961 +
74962 + /* release memory allocated for busy blocks */
74963 + p_BusyBlock = p_MM->busyBlocks;
74964 + while ( p_BusyBlock )
74965 + {
74966 + p_Block = p_BusyBlock;
74967 + p_BusyBlock = p_BusyBlock->p_Next;
74968 + XX_Free(p_Block);
74969 + }
74970 +
74971 + /* release memory allocated for free blocks */
74972 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74973 + {
74974 + p_FreeBlock = p_MM->freeBlocks[i];
74975 + while ( p_FreeBlock )
74976 + {
74977 + p_Block = p_FreeBlock;
74978 + p_FreeBlock = p_FreeBlock->p_Next;
74979 + XX_Free(p_Block);
74980 + }
74981 + }
74982 +
74983 + /* release memory allocated for memory blocks */
74984 + p_MemBlock = p_MM->memBlocks;
74985 + while ( p_MemBlock )
74986 + {
74987 + p_Block = p_MemBlock;
74988 + p_MemBlock = p_MemBlock->p_Next;
74989 + XX_Free(p_Block);
74990 + }
74991 +
74992 + if (p_MM->h_Spinlock)
74993 + XX_FreeSpinlock(p_MM->h_Spinlock);
74994 +
74995 + /* release memory allocated for MM object itself */
74996 + XX_Free(p_MM);
74997 +}
74998 +
74999 +/*****************************************************************************/
75000 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name)
75001 +{
75002 + t_MM *p_MM = (t_MM *)h_MM;
75003 + t_FreeBlock *p_FreeB;
75004 + t_BusyBlock *p_NewBusyB;
75005 + uint64_t holdBase, holdEnd, j, i = 0;
75006 + uint32_t intFlags;
75007 +
75008 + SANITY_CHECK_RETURN_VALUE(p_MM, E_INVALID_HANDLE, (uint64_t)ILLEGAL_BASE);
75009 +
75010 + /* checks that alignment value is greater then zero */
75011 + if (alignment == 0)
75012 + {
75013 + alignment = 1;
75014 + }
75015 +
75016 + j = alignment;
75017 +
75018 + /* checks if alignment is a power of two, if it correct and if the
75019 + required size is multiple of the given alignment. */
75020 + while ((j & 0x1) == 0)
75021 + {
75022 + i++;
75023 + j = j >> 1;
75024 + }
75025 +
75026 + /* if the given alignment isn't power of two, returns an error */
75027 + if (j != 1)
75028 + {
75029 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("alignment (should be power of 2)"));
75030 + return (uint64_t)ILLEGAL_BASE;
75031 + }
75032 +
75033 + if (i > MM_MAX_ALIGNMENT)
75034 + {
75035 + return (MmGetGreaterAlignment(p_MM, size, alignment, name));
75036 + }
75037 +
75038 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75039 + /* look for a block of the size greater or equal to the required size. */
75040 + p_FreeB = p_MM->freeBlocks[i];
75041 + while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size )
75042 + p_FreeB = p_FreeB->p_Next;
75043 +
75044 + /* If such block is found */
75045 + if ( !p_FreeB )
75046 + {
75047 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75048 + return (uint64_t)(ILLEGAL_BASE);
75049 + }
75050 +
75051 + holdBase = p_FreeB->base;
75052 + holdEnd = holdBase + size;
75053 +
75054 + /* init a new busy block */
75055 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75056 + {
75057 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75058 + return (uint64_t)(ILLEGAL_BASE);
75059 + }
75060 +
75061 + /* calls Update routine to update a lists of free blocks */
75062 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
75063 + {
75064 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75065 + XX_Free(p_NewBusyB);
75066 + return (uint64_t)(ILLEGAL_BASE);
75067 + }
75068 +
75069 + /* Decreasing the allocated memory size from free memory size */
75070 + p_MM->freeMemSize -= size;
75071 +
75072 + /* insert the new busy block into the list of busy blocks */
75073 + AddBusy ( p_MM, p_NewBusyB );
75074 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75075 +
75076 + return (holdBase);
75077 +}
75078 +
75079 +/*****************************************************************************/
75080 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name)
75081 +{
75082 + t_MM *p_MM = (t_MM *)h_MM;
75083 + t_FreeBlock *p_FreeB;
75084 + t_BusyBlock *p_NewBusyB;
75085 + uint32_t intFlags;
75086 + bool blockIsFree = FALSE;
75087 +
75088 + ASSERT_COND(p_MM);
75089 +
75090 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75091 + p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the
75092 + free list with alignment 1 */
75093 +
75094 + while ( p_FreeB )
75095 + {
75096 + if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end )
75097 + {
75098 + blockIsFree = TRUE;
75099 + break;
75100 + }
75101 + else
75102 + p_FreeB = p_FreeB->p_Next;
75103 + }
75104 +
75105 + if ( !blockIsFree )
75106 + {
75107 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75108 + return (uint64_t)(ILLEGAL_BASE);
75109 + }
75110 +
75111 + /* init a new busy block */
75112 + if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL)
75113 + {
75114 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75115 + return (uint64_t)(ILLEGAL_BASE);
75116 + }
75117 +
75118 + /* calls Update routine to update a lists of free blocks */
75119 + if ( CutFree ( p_MM, base, base+size ) != E_OK )
75120 + {
75121 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75122 + XX_Free(p_NewBusyB);
75123 + return (uint64_t)(ILLEGAL_BASE);
75124 + }
75125 +
75126 + /* Decreasing the allocated memory size from free memory size */
75127 + p_MM->freeMemSize -= size;
75128 +
75129 + /* insert the new busy block into the list of busy blocks */
75130 + AddBusy ( p_MM, p_NewBusyB );
75131 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75132 +
75133 + return (base);
75134 +}
75135 +
75136 +/*****************************************************************************/
75137 +uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name)
75138 +{
75139 + t_MM *p_MM = (t_MM *)h_MM;
75140 + t_FreeBlock *p_FreeB;
75141 + t_BusyBlock *p_NewBusyB;
75142 + uint64_t holdBase, holdEnd, j = alignment, i=0;
75143 + uint32_t intFlags;
75144 +
75145 + ASSERT_COND(p_MM);
75146 +
75147 + /* checks if alignment is a power of two, if it correct and if the
75148 + required size is multiple of the given alignment. */
75149 + while ((j & 0x1) == 0)
75150 + {
75151 + i++;
75152 + j = j >> 1;
75153 + }
75154 +
75155 + if ( (j != 1) || (i > MM_MAX_ALIGNMENT) )
75156 + {
75157 + return (uint64_t)(ILLEGAL_BASE);
75158 + }
75159 +
75160 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75161 + p_FreeB = p_MM->freeBlocks[i];
75162 +
75163 + /* look for the first block that contains the minimum
75164 + base address. If the whole required size may be fit
75165 + into it, use that block, otherwise look for the next
75166 + block of size greater or equal to the required size. */
75167 + while ( p_FreeB && (min >= p_FreeB->end))
75168 + p_FreeB = p_FreeB->p_Next;
75169 +
75170 + /* If such block is found */
75171 + if ( !p_FreeB )
75172 + {
75173 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75174 + return (uint64_t)(ILLEGAL_BASE);
75175 + }
75176 +
75177 + /* if this block is large enough, use this block */
75178 + holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min;
75179 + if ((holdBase + size) <= p_FreeB->end )
75180 + {
75181 + holdEnd = holdBase + size;
75182 + }
75183 + else
75184 + {
75185 + p_FreeB = p_FreeB->p_Next;
75186 + while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) )
75187 + p_FreeB = p_FreeB->p_Next;
75188 +
75189 + /* If such block is found */
75190 + if ( !p_FreeB )
75191 + {
75192 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75193 + return (uint64_t)(ILLEGAL_BASE);
75194 + }
75195 +
75196 + holdBase = p_FreeB->base;
75197 + holdEnd = holdBase + size;
75198 + }
75199 +
75200 + /* init a new busy block */
75201 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75202 + {
75203 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75204 + return (uint64_t)(ILLEGAL_BASE);
75205 + }
75206 +
75207 + /* calls Update routine to update a lists of free blocks */
75208 + if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK )
75209 + {
75210 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75211 + XX_Free(p_NewBusyB);
75212 + return (uint64_t)(ILLEGAL_BASE);
75213 + }
75214 +
75215 + /* Decreasing the allocated memory size from free memory size */
75216 + p_MM->freeMemSize -= size;
75217 +
75218 + /* insert the new busy block into the list of busy blocks */
75219 + AddBusy( p_MM, p_NewBusyB );
75220 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75221 +
75222 + return (holdBase);
75223 +}
75224 +
75225 +/*****************************************************************************/
75226 +uint64_t MM_Put(t_Handle h_MM, uint64_t base)
75227 +{
75228 + t_MM *p_MM = (t_MM *)h_MM;
75229 + t_BusyBlock *p_BusyB, *p_PrevBusyB;
75230 + uint64_t size;
75231 + uint32_t intFlags;
75232 +
75233 + ASSERT_COND(p_MM);
75234 +
75235 + /* Look for a busy block that have the given base value.
75236 + * That block will be returned back to the memory.
75237 + */
75238 + p_PrevBusyB = 0;
75239 +
75240 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75241 + p_BusyB = p_MM->busyBlocks;
75242 + while ( p_BusyB && base != p_BusyB->base )
75243 + {
75244 + p_PrevBusyB = p_BusyB;
75245 + p_BusyB = p_BusyB->p_Next;
75246 + }
75247 +
75248 + if ( !p_BusyB )
75249 + {
75250 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75251 + return (uint64_t)(0);
75252 + }
75253 +
75254 + if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK )
75255 + {
75256 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75257 + return (uint64_t)(0);
75258 + }
75259 +
75260 + /* removes a busy block form the list of busy blocks */
75261 + if ( p_PrevBusyB )
75262 + p_PrevBusyB->p_Next = p_BusyB->p_Next;
75263 + else
75264 + p_MM->busyBlocks = p_BusyB->p_Next;
75265 +
75266 + size = p_BusyB->end - p_BusyB->base;
75267 +
75268 + /* Adding the deallocated memory size to free memory size */
75269 + p_MM->freeMemSize += size;
75270 +
75271 + XX_Free(p_BusyB);
75272 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75273 +
75274 + return (size);
75275 +}
75276 +
75277 +/*****************************************************************************/
75278 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size)
75279 +{
75280 + t_MM *p_MM = (t_MM *)h_MM;
75281 + uint64_t end = base + size;
75282 + uint32_t intFlags;
75283 +
75284 + ASSERT_COND(p_MM);
75285 +
75286 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75287 +
75288 + if ( CutBusy( p_MM, base, end ) != E_OK )
75289 + {
75290 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75291 + return (uint64_t)(0);
75292 + }
75293 +
75294 + if ( AddFree ( p_MM, base, end ) != E_OK )
75295 + {
75296 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75297 + return (uint64_t)(0);
75298 + }
75299 +
75300 + /* Adding the deallocated memory size to free memory size */
75301 + p_MM->freeMemSize += size;
75302 +
75303 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75304 +
75305 + return (size);
75306 +}
75307 +
75308 +/*****************************************************************************/
75309 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size)
75310 +{
75311 + t_MM *p_MM = (t_MM *)h_MM;
75312 + t_MemBlock *p_MemB, *p_NewMemB;
75313 + t_Error errCode;
75314 + uint32_t intFlags;
75315 +
75316 + ASSERT_COND(p_MM);
75317 +
75318 + /* find a last block in the list of memory blocks to insert a new
75319 + * memory block
75320 + */
75321 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75322 +
75323 + p_MemB = p_MM->memBlocks;
75324 + while ( p_MemB->p_Next )
75325 + {
75326 + if ( base >= p_MemB->base && base < p_MemB->end )
75327 + {
75328 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75329 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75330 + }
75331 + p_MemB = p_MemB->p_Next;
75332 + }
75333 + /* check for a last memory block */
75334 + if ( base >= p_MemB->base && base < p_MemB->end )
75335 + {
75336 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75337 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75338 + }
75339 +
75340 + /* create a new memory block */
75341 + if ((p_NewMemB = CreateNewBlock(base, size)) == NULL)
75342 + {
75343 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75344 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75345 + }
75346 +
75347 + /* append a new memory block to the end of the list of memory blocks */
75348 + p_MemB->p_Next = p_NewMemB;
75349 +
75350 + /* add a new free block to the free lists */
75351 + errCode = AddFree(p_MM, base, base+size);
75352 + if (errCode)
75353 + {
75354 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75355 + p_MemB->p_Next = 0;
75356 + XX_Free(p_NewMemB);
75357 + return ((t_Error)errCode);
75358 + }
75359 +
75360 + /* Adding the new block size to free memory size */
75361 + p_MM->freeMemSize += size;
75362 +
75363 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75364 +
75365 + return (E_OK);
75366 +}
75367 +
75368 +/*****************************************************************************/
75369 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index)
75370 +{
75371 + t_MM *p_MM = (t_MM*)h_MM;
75372 + t_MemBlock *p_MemBlock;
75373 + int i;
75374 +
75375 + ASSERT_COND(p_MM);
75376 +
75377 + p_MemBlock = p_MM->memBlocks;
75378 + for (i=0; i < index; i++)
75379 + p_MemBlock = p_MemBlock->p_Next;
75380 +
75381 + if ( p_MemBlock )
75382 + return (p_MemBlock->base);
75383 + else
75384 + return (uint64_t)ILLEGAL_BASE;
75385 +}
75386 +
75387 +/*****************************************************************************/
75388 +uint64_t MM_GetBase(t_Handle h_MM)
75389 +{
75390 + t_MM *p_MM = (t_MM*)h_MM;
75391 + t_MemBlock *p_MemBlock;
75392 +
75393 + ASSERT_COND(p_MM);
75394 +
75395 + p_MemBlock = p_MM->memBlocks;
75396 + return p_MemBlock->base;
75397 +}
75398 +
75399 +/*****************************************************************************/
75400 +bool MM_InRange(t_Handle h_MM, uint64_t addr)
75401 +{
75402 + t_MM *p_MM = (t_MM*)h_MM;
75403 + t_MemBlock *p_MemBlock;
75404 +
75405 + ASSERT_COND(p_MM);
75406 +
75407 + p_MemBlock = p_MM->memBlocks;
75408 +
75409 + if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end))
75410 + return TRUE;
75411 + else
75412 + return FALSE;
75413 +}
75414 +
75415 +/*****************************************************************************/
75416 +uint64_t MM_GetFreeMemSize(t_Handle h_MM)
75417 +{
75418 + t_MM *p_MM = (t_MM*)h_MM;
75419 +
75420 + ASSERT_COND(p_MM);
75421 +
75422 + return p_MM->freeMemSize;
75423 +}
75424 +
75425 +/*****************************************************************************/
75426 +void MM_Dump(t_Handle h_MM)
75427 +{
75428 + t_MM *p_MM = (t_MM *)h_MM;
75429 + t_FreeBlock *p_FreeB;
75430 + t_BusyBlock *p_BusyB;
75431 + int i;
75432 +
75433 + p_BusyB = p_MM->busyBlocks;
75434 + XX_Print("List of busy blocks:\n");
75435 + while (p_BusyB)
75436 + {
75437 + XX_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end );
75438 + p_BusyB = p_BusyB->p_Next;
75439 + }
75440 +
75441 + XX_Print("\nLists of free blocks according to alignment:\n");
75442 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75443 + {
75444 + XX_Print("%d alignment:\n", (0x1 << i));
75445 + p_FreeB = p_MM->freeBlocks[i];
75446 + while (p_FreeB)
75447 + {
75448 + XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end);
75449 + p_FreeB = p_FreeB->p_Next;
75450 + }
75451 + XX_Print("\n");
75452 + }
75453 +}
75454 --- /dev/null
75455 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
75456 @@ -0,0 +1,105 @@
75457 +/*
75458 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75459 + *
75460 + * Redistribution and use in source and binary forms, with or without
75461 + * modification, are permitted provided that the following conditions are met:
75462 + * * Redistributions of source code must retain the above copyright
75463 + * notice, this list of conditions and the following disclaimer.
75464 + * * Redistributions in binary form must reproduce the above copyright
75465 + * notice, this list of conditions and the following disclaimer in the
75466 + * documentation and/or other materials provided with the distribution.
75467 + * * Neither the name of Freescale Semiconductor nor the
75468 + * names of its contributors may be used to endorse or promote products
75469 + * derived from this software without specific prior written permission.
75470 + *
75471 + *
75472 + * ALTERNATIVELY, this software may be distributed under the terms of the
75473 + * GNU General Public License ("GPL") as published by the Free Software
75474 + * Foundation, either version 2 of that License or (at your option) any
75475 + * later version.
75476 + *
75477 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75478 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75479 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75480 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75481 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75482 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75483 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75484 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75485 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75486 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75487 + */
75488 +
75489 +
75490 +/****************************************************************
75491 + *
75492 + * File: mm.h
75493 + *
75494 + *
75495 + * Description:
75496 + * MM (Memory Management) object definitions.
75497 + * It also includes definitions of the Free Block, Busy Block
75498 + * and Memory Block structures used by the MM object.
75499 + *
75500 + ****************************************************************/
75501 +
75502 +#ifndef __MM_H
75503 +#define __MM_H
75504 +
75505 +
75506 +#include "mm_ext.h"
75507 +
75508 +#define __ERR_MODULE__ MODULE_MM
75509 +
75510 +
75511 +#define MAKE_ALIGNED(addr, align) \
75512 + (((uint64_t)(addr) + ((align) - 1)) & (~(((uint64_t)align) - 1)))
75513 +
75514 +
75515 +/* t_MemBlock data structure defines parameters of the Memory Block */
75516 +typedef struct t_MemBlock
75517 +{
75518 + struct t_MemBlock *p_Next; /* Pointer to the next memory block */
75519 +
75520 + uint64_t base; /* Base address of the memory block */
75521 + uint64_t end; /* End address of the memory block */
75522 +} t_MemBlock;
75523 +
75524 +
75525 +/* t_FreeBlock data structure defines parameters of the Free Block */
75526 +typedef struct t_FreeBlock
75527 +{
75528 + struct t_FreeBlock *p_Next; /* Pointer to the next free block */
75529 +
75530 + uint64_t base; /* Base address of the block */
75531 + uint64_t end; /* End address of the block */
75532 +} t_FreeBlock;
75533 +
75534 +
75535 +/* t_BusyBlock data structure defines parameters of the Busy Block */
75536 +typedef struct t_BusyBlock
75537 +{
75538 + struct t_BusyBlock *p_Next; /* Pointer to the next free block */
75539 +
75540 + uint64_t base; /* Base address of the block */
75541 + uint64_t end; /* End address of the block */
75542 + char name[MM_MAX_NAME_LEN]; /* That block of memory was allocated for
75543 + something specified by the Name */
75544 +} t_BusyBlock;
75545 +
75546 +
75547 +/* t_MM data structure defines parameters of the MM object */
75548 +typedef struct t_MM
75549 +{
75550 + t_Handle h_Spinlock;
75551 +
75552 + t_MemBlock *memBlocks; /* List of memory blocks (Memory list) */
75553 + t_BusyBlock *busyBlocks; /* List of busy blocks (Busy list) */
75554 + t_FreeBlock *freeBlocks[MM_MAX_ALIGNMENT + 1];
75555 + /* Alignment lists of free blocks (Free lists) */
75556 +
75557 + uint64_t freeMemSize; /* Total size of free memory (in bytes) */
75558 +} t_MM;
75559 +
75560 +
75561 +#endif /* __MM_H */
75562 --- /dev/null
75563 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
75564 @@ -0,0 +1,81 @@
75565 +/*
75566 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75567 + *
75568 + * Redistribution and use in source and binary forms, with or without
75569 + * modification, are permitted provided that the following conditions are met:
75570 + * * Redistributions of source code must retain the above copyright
75571 + * notice, this list of conditions and the following disclaimer.
75572 + * * Redistributions in binary form must reproduce the above copyright
75573 + * notice, this list of conditions and the following disclaimer in the
75574 + * documentation and/or other materials provided with the distribution.
75575 + * * Neither the name of Freescale Semiconductor nor the
75576 + * names of its contributors may be used to endorse or promote products
75577 + * derived from this software without specific prior written permission.
75578 + *
75579 + *
75580 + * ALTERNATIVELY, this software may be distributed under the terms of the
75581 + * GNU General Public License ("GPL") as published by the Free Software
75582 + * Foundation, either version 2 of that License or (at your option) any
75583 + * later version.
75584 + *
75585 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75586 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75587 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75588 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75589 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75590 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75591 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75592 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75593 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75594 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75595 + */
75596 +
75597 +
75598 +/*------------------------------------------------------*/
75599 +/* File: sprint.c */
75600 +/* */
75601 +/* Description: */
75602 +/* Debug routines (externals) */
75603 +/*------------------------------------------------------*/
75604 +#include "string_ext.h"
75605 +#include "stdlib_ext.h"
75606 +#include "stdarg_ext.h"
75607 +#include "sprint_ext.h"
75608 +#include "std_ext.h"
75609 +#include "xx_ext.h"
75610 +
75611 +
75612 +int Sprint(char * buf, const char *fmt, ...)
75613 +{
75614 + va_list args;
75615 + int i;
75616 +
75617 + va_start(args, fmt);
75618 + i=vsprintf(buf,fmt,args);
75619 + va_end(args);
75620 + return i;
75621 +}
75622 +
75623 +int Snprint(char * buf, uint32_t size, const char *fmt, ...)
75624 +{
75625 + va_list args;
75626 + int i;
75627 +
75628 + va_start(args, fmt);
75629 + i=vsnprintf(buf,size,fmt,args);
75630 + va_end(args);
75631 + return i;
75632 +}
75633 +
75634 +#ifndef NCSW_VXWORKS
75635 +int Sscan(const char * buf, const char * fmt, ...)
75636 +{
75637 + va_list args;
75638 + int i;
75639 +
75640 + va_start(args,fmt);
75641 + i = vsscanf(buf,fmt,args);
75642 + va_end(args);
75643 + return i;
75644 +}
75645 +#endif /* NCSW_VXWORKS */
75646 --- /dev/null
75647 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
75648 @@ -0,0 +1,57 @@
75649 +/*
75650 + * Copyright 2012 Freescale Semiconductor Inc.
75651 + *
75652 + * Redistribution and use in source and binary forms, with or without
75653 + * modification, are permitted provided that the following conditions are met:
75654 + * * Redistributions of source code must retain the above copyright
75655 + * notice, this list of conditions and the following disclaimer.
75656 + * * Redistributions in binary form must reproduce the above copyright
75657 + * notice, this list of conditions and the following disclaimer in the
75658 + * documentation and/or other materials provided with the distribution.
75659 + * * Neither the name of Freescale Semiconductor nor the
75660 + * names of its contributors may be used to endorse or promote products
75661 + * derived from this software without specific prior written permission.
75662 + *
75663 + *
75664 + * ALTERNATIVELY, this software may be distributed under the terms of the
75665 + * GNU General Public License ("GPL") as published by the Free Software
75666 + * Foundation, either version 2 of that License or (at your option) any
75667 + * later version.
75668 + *
75669 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75670 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75671 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75672 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75673 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75674 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75675 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75676 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75677 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75678 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75679 + */
75680 +
75681 +#ifndef __dflags_h
75682 +#define __dflags_h
75683 +
75684 +
75685 +#define NCSW_LINUX
75686 +
75687 +#define T4240
75688 +#define NCSW_PPC_CORE
75689 +
75690 +#define DEBUG_ERRORS 1
75691 +
75692 +#if defined(DEBUG)
75693 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
75694 +
75695 +#define DEBUG_XX_MALLOC
75696 +#define DEBUG_MEM_LEAKS
75697 +
75698 +#else
75699 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
75700 +#endif /* (DEBUG) */
75701 +
75702 +#define REPORT_EVENTS 1
75703 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
75704 +
75705 +#endif /* __dflags_h */
75706 --- /dev/null
75707 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
75708 @@ -0,0 +1,56 @@
75709 +/*
75710 + * Copyright 2012 Freescale Semiconductor Inc.
75711 + *
75712 + * Redistribution and use in source and binary forms, with or without
75713 + * modification, are permitted provided that the following conditions are met:
75714 + * * Redistributions of source code must retain the above copyright
75715 + * notice, this list of conditions and the following disclaimer.
75716 + * * Redistributions in binary form must reproduce the above copyright
75717 + * notice, this list of conditions and the following disclaimer in the
75718 + * documentation and/or other materials provided with the distribution.
75719 + * * Neither the name of Freescale Semiconductor nor the
75720 + * names of its contributors may be used to endorse or promote products
75721 + * derived from this software without specific prior written permission.
75722 + *
75723 + *
75724 + * ALTERNATIVELY, this software may be distributed under the terms of the
75725 + * GNU General Public License ("GPL") as published by the Free Software
75726 + * Foundation, either version 2 of that License or (at your option) any
75727 + * later version.
75728 + *
75729 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75730 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75731 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75732 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75733 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75734 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75735 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75736 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75737 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75738 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75739 + */
75740 +
75741 +#ifndef __dflags_h
75742 +#define __dflags_h
75743 +
75744 +
75745 +#define NCSW_LINUX
75746 +
75747 +#define NCSW_PPC_CORE
75748 +
75749 +#define DEBUG_ERRORS 1
75750 +
75751 +#if defined(DEBUG)
75752 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
75753 +
75754 +#define DEBUG_XX_MALLOC
75755 +#define DEBUG_MEM_LEAKS
75756 +
75757 +#else
75758 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
75759 +#endif /* (DEBUG) */
75760 +
75761 +#define REPORT_EVENTS 1
75762 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
75763 +
75764 +#endif /* __dflags_h */
75765 --- /dev/null
75766 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
75767 @@ -0,0 +1,364 @@
75768 +/*
75769 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75770 + *
75771 + * Redistribution and use in source and binary forms, with or without
75772 + * modification, are permitted provided that the following conditions are met:
75773 + * * Redistributions of source code must retain the above copyright
75774 + * notice, this list of conditions and the following disclaimer.
75775 + * * Redistributions in binary form must reproduce the above copyright
75776 + * notice, this list of conditions and the following disclaimer in the
75777 + * documentation and/or other materials provided with the distribution.
75778 + * * Neither the name of Freescale Semiconductor nor the
75779 + * names of its contributors may be used to endorse or promote products
75780 + * derived from this software without specific prior written permission.
75781 + *
75782 + *
75783 + * ALTERNATIVELY, this software may be distributed under the terms of the
75784 + * GNU General Public License ("GPL") as published by the Free Software
75785 + * Foundation, either version 2 of that License or (at your option) any
75786 + * later version.
75787 + *
75788 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75789 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75790 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75791 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75792 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75793 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75794 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75795 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75796 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75797 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75798 + */
75799 +
75800 +
75801 +/*------------------------------------------------------*/
75802 +/* */
75803 +/* File: crc_mac_addr_ext.h */
75804 +/* */
75805 +/* Description: */
75806 +/* Define a macro that calculate the crc value of */
75807 +/* an Ethernet MAC address (48 bitd address */
75808 +/*------------------------------------------------------*/
75809 +
75810 +#ifndef __crc_mac_addr_ext_h
75811 +#define __crc_mac_addr_ext_h
75812 +
75813 +#include "std_ext.h"
75814 +
75815 +
75816 +static uint32_t crc_table[256] =
75817 +{
75818 + 0x00000000,
75819 + 0x77073096,
75820 + 0xee0e612c,
75821 + 0x990951ba,
75822 + 0x076dc419,
75823 + 0x706af48f,
75824 + 0xe963a535,
75825 + 0x9e6495a3,
75826 + 0x0edb8832,
75827 + 0x79dcb8a4,
75828 + 0xe0d5e91e,
75829 + 0x97d2d988,
75830 + 0x09b64c2b,
75831 + 0x7eb17cbd,
75832 + 0xe7b82d07,
75833 + 0x90bf1d91,
75834 + 0x1db71064,
75835 + 0x6ab020f2,
75836 + 0xf3b97148,
75837 + 0x84be41de,
75838 + 0x1adad47d,
75839 + 0x6ddde4eb,
75840 + 0xf4d4b551,
75841 + 0x83d385c7,
75842 + 0x136c9856,
75843 + 0x646ba8c0,
75844 + 0xfd62f97a,
75845 + 0x8a65c9ec,
75846 + 0x14015c4f,
75847 + 0x63066cd9,
75848 + 0xfa0f3d63,
75849 + 0x8d080df5,
75850 + 0x3b6e20c8,
75851 + 0x4c69105e,
75852 + 0xd56041e4,
75853 + 0xa2677172,
75854 + 0x3c03e4d1,
75855 + 0x4b04d447,
75856 + 0xd20d85fd,
75857 + 0xa50ab56b,
75858 + 0x35b5a8fa,
75859 + 0x42b2986c,
75860 + 0xdbbbc9d6,
75861 + 0xacbcf940,
75862 + 0x32d86ce3,
75863 + 0x45df5c75,
75864 + 0xdcd60dcf,
75865 + 0xabd13d59,
75866 + 0x26d930ac,
75867 + 0x51de003a,
75868 + 0xc8d75180,
75869 + 0xbfd06116,
75870 + 0x21b4f4b5,
75871 + 0x56b3c423,
75872 + 0xcfba9599,
75873 + 0xb8bda50f,
75874 + 0x2802b89e,
75875 + 0x5f058808,
75876 + 0xc60cd9b2,
75877 + 0xb10be924,
75878 + 0x2f6f7c87,
75879 + 0x58684c11,
75880 + 0xc1611dab,
75881 + 0xb6662d3d,
75882 + 0x76dc4190,
75883 + 0x01db7106,
75884 + 0x98d220bc,
75885 + 0xefd5102a,
75886 + 0x71b18589,
75887 + 0x06b6b51f,
75888 + 0x9fbfe4a5,
75889 + 0xe8b8d433,
75890 + 0x7807c9a2,
75891 + 0x0f00f934,
75892 + 0x9609a88e,
75893 + 0xe10e9818,
75894 + 0x7f6a0dbb,
75895 + 0x086d3d2d,
75896 + 0x91646c97,
75897 + 0xe6635c01,
75898 + 0x6b6b51f4,
75899 + 0x1c6c6162,
75900 + 0x856530d8,
75901 + 0xf262004e,
75902 + 0x6c0695ed,
75903 + 0x1b01a57b,
75904 + 0x8208f4c1,
75905 + 0xf50fc457,
75906 + 0x65b0d9c6,
75907 + 0x12b7e950,
75908 + 0x8bbeb8ea,
75909 + 0xfcb9887c,
75910 + 0x62dd1ddf,
75911 + 0x15da2d49,
75912 + 0x8cd37cf3,
75913 + 0xfbd44c65,
75914 + 0x4db26158,
75915 + 0x3ab551ce,
75916 + 0xa3bc0074,
75917 + 0xd4bb30e2,
75918 + 0x4adfa541,
75919 + 0x3dd895d7,
75920 + 0xa4d1c46d,
75921 + 0xd3d6f4fb,
75922 + 0x4369e96a,
75923 + 0x346ed9fc,
75924 + 0xad678846,
75925 + 0xda60b8d0,
75926 + 0x44042d73,
75927 + 0x33031de5,
75928 + 0xaa0a4c5f,
75929 + 0xdd0d7cc9,
75930 + 0x5005713c,
75931 + 0x270241aa,
75932 + 0xbe0b1010,
75933 + 0xc90c2086,
75934 + 0x5768b525,
75935 + 0x206f85b3,
75936 + 0xb966d409,
75937 + 0xce61e49f,
75938 + 0x5edef90e,
75939 + 0x29d9c998,
75940 + 0xb0d09822,
75941 + 0xc7d7a8b4,
75942 + 0x59b33d17,
75943 + 0x2eb40d81,
75944 + 0xb7bd5c3b,
75945 + 0xc0ba6cad,
75946 + 0xedb88320,
75947 + 0x9abfb3b6,
75948 + 0x03b6e20c,
75949 + 0x74b1d29a,
75950 + 0xead54739,
75951 + 0x9dd277af,
75952 + 0x04db2615,
75953 + 0x73dc1683,
75954 + 0xe3630b12,
75955 + 0x94643b84,
75956 + 0x0d6d6a3e,
75957 + 0x7a6a5aa8,
75958 + 0xe40ecf0b,
75959 + 0x9309ff9d,
75960 + 0x0a00ae27,
75961 + 0x7d079eb1,
75962 + 0xf00f9344,
75963 + 0x8708a3d2,
75964 + 0x1e01f268,
75965 + 0x6906c2fe,
75966 + 0xf762575d,
75967 + 0x806567cb,
75968 + 0x196c3671,
75969 + 0x6e6b06e7,
75970 + 0xfed41b76,
75971 + 0x89d32be0,
75972 + 0x10da7a5a,
75973 + 0x67dd4acc,
75974 + 0xf9b9df6f,
75975 + 0x8ebeeff9,
75976 + 0x17b7be43,
75977 + 0x60b08ed5,
75978 + 0xd6d6a3e8,
75979 + 0xa1d1937e,
75980 + 0x38d8c2c4,
75981 + 0x4fdff252,
75982 + 0xd1bb67f1,
75983 + 0xa6bc5767,
75984 + 0x3fb506dd,
75985 + 0x48b2364b,
75986 + 0xd80d2bda,
75987 + 0xaf0a1b4c,
75988 + 0x36034af6,
75989 + 0x41047a60,
75990 + 0xdf60efc3,
75991 + 0xa867df55,
75992 + 0x316e8eef,
75993 + 0x4669be79,
75994 + 0xcb61b38c,
75995 + 0xbc66831a,
75996 + 0x256fd2a0,
75997 + 0x5268e236,
75998 + 0xcc0c7795,
75999 + 0xbb0b4703,
76000 + 0x220216b9,
76001 + 0x5505262f,
76002 + 0xc5ba3bbe,
76003 + 0xb2bd0b28,
76004 + 0x2bb45a92,
76005 + 0x5cb36a04,
76006 + 0xc2d7ffa7,
76007 + 0xb5d0cf31,
76008 + 0x2cd99e8b,
76009 + 0x5bdeae1d,
76010 + 0x9b64c2b0,
76011 + 0xec63f226,
76012 + 0x756aa39c,
76013 + 0x026d930a,
76014 + 0x9c0906a9,
76015 + 0xeb0e363f,
76016 + 0x72076785,
76017 + 0x05005713,
76018 + 0x95bf4a82,
76019 + 0xe2b87a14,
76020 + 0x7bb12bae,
76021 + 0x0cb61b38,
76022 + 0x92d28e9b,
76023 + 0xe5d5be0d,
76024 + 0x7cdcefb7,
76025 + 0x0bdbdf21,
76026 + 0x86d3d2d4,
76027 + 0xf1d4e242,
76028 + 0x68ddb3f8,
76029 + 0x1fda836e,
76030 + 0x81be16cd,
76031 + 0xf6b9265b,
76032 + 0x6fb077e1,
76033 + 0x18b74777,
76034 + 0x88085ae6,
76035 + 0xff0f6a70,
76036 + 0x66063bca,
76037 + 0x11010b5c,
76038 + 0x8f659eff,
76039 + 0xf862ae69,
76040 + 0x616bffd3,
76041 + 0x166ccf45,
76042 + 0xa00ae278,
76043 + 0xd70dd2ee,
76044 + 0x4e048354,
76045 + 0x3903b3c2,
76046 + 0xa7672661,
76047 + 0xd06016f7,
76048 + 0x4969474d,
76049 + 0x3e6e77db,
76050 + 0xaed16a4a,
76051 + 0xd9d65adc,
76052 + 0x40df0b66,
76053 + 0x37d83bf0,
76054 + 0xa9bcae53,
76055 + 0xdebb9ec5,
76056 + 0x47b2cf7f,
76057 + 0x30b5ffe9,
76058 + 0xbdbdf21c,
76059 + 0xcabac28a,
76060 + 0x53b39330,
76061 + 0x24b4a3a6,
76062 + 0xbad03605,
76063 + 0xcdd70693,
76064 + 0x54de5729,
76065 + 0x23d967bf,
76066 + 0xb3667a2e,
76067 + 0xc4614ab8,
76068 + 0x5d681b02,
76069 + 0x2a6f2b94,
76070 + 0xb40bbe37,
76071 + 0xc30c8ea1,
76072 + 0x5a05df1b,
76073 + 0x2d02ef8d
76074 +};
76075 +
76076 +
76077 +#define GET_MAC_ADDR_CRC(addr, crc) \
76078 +{ \
76079 + uint32_t i; \
76080 + uint8_t data; \
76081 + \
76082 + /* CRC calculation */ \
76083 + crc = 0xffffffff; \
76084 + for (i=0; i < 6; i++) \
76085 + { \
76086 + data = (uint8_t)(addr >> ((5-i)*8)); \
76087 + crc = crc^data; \
76088 + crc = crc_table[crc&0xff] ^ (crc>>8); \
76089 + } \
76090 +} \
76091 +
76092 +/* Define a macro for getting the mirrored value of */
76093 +/* a byte size number. (0x11010011 --> 0x11001011) */
76094 +/* Sometimes the mirrored value of the CRC is required */
76095 +static __inline__ uint8_t GetMirror(uint8_t n)
76096 +{
76097 + uint8_t mirror[16] =
76098 + {
76099 + 0x00,
76100 + 0x08,
76101 + 0x04,
76102 + 0x0c,
76103 + 0x02,
76104 + 0x0a,
76105 + 0x06,
76106 + 0x0e,
76107 + 0x01,
76108 + 0x09,
76109 + 0x05,
76110 + 0x0d,
76111 + 0x03,
76112 + 0x0b,
76113 + 0x07,
76114 + 0x0f
76115 + };
76116 + return ((uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4]))));
76117 +}
76118 +
76119 +static __inline__ uint32_t GetMirror32(uint32_t n)
76120 +{
76121 + return (((uint32_t)GetMirror((uint8_t)(n))<<24) |
76122 + ((uint32_t)GetMirror((uint8_t)(n>>8))<<16) |
76123 + ((uint32_t)GetMirror((uint8_t)(n>>16))<<8) |
76124 + ((uint32_t)GetMirror((uint8_t)(n>>24))));
76125 +}
76126 +
76127 +#define MIRROR GetMirror
76128 +#define MIRROR_32 GetMirror32
76129 +
76130 +
76131 +#endif /* __crc_mac_addr_ext_h */
76132 --- /dev/null
76133 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
76134 @@ -0,0 +1,210 @@
76135 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76136 + * All rights reserved.
76137 + *
76138 + * Redistribution and use in source and binary forms, with or without
76139 + * modification, are permitted provided that the following conditions are met:
76140 + * * Redistributions of source code must retain the above copyright
76141 + * notice, this list of conditions and the following disclaimer.
76142 + * * Redistributions in binary form must reproduce the above copyright
76143 + * notice, this list of conditions and the following disclaimer in the
76144 + * documentation and/or other materials provided with the distribution.
76145 + * * Neither the name of Freescale Semiconductor nor the
76146 + * names of its contributors may be used to endorse or promote products
76147 + * derived from this software without specific prior written permission.
76148 + *
76149 + *
76150 + * ALTERNATIVELY, this software may be distributed under the terms of the
76151 + * GNU General Public License ("GPL") as published by the Free Software
76152 + * Foundation, either version 2 of that License or (at your option) any
76153 + * later version.
76154 + *
76155 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76156 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76157 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76158 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76159 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76160 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76161 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76162 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76163 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76164 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76165 + */
76166 +
76167 +
76168 +/**************************************************************************//**
76169 + @File dpaa_ext.h
76170 +
76171 + @Description DPAA Application Programming Interface.
76172 +*//***************************************************************************/
76173 +#ifndef __DPAA_EXT_H
76174 +#define __DPAA_EXT_H
76175 +
76176 +#include "std_ext.h"
76177 +#include "error_ext.h"
76178 +
76179 +
76180 +/**************************************************************************//**
76181 + @Group DPAA_grp Data Path Acceleration Architecture API
76182 +
76183 + @Description DPAA API functions, definitions and enums.
76184 +
76185 + @{
76186 +*//***************************************************************************/
76187 +
76188 +#if defined(__MWERKS__) && !defined(__GNUC__)
76189 +#pragma pack(push,1)
76190 +#endif /* defined(__MWERKS__) && ... */
76191 +
76192 +/**************************************************************************//**
76193 + @Description Frame descriptor
76194 +*//***************************************************************************/
76195 +typedef _Packed struct t_DpaaFD {
76196 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
76197 + volatile uint8_t liodn;
76198 + volatile uint8_t bpid;
76199 + volatile uint8_t elion;
76200 + volatile uint8_t addrh;
76201 + volatile uint32_t addrl;
76202 +#else
76203 + volatile uint32_t addrl;
76204 + volatile uint8_t addrh;
76205 + volatile uint8_t elion;
76206 + volatile uint8_t bpid;
76207 + volatile uint8_t liodn;
76208 + #endif
76209 + volatile uint32_t length; /**< Frame length */
76210 + volatile uint32_t status; /**< FD status */
76211 +} _PackedType t_DpaaFD;
76212 +
76213 +/**************************************************************************//**
76214 + @Description enum for defining frame format
76215 +*//***************************************************************************/
76216 +typedef enum e_DpaaFDFormatType {
76217 + e_DPAA_FD_FORMAT_TYPE_SHORT_SBSF = 0x0, /**< Simple frame Single buffer; Offset and
76218 + small length (9b OFFSET, 20b LENGTH) */
76219 + e_DPAA_FD_FORMAT_TYPE_LONG_SBSF = 0x2, /**< Simple frame, single buffer; big length
76220 + (29b LENGTH ,No OFFSET) */
76221 + e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF = 0x4, /**< Simple frame, Scatter Gather table; Offset
76222 + and small length (9b OFFSET, 20b LENGTH) */
76223 + e_DPAA_FD_FORMAT_TYPE_LONG_MBSF = 0x6, /**< Simple frame, Scatter Gather table;
76224 + big length (29b LENGTH ,No OFFSET) */
76225 + e_DPAA_FD_FORMAT_TYPE_COMPOUND = 0x1, /**< Compound Frame (29b CONGESTION-WEIGHT
76226 + No LENGTH or OFFSET) */
76227 + e_DPAA_FD_FORMAT_TYPE_DUMMY
76228 +} e_DpaaFDFormatType;
76229 +
76230 +/**************************************************************************//**
76231 + @Collection Frame descriptor macros
76232 +*//***************************************************************************/
76233 +#define DPAA_FD_DD_MASK 0xc0000000 /**< FD DD field mask */
76234 +#define DPAA_FD_PID_MASK 0x3f000000 /**< FD PID field mask */
76235 +#define DPAA_FD_ELIODN_MASK 0x0000f000 /**< FD ELIODN field mask */
76236 +#define DPAA_FD_BPID_MASK 0x00ff0000 /**< FD BPID field mask */
76237 +#define DPAA_FD_ADDRH_MASK 0x000000ff /**< FD ADDRH field mask */
76238 +#define DPAA_FD_ADDRL_MASK 0xffffffff /**< FD ADDRL field mask */
76239 +#define DPAA_FD_FORMAT_MASK 0xe0000000 /**< FD FORMAT field mask */
76240 +#define DPAA_FD_OFFSET_MASK 0x1ff00000 /**< FD OFFSET field mask */
76241 +#define DPAA_FD_LENGTH_MASK 0x000fffff /**< FD LENGTH field mask */
76242 +
76243 +#define DPAA_FD_GET_ADDRH(fd) ((t_DpaaFD *)fd)->addrh /**< Macro to get FD ADDRH field */
76244 +#define DPAA_FD_GET_ADDRL(fd) ((t_DpaaFD *)fd)->addrl /**< Macro to get FD ADDRL field */
76245 +#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 */
76246 +#define DPAA_FD_GET_FORMAT(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_FORMAT_MASK) >> (31-2)) /**< Macro to get FD FORMAT field */
76247 +#define DPAA_FD_GET_OFFSET(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_OFFSET_MASK) >> (31-11)) /**< Macro to get FD OFFSET field */
76248 +#define DPAA_FD_GET_LENGTH(fd) (((t_DpaaFD *)fd)->length & DPAA_FD_LENGTH_MASK) /**< Macro to get FD LENGTH field */
76249 +#define DPAA_FD_GET_STATUS(fd) ((t_DpaaFD *)fd)->status /**< Macro to get FD STATUS field */
76250 +#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd)) /**< Macro to get FD ADDR (virtual) */
76251 +
76252 +#define DPAA_FD_SET_ADDRH(fd,val) ((t_DpaaFD *)fd)->addrh = (val) /**< Macro to set FD ADDRH field */
76253 +#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */
76254 +#define DPAA_FD_SET_ADDR(fd,val) \
76255 +do { \
76256 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76257 + DPAA_FD_SET_ADDRH(fd, ((uint32_t)(physAddr >> 32))); \
76258 + DPAA_FD_SET_ADDRL(fd, (uint32_t)physAddr); \
76259 +} while (0) /**< Macro to set FD ADDR field */
76260 +#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 */
76261 +#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 */
76262 +#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 */
76263 +#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */
76264 +/* @} */
76265 +
76266 +/**************************************************************************//**
76267 + @Description Frame Scatter/Gather Table Entry
76268 +*//***************************************************************************/
76269 +typedef _Packed struct t_DpaaSGTE {
76270 + volatile uint32_t addrh; /**< Buffer Address high */
76271 + volatile uint32_t addrl; /**< Buffer Address low */
76272 + volatile uint32_t length; /**< Buffer length */
76273 + volatile uint32_t offset; /**< SGTE offset */
76274 +} _PackedType t_DpaaSGTE;
76275 +
76276 +#define DPAA_NUM_OF_SG_TABLE_ENTRY 16
76277 +
76278 +/**************************************************************************//**
76279 + @Description Frame Scatter/Gather Table
76280 +*//***************************************************************************/
76281 +typedef _Packed struct t_DpaaSGT {
76282 + t_DpaaSGTE tableEntry[DPAA_NUM_OF_SG_TABLE_ENTRY];
76283 + /**< Structure that holds information about
76284 + a single S/G entry. */
76285 +} _PackedType t_DpaaSGT;
76286 +
76287 +/**************************************************************************//**
76288 + @Description Compound Frame Table
76289 +*//***************************************************************************/
76290 +typedef _Packed struct t_DpaaCompTbl {
76291 + t_DpaaSGTE outputBuffInfo; /**< Structure that holds information about
76292 + the compound-frame output buffer;
76293 + NOTE: this may point to a S/G table */
76294 + t_DpaaSGTE inputBuffInfo; /**< Structure that holds information about
76295 + the compound-frame input buffer;
76296 + NOTE: this may point to a S/G table */
76297 +} _PackedType t_DpaaCompTbl;
76298 +
76299 +/**************************************************************************//**
76300 + @Collection Frame Scatter/Gather Table Entry macros
76301 +*//***************************************************************************/
76302 +#define DPAA_SGTE_ADDRH_MASK 0x000000ff /**< SGTE ADDRH field mask */
76303 +#define DPAA_SGTE_ADDRL_MASK 0xffffffff /**< SGTE ADDRL field mask */
76304 +#define DPAA_SGTE_E_MASK 0x80000000 /**< SGTE Extension field mask */
76305 +#define DPAA_SGTE_F_MASK 0x40000000 /**< SGTE Final field mask */
76306 +#define DPAA_SGTE_LENGTH_MASK 0x3fffffff /**< SGTE LENGTH field mask */
76307 +#define DPAA_SGTE_BPID_MASK 0x00ff0000 /**< SGTE BPID field mask */
76308 +#define DPAA_SGTE_OFFSET_MASK 0x00001fff /**< SGTE OFFSET field mask */
76309 +
76310 +#define DPAA_SGTE_GET_ADDRH(sgte) (((t_DpaaSGTE *)sgte)->addrh & DPAA_SGTE_ADDRH_MASK) /**< Macro to get SGTE ADDRH field */
76311 +#define DPAA_SGTE_GET_ADDRL(sgte) ((t_DpaaSGTE *)sgte)->addrl /**< Macro to get SGTE ADDRL field */
76312 +#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 */
76313 +#define DPAA_SGTE_GET_EXTENSION(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_E_MASK) >> (31-0)) /**< Macro to get SGTE EXTENSION field */
76314 +#define DPAA_SGTE_GET_FINAL(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_F_MASK) >> (31-1)) /**< Macro to get SGTE FINAL field */
76315 +#define DPAA_SGTE_GET_LENGTH(sgte) (((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_LENGTH_MASK) /**< Macro to get SGTE LENGTH field */
76316 +#define DPAA_SGTE_GET_BPID(sgte) ((((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_BPID_MASK) >> (31-15)) /**< Macro to get SGTE BPID field */
76317 +#define DPAA_SGTE_GET_OFFSET(sgte) (((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_OFFSET_MASK) /**< Macro to get SGTE OFFSET field */
76318 +#define DPAA_SGTE_GET_ADDR(sgte) XX_PhysToVirt(DPAA_SGTE_GET_PHYS_ADDR(sgte))
76319 +
76320 +#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 */
76321 +#define DPAA_SGTE_SET_ADDRL(sgte,val) ((t_DpaaSGTE *)sgte)->addrl = (val) /**< Macro to set SGTE ADDRL field */
76322 +#define DPAA_SGTE_SET_ADDR(sgte,val) \
76323 +do { \
76324 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76325 + DPAA_SGTE_SET_ADDRH(sgte, ((uint32_t)(physAddr >> 32))); \
76326 + DPAA_SGTE_SET_ADDRL(sgte, (uint32_t)physAddr); \
76327 +} while (0) /**< Macro to set SGTE ADDR field */
76328 +#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 */
76329 +#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 */
76330 +#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 */
76331 +#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 */
76332 +#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 */
76333 +/* @} */
76334 +
76335 +#if defined(__MWERKS__) && !defined(__GNUC__)
76336 +#pragma pack(pop)
76337 +#endif /* defined(__MWERKS__) && ... */
76338 +
76339 +#define DPAA_LIODN_DONT_OVERRIDE (-1)
76340 +
76341 +/** @} */ /* end of DPAA_grp group */
76342 +
76343 +
76344 +#endif /* __DPAA_EXT_H */
76345 --- /dev/null
76346 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
76347 @@ -0,0 +1,1731 @@
76348 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76349 + * All rights reserved.
76350 + *
76351 + * Redistribution and use in source and binary forms, with or without
76352 + * modification, are permitted provided that the following conditions are met:
76353 + * * Redistributions of source code must retain the above copyright
76354 + * notice, this list of conditions and the following disclaimer.
76355 + * * Redistributions in binary form must reproduce the above copyright
76356 + * notice, this list of conditions and the following disclaimer in the
76357 + * documentation and/or other materials provided with the distribution.
76358 + * * Neither the name of Freescale Semiconductor nor the
76359 + * names of its contributors may be used to endorse or promote products
76360 + * derived from this software without specific prior written permission.
76361 + *
76362 + *
76363 + * ALTERNATIVELY, this software may be distributed under the terms of the
76364 + * GNU General Public License ("GPL") as published by the Free Software
76365 + * Foundation, either version 2 of that License or (at your option) any
76366 + * later version.
76367 + *
76368 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76369 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76370 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76371 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76372 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76373 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76374 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76375 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76376 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76377 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76378 + */
76379 +
76380 +
76381 +/**************************************************************************//**
76382 + @File fm_ext.h
76383 +
76384 + @Description FM Application Programming Interface.
76385 +*//***************************************************************************/
76386 +#ifndef __FM_EXT
76387 +#define __FM_EXT
76388 +
76389 +#include "error_ext.h"
76390 +#include "std_ext.h"
76391 +#include "dpaa_ext.h"
76392 +#include "fsl_fman_sp.h"
76393 +
76394 +/**************************************************************************//**
76395 + @Group FM_grp Frame Manager API
76396 +
76397 + @Description FM API functions, definitions and enums.
76398 +
76399 + @{
76400 +*//***************************************************************************/
76401 +
76402 +/**************************************************************************//**
76403 + @Group FM_lib_grp FM library
76404 +
76405 + @Description FM API functions, definitions and enums.
76406 +
76407 + The FM module is the main driver module and is a mandatory module
76408 + for FM driver users. This module must be initialized first prior
76409 + to any other drivers modules.
76410 + The FM is a "singleton" module. It is responsible of the common
76411 + HW modules: FPM, DMA, common QMI and common BMI initializations and
76412 + run-time control routines. This module must be initialized always
76413 + when working with any of the FM modules.
76414 + NOTE - We assume that the FM library will be initialized only by core No. 0!
76415 +
76416 + @{
76417 +*//***************************************************************************/
76418 +
76419 +/**************************************************************************//**
76420 + @Description Enum for defining port types
76421 +*//***************************************************************************/
76422 +typedef enum e_FmPortType {
76423 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
76424 + e_FM_PORT_TYPE_RX, /**< 1G Rx port */
76425 + e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
76426 + e_FM_PORT_TYPE_TX, /**< 1G Tx port */
76427 + e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
76428 + e_FM_PORT_TYPE_DUMMY
76429 +} e_FmPortType;
76430 +
76431 +/**************************************************************************//**
76432 + @Collection General FM defines
76433 +*//***************************************************************************/
76434 +#define FM_MAX_NUM_OF_PARTITIONS 64 /**< Maximum number of partitions */
76435 +#define FM_PHYS_ADDRESS_SIZE 6 /**< FM Physical address size */
76436 +/* @} */
76437 +
76438 +
76439 +#if defined(__MWERKS__) && !defined(__GNUC__)
76440 +#pragma pack(push,1)
76441 +#endif /* defined(__MWERKS__) && ... */
76442 +
76443 +/**************************************************************************//**
76444 + @Description FM physical Address
76445 +*//***************************************************************************/
76446 +typedef _Packed struct t_FmPhysAddr {
76447 + volatile uint8_t high; /**< High part of the physical address */
76448 + volatile uint32_t low; /**< Low part of the physical address */
76449 +} _PackedType t_FmPhysAddr;
76450 +
76451 +/**************************************************************************//**
76452 + @Description Parse results memory layout
76453 +*//***************************************************************************/
76454 +typedef _Packed struct t_FmPrsResult {
76455 + volatile uint8_t lpid; /**< Logical port id */
76456 + volatile uint8_t shimr; /**< Shim header result */
76457 + volatile uint16_t l2r; /**< Layer 2 result */
76458 + volatile uint16_t l3r; /**< Layer 3 result */
76459 + volatile uint8_t l4r; /**< Layer 4 result */
76460 + volatile uint8_t cplan; /**< Classification plan id */
76461 + volatile uint16_t nxthdr; /**< Next Header */
76462 + volatile uint16_t cksum; /**< Running-sum */
76463 + volatile uint16_t flags_frag_off; /**< Flags & fragment-offset field of the last IP-header */
76464 + volatile uint8_t route_type; /**< Routing type field of a IPv6 routing extension header */
76465 + volatile uint8_t rhp_ip_valid; /**< Routing Extension Header Present; last bit is IP valid */
76466 + volatile uint8_t shim_off[2]; /**< Shim offset */
76467 + volatile uint8_t ip_pid_off; /**< IP PID (last IP-proto) offset */
76468 + volatile uint8_t eth_off; /**< ETH offset */
76469 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
76470 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
76471 + volatile uint8_t etype_off; /**< ETYPE offset */
76472 + volatile uint8_t pppoe_off; /**< PPP offset */
76473 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
76474 + volatile uint8_t ip_off[2]; /**< IP offset */
76475 + volatile uint8_t gre_off; /**< GRE offset */
76476 + volatile uint8_t l4_off; /**< Layer 4 offset */
76477 + volatile uint8_t nxthdr_off; /**< Parser end point */
76478 +} _PackedType t_FmPrsResult;
76479 +
76480 +/**************************************************************************//**
76481 + @Collection FM Parser results
76482 +*//***************************************************************************/
76483 +#define FM_PR_L2_VLAN_STACK 0x00000100 /**< Parse Result: VLAN stack */
76484 +#define FM_PR_L2_ETHERNET 0x00008000 /**< Parse Result: Ethernet*/
76485 +#define FM_PR_L2_VLAN 0x00004000 /**< Parse Result: VLAN */
76486 +#define FM_PR_L2_LLC_SNAP 0x00002000 /**< Parse Result: LLC_SNAP */
76487 +#define FM_PR_L2_MPLS 0x00001000 /**< Parse Result: MPLS */
76488 +#define FM_PR_L2_PPPoE 0x00000800 /**< Parse Result: PPPoE */
76489 +/* @} */
76490 +
76491 +/**************************************************************************//**
76492 + @Collection FM Frame descriptor macros
76493 +*//***************************************************************************/
76494 +#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */
76495 +#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */
76496 +#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */
76497 +#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */
76498 +#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */
76499 +#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */
76500 +
76501 +#define FM_FD_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Not for Rx-Port! Unsupported Format */
76502 +#define FM_FD_ERR_LENGTH 0x02000000 /**< Not for Rx-Port! Length Error */
76503 +#define FM_FD_ERR_DMA 0x01000000 /**< DMA Data error */
76504 +
76505 +#define FM_FD_IPR 0x00000001 /**< IPR frame (not error) */
76506 +
76507 +#define FM_FD_ERR_IPR_NCSP (0x00100000 | FM_FD_IPR) /**< IPR non-consistent-sp */
76508 +#define FM_FD_ERR_IPR (0x00200000 | FM_FD_IPR) /**< IPR error */
76509 +#define FM_FD_ERR_IPR_TO (0x00300000 | FM_FD_IPR) /**< IPR timeout */
76510 +
76511 +#ifdef FM_CAPWAP_SUPPORT
76512 +#define FM_FD_ERR_CRE 0x00200000
76513 +#define FM_FD_ERR_CHE 0x00100000
76514 +#endif /* FM_CAPWAP_SUPPORT */
76515 +
76516 +#define FM_FD_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity
76517 + error (SGMII and TBI modes), FIFO parity error. PHY
76518 + Sequence error, PHY error control character detected. */
76519 +#define FM_FD_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */
76520 +#define FM_FD_ERR_CLS_DISCARD 0x00020000 /**< classification discard */
76521 +#define FM_FD_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */
76522 +#define FM_FD_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */
76523 +#define FM_FD_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */
76524 +#define FM_FD_ERR_COLOR_RED 0x00000800 /**< Frame color is red */
76525 +#define FM_FD_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */
76526 +#define FM_FD_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */
76527 +#define FM_FD_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */
76528 +#define FM_FD_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */
76529 +#define FM_FD_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */
76530 +#define FM_FD_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */
76531 +#define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */
76532 +
76533 +#define FM_FD_TX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76534 + FM_FD_ERR_LENGTH | \
76535 + FM_FD_ERR_DMA) /**< TX Error FD bits */
76536 +
76537 +#define FM_FD_RX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76538 + FM_FD_ERR_LENGTH | \
76539 + FM_FD_ERR_DMA | \
76540 + FM_FD_ERR_IPR | \
76541 + FM_FD_ERR_IPR_TO | \
76542 + FM_FD_ERR_IPR_NCSP | \
76543 + FM_FD_ERR_PHYSICAL | \
76544 + FM_FD_ERR_SIZE | \
76545 + FM_FD_ERR_CLS_DISCARD | \
76546 + FM_FD_ERR_COLOR_RED | \
76547 + FM_FD_ERR_COLOR_YELLOW | \
76548 + FM_FD_ERR_ILL_PLCR | \
76549 + FM_FD_ERR_PLCR_FRAME_LEN | \
76550 + FM_FD_ERR_EXTRACTION | \
76551 + FM_FD_ERR_NO_SCHEME | \
76552 + FM_FD_ERR_KEYSIZE_OVERFLOW | \
76553 + FM_FD_ERR_PRS_TIMEOUT | \
76554 + FM_FD_ERR_PRS_ILL_INSTRUCT | \
76555 + FM_FD_ERR_PRS_HDR_ERR | \
76556 + FM_FD_ERR_BLOCK_LIMIT_EXCEEDED) /**< RX Error FD bits */
76557 +
76558 +#define FM_FD_RX_STATUS_ERR_NON_FM 0x00400000 /**< non Frame-Manager error */
76559 +/* @} */
76560 +
76561 +/**************************************************************************//**
76562 + @Description Context A
76563 +*//***************************************************************************/
76564 +typedef _Packed struct t_FmContextA {
76565 + volatile uint32_t command; /**< ContextA Command */
76566 + volatile uint8_t res0[4]; /**< ContextA Reserved bits */
76567 +} _PackedType t_FmContextA;
76568 +
76569 +/**************************************************************************//**
76570 + @Description Context B
76571 +*//***************************************************************************/
76572 +typedef uint32_t t_FmContextB;
76573 +
76574 +/**************************************************************************//**
76575 + @Collection Special Operation options
76576 +*//***************************************************************************/
76577 +typedef uint32_t fmSpecialOperations_t; /**< typedef for defining Special Operation options */
76578 +
76579 +#define FM_SP_OP_IPSEC 0x80000000 /**< activate features that related to IPSec (e.g fix Eth-type) */
76580 +#define FM_SP_OP_IPSEC_UPDATE_UDP_LEN 0x40000000 /**< update the UDP-Len after Encryption */
76581 +#define FM_SP_OP_IPSEC_MANIP 0x20000000 /**< handle the IPSec-manip options */
76582 +#define FM_SP_OP_RPD 0x10000000 /**< Set the RPD bit */
76583 +#define FM_SP_OP_DCL4C 0x08000000 /**< Set the DCL4C bit */
76584 +#define FM_SP_OP_CHECK_SEC_ERRORS 0x04000000 /**< Check SEC errors */
76585 +#define FM_SP_OP_CLEAR_RPD 0x02000000 /**< Clear the RPD bit */
76586 +#define FM_SP_OP_CAPWAP_DTLS_ENC 0x01000000 /**< activate features that related to CAPWAP-DTLS post Encryption */
76587 +#define FM_SP_OP_CAPWAP_DTLS_DEC 0x00800000 /**< activate features that related to CAPWAP-DTLS post Decryption */
76588 +#define FM_SP_OP_IPSEC_NO_ETH_HDR 0x00400000 /**< activate features that related to IPSec without Eth hdr */
76589 +/* @} */
76590 +
76591 +/**************************************************************************//**
76592 + @Collection Context A macros
76593 +*//***************************************************************************/
76594 +#define FM_CONTEXTA_OVERRIDE_MASK 0x80000000
76595 +#define FM_CONTEXTA_ICMD_MASK 0x40000000
76596 +#define FM_CONTEXTA_A1_VALID_MASK 0x20000000
76597 +#define FM_CONTEXTA_MACCMD_MASK 0x00ff0000
76598 +#define FM_CONTEXTA_MACCMD_VALID_MASK 0x00800000
76599 +#define FM_CONTEXTA_MACCMD_SECURED_MASK 0x00100000
76600 +#define FM_CONTEXTA_MACCMD_SC_MASK 0x000f0000
76601 +#define FM_CONTEXTA_A1_MASK 0x0000ffff
76602 +
76603 +#define FM_CONTEXTA_GET_OVERRIDE(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_OVERRIDE_MASK) >> (31-0))
76604 +#define FM_CONTEXTA_GET_ICMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_ICMD_MASK) >> (31-1))
76605 +#define FM_CONTEXTA_GET_A1_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_VALID_MASK) >> (31-2))
76606 +#define FM_CONTEXTA_GET_A1(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_MASK) >> (31-31))
76607 +#define FM_CONTEXTA_GET_MACCMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_MASK) >> (31-15))
76608 +#define FM_CONTEXTA_GET_MACCMD_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_VALID_MASK) >> (31-8))
76609 +#define FM_CONTEXTA_GET_MACCMD_SECURED(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SECURED_MASK) >> (31-11))
76610 +#define FM_CONTEXTA_GET_MACCMD_SECURE_CHANNEL(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SC_MASK) >> (31-15))
76611 +
76612 +#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) ))
76613 +#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) ))
76614 +#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) ))
76615 +#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) ))
76616 +#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) ))
76617 +#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) ))
76618 +#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) ))
76619 +#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) ))
76620 +/* @} */
76621 +
76622 +/**************************************************************************//**
76623 + @Collection Context B macros
76624 +*//***************************************************************************/
76625 +#define FM_CONTEXTB_FQID_MASK 0x00ffffff
76626 +
76627 +#define FM_CONTEXTB_GET_FQID(contextB) (*((t_FmContextB *)contextB) & FM_CONTEXTB_FQID_MASK)
76628 +#define FM_CONTEXTB_SET_FQID(contextB,val) (*((t_FmContextB *)contextB) = ((*((t_FmContextB *)contextB) & ~FM_CONTEXTB_FQID_MASK) | ((val) & FM_CONTEXTB_FQID_MASK)))
76629 +/* @} */
76630 +
76631 +#if defined(__MWERKS__) && !defined(__GNUC__)
76632 +#pragma pack(pop)
76633 +#endif /* defined(__MWERKS__) && ... */
76634 +
76635 +
76636 +/**************************************************************************//**
76637 + @Description FM Exceptions
76638 +*//***************************************************************************/
76639 +typedef enum e_FmExceptions {
76640 + e_FM_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
76641 + e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
76642 + e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
76643 + e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
76644 + e_FM_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
76645 + e_FM_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
76646 + e_FM_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
76647 + e_FM_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
76648 + e_FM_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
76649 + e_FM_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
76650 + e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
76651 + e_FM_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
76652 + e_FM_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
76653 + e_FM_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
76654 + e_FM_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
76655 + e_FM_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
76656 + e_FM_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
76657 +} e_FmExceptions;
76658 +
76659 +/**************************************************************************//**
76660 + @Description Enum for defining port DMA swap mode
76661 +*//***************************************************************************/
76662 +typedef enum e_FmDmaSwapOption {
76663 + e_FM_DMA_NO_SWP = FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
76664 + e_FM_DMA_SWP_PPC_LE = FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
76665 + in PowerPc Little Endian mode. */
76666 + e_FM_DMA_SWP_BE = FMAN_DMA_SWP_BE /**< The transferred data should be swapped
76667 + in Big Endian mode */
76668 +} e_FmDmaSwapOption;
76669 +
76670 +/**************************************************************************//**
76671 + @Description Enum for defining port DMA cache attributes
76672 +*//***************************************************************************/
76673 +typedef enum e_FmDmaCacheOption {
76674 + e_FM_DMA_NO_STASH = FMAN_DMA_NO_STASH, /**< Cacheable, no Allocate (No Stashing) */
76675 + e_FM_DMA_STASH = FMAN_DMA_STASH /**< Cacheable and Allocate (Stashing on) */
76676 +} e_FmDmaCacheOption;
76677 +
76678 +
76679 +/**************************************************************************//**
76680 + @Group FM_init_grp FM Initialization Unit
76681 +
76682 + @Description FM Initialization Unit
76683 +
76684 + Initialization Flow
76685 + Initialization of the FM Module will be carried out by the application
76686 + according to the following sequence:
76687 + - Calling the configuration routine with basic parameters.
76688 + - Calling the advance initialization routines to change driver's defaults.
76689 + - Calling the initialization routine.
76690 +
76691 + @{
76692 +*//***************************************************************************/
76693 +
76694 +/**************************************************************************//**
76695 + @Function t_FmExceptionsCallback
76696 +
76697 + @Description Exceptions user callback routine, will be called upon an
76698 + exception passing the exception identification.
76699 +
76700 + @Param[in] h_App - User's application descriptor.
76701 + @Param[in] exception - The exception.
76702 +*//***************************************************************************/
76703 +typedef void (t_FmExceptionsCallback)(t_Handle h_App,
76704 + e_FmExceptions exception);
76705 +
76706 +
76707 +/**************************************************************************//**
76708 + @Function t_FmBusErrorCallback
76709 +
76710 + @Description Bus error user callback routine, will be called upon a
76711 + bus error, passing parameters describing the errors and the owner.
76712 +
76713 + @Param[in] h_App - User's application descriptor.
76714 + @Param[in] portType - Port type (e_FmPortType)
76715 + @Param[in] portId - Port id - relative to type.
76716 + @Param[in] addr - Address that caused the error
76717 + @Param[in] tnum - Owner of error
76718 + @Param[in] liodn - Logical IO device number
76719 +*//***************************************************************************/
76720 +typedef void (t_FmBusErrorCallback) (t_Handle h_App,
76721 + e_FmPortType portType,
76722 + uint8_t portId,
76723 + uint64_t addr,
76724 + uint8_t tnum,
76725 + uint16_t liodn);
76726 +
76727 +/**************************************************************************//**
76728 + @Description A structure for defining buffer prefix area content.
76729 +*//***************************************************************************/
76730 +typedef struct t_FmBufferPrefixContent {
76731 + uint16_t privDataSize; /**< Number of bytes to be left at the beginning
76732 + of the external buffer; Note that the private-area will
76733 + start from the base of the buffer address. */
76734 + bool passPrsResult; /**< TRUE to pass the parse result to/from the FM;
76735 + User may use FM_PORT_GetBufferPrsResult() in order to
76736 + get the parser-result from a buffer. */
76737 + bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM
76738 + User may use FM_PORT_GetBufferTimeStamp() in order to
76739 + get the parser-result from a buffer. */
76740 + bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM
76741 + User may use FM_PORT_GetBufferHashResult() in order to
76742 + get the parser-result from a buffer. */
76743 + bool passAllOtherPCDInfo;/**< Add all other Internal-Context information:
76744 + AD, hash-result, key, etc. */
76745 + uint16_t dataAlign; /**< 0 to use driver's default alignment [DEFAULT_FM_SP_bufferPrefixContent_dataAlign],
76746 + other value for selecting a data alignment (must be a power of 2);
76747 + if write optimization is used, must be >= 16. */
76748 + uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size);
76749 + Note that this field impacts the size of the buffer-prefix
76750 + (i.e. it pushes the data offset);
76751 + This field is irrelevant if DPAA_VERSION==10 */
76752 +} t_FmBufferPrefixContent;
76753 +
76754 +/**************************************************************************//**
76755 + @Description A structure of information about each of the external
76756 + buffer pools used by a port or storage-profile.
76757 +*//***************************************************************************/
76758 +typedef struct t_FmExtPoolParams {
76759 + uint8_t id; /**< External buffer pool id */
76760 + uint16_t size; /**< External buffer pool buffer size */
76761 +} t_FmExtPoolParams;
76762 +
76763 +/**************************************************************************//**
76764 + @Description A structure for informing the driver about the external
76765 + buffer pools allocated in the BM and used by a port or a
76766 + storage-profile.
76767 +*//***************************************************************************/
76768 +typedef struct t_FmExtPools {
76769 + uint8_t numOfPoolsUsed; /**< Number of pools use by this port */
76770 + t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
76771 + /**< Parameters for each port */
76772 +} t_FmExtPools;
76773 +
76774 +/**************************************************************************//**
76775 + @Description A structure for defining backup BM Pools.
76776 +*//***************************************************************************/
76777 +typedef struct t_FmBackupBmPools {
76778 + uint8_t numOfBackupPools; /**< Number of BM backup pools -
76779 + must be smaller than the total number of
76780 + pools defined for the specified port.*/
76781 + uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS];
76782 + /**< numOfBackupPools pool id's, specifying which
76783 + pools should be used only as backup. Pool
76784 + id's specified here must be a subset of the
76785 + pools used by the specified port.*/
76786 +} t_FmBackupBmPools;
76787 +
76788 +/**************************************************************************//**
76789 + @Description A structure for defining BM pool depletion criteria
76790 +*//***************************************************************************/
76791 +typedef struct t_FmBufPoolDepletion {
76792 + bool poolsGrpModeEnable; /**< select mode in which pause frames will be sent after
76793 + a number of pools (all together!) are depleted */
76794 + uint8_t numOfPools; /**< the number of depleted pools that will invoke
76795 + pause frames transmission. */
76796 + bool poolsToConsider[BM_MAX_NUM_OF_POOLS];
76797 + /**< For each pool, TRUE if it should be considered for
76798 + depletion (Note - this pool must be used by this port!). */
76799 + bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after
76800 + a single-pool is depleted; */
76801 + bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS];
76802 + /**< For each pool, TRUE if it should be considered for
76803 + depletion (Note - this pool must be used by this port!) */
76804 +#if (DPAA_VERSION >= 11)
76805 + bool pfcPrioritiesEn[FM_MAX_NUM_OF_PFC_PRIORITIES];
76806 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame which is transmitted */
76807 +#endif /* (DPAA_VERSION >= 11) */
76808 +} t_FmBufPoolDepletion;
76809 +
76810 +/**************************************************************************//**
76811 + @Description A Structure for defining Ucode patch for loading.
76812 +*//***************************************************************************/
76813 +typedef struct t_FmFirmwareParams {
76814 + uint32_t size; /**< Size of uCode */
76815 + uint32_t *p_Code; /**< A pointer to the uCode */
76816 +} t_FmFirmwareParams;
76817 +
76818 +/**************************************************************************//**
76819 + @Description A Structure for defining FM initialization parameters
76820 +*//***************************************************************************/
76821 +typedef struct t_FmParams {
76822 + uint8_t fmId; /**< Index of the FM */
76823 + uint8_t guestId; /**< FM Partition Id */
76824 + uintptr_t baseAddr; /**< A pointer to base of memory mapped FM registers (virtual);
76825 + this field is optional when the FM runs in "guest-mode"
76826 + (i.e. guestId != NCSW_MASTER_ID); in that case, the driver will
76827 + use the memory-map instead of calling the IPC where possible;
76828 + NOTE that this should include ALL common registers of the FM including
76829 + the PCD registers area (i.e. until the VSP pages - 880KB). */
76830 + t_Handle h_FmMuram; /**< A handle of an initialized MURAM object,
76831 + to be used by the FM. */
76832 + uint16_t fmClkFreq; /**< In Mhz;
76833 + Relevant when FM not runs in "guest-mode". */
76834 + uint16_t fmMacClkRatio; /**< FM MAC Clock ratio, for backward comparability:
76835 + when fmMacClkRatio = 0, ratio is 2:1
76836 + when fmMacClkRatio = 1, ratio is 1:1 */
76837 + t_FmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions;
76838 + Relevant when FM not runs in "guest-mode". */
76839 + t_FmBusErrorCallback *f_BusError; /**< An application callback routine to handle exceptions;
76840 + Relevant when FM not runs in "guest-mode". */
76841 + t_Handle h_App; /**< A handle to an application layer object; This handle will
76842 + be passed by the driver upon calling the above callbacks;
76843 + Relevant when FM not runs in "guest-mode". */
76844 + int irq; /**< FM interrupt source for normal events;
76845 + Relevant when FM not runs in "guest-mode". */
76846 + int errIrq; /**< FM interrupt source for errors;
76847 + Relevant when FM not runs in "guest-mode". */
76848 + t_FmFirmwareParams firmware; /**< The firmware parameters structure;
76849 + Relevant when FM not runs in "guest-mode". */
76850 +
76851 +#if (DPAA_VERSION >= 11)
76852 + uintptr_t vspBaseAddr; /**< A pointer to base of memory mapped FM VSP registers (virtual);
76853 + i.e. up to 24KB, depending on the specific chip. */
76854 + uint8_t partVSPBase; /**< The first Virtual-Storage-Profile-id dedicated to this partition.
76855 + NOTE: this parameter relevant only when working with multiple partitions. */
76856 + uint8_t partNumOfVSPs; /**< Number of VSPs dedicated to this partition.
76857 + NOTE: this parameter relevant only when working with multiple partitions. */
76858 +#endif /* (DPAA_VERSION >= 11) */
76859 +} t_FmParams;
76860 +
76861 +
76862 +/**************************************************************************//**
76863 + @Function FM_Config
76864 +
76865 + @Description Creates the FM module and returns its handle (descriptor).
76866 + This descriptor must be passed as first parameter to all other
76867 + FM function calls.
76868 +
76869 + No actual initialization or configuration of FM hardware is
76870 + done by this routine. All FM parameters get default values that
76871 + may be changed by calling one or more of the advance config routines.
76872 +
76873 + @Param[in] p_FmParams - A pointer to a data structure of mandatory FM parameters
76874 +
76875 + @Return A handle to the FM object, or NULL for Failure.
76876 +*//***************************************************************************/
76877 +t_Handle FM_Config(t_FmParams *p_FmParams);
76878 +
76879 +/**************************************************************************//**
76880 + @Function FM_Init
76881 +
76882 + @Description Initializes the FM module by defining the software structure
76883 + and configuring the hardware registers.
76884 +
76885 + @Param[in] h_Fm - FM module descriptor
76886 +
76887 + @Return E_OK on success; Error code otherwise.
76888 +*//***************************************************************************/
76889 +t_Error FM_Init(t_Handle h_Fm);
76890 +
76891 +/**************************************************************************//**
76892 + @Function FM_Free
76893 +
76894 + @Description Frees all resources that were assigned to FM module.
76895 +
76896 + Calling this routine invalidates the descriptor.
76897 +
76898 + @Param[in] h_Fm - FM module descriptor
76899 +
76900 + @Return E_OK on success; Error code otherwise.
76901 +*//***************************************************************************/
76902 +t_Error FM_Free(t_Handle h_Fm);
76903 +
76904 +
76905 +/**************************************************************************//**
76906 + @Group FM_advanced_init_grp FM Advanced Configuration Unit
76907 +
76908 + @Description Advanced configuration routines are optional routines that may
76909 + be called in order to change the default driver settings.
76910 +
76911 + Note: Advanced configuration routines are not available for guest partition.
76912 + @{
76913 +*//***************************************************************************/
76914 +
76915 +/**************************************************************************//**
76916 + @Description Enum for selecting DMA debug mode
76917 +*//***************************************************************************/
76918 +typedef enum e_FmDmaDbgCntMode {
76919 + e_FM_DMA_DBG_NO_CNT = 0, /**< No counting */
76920 + e_FM_DMA_DBG_CNT_DONE, /**< Count DONE commands */
76921 + e_FM_DMA_DBG_CNT_COMM_Q_EM, /**< count command queue emergency signals */
76922 + e_FM_DMA_DBG_CNT_INT_READ_EM, /**< Count Internal Read buffer emergency signal */
76923 + e_FM_DMA_DBG_CNT_INT_WRITE_EM, /**< Count Internal Write buffer emergency signal */
76924 + e_FM_DMA_DBG_CNT_FPM_WAIT, /**< Count FPM WAIT signal */
76925 + e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors. */
76926 + e_FM_DMA_DBG_CNT_RAW_WAR_PROT /**< Number of times there was a need for RAW & WAR protection. */
76927 +} e_FmDmaDbgCntMode;
76928 +
76929 +/**************************************************************************//**
76930 + @Description Enum for selecting DMA Cache Override
76931 +*//***************************************************************************/
76932 +typedef enum e_FmDmaCacheOverride {
76933 + e_FM_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
76934 + e_FM_DMA_NO_STASH_DATA, /**< Data should not be stashed in system level cache */
76935 + e_FM_DMA_MAY_STASH_DATA, /**< Data may be stashed in system level cache */
76936 + e_FM_DMA_STASH_DATA /**< Data should be stashed in system level cache */
76937 +} e_FmDmaCacheOverride;
76938 +
76939 +/**************************************************************************//**
76940 + @Description Enum for selecting DMA External Bus Priority
76941 +*//***************************************************************************/
76942 +typedef enum e_FmDmaExtBusPri {
76943 + e_FM_DMA_EXT_BUS_NORMAL = 0, /**< Normal priority */
76944 + e_FM_DMA_EXT_BUS_EBS, /**< AXI extended bus service priority */
76945 + e_FM_DMA_EXT_BUS_SOS, /**< AXI sos priority */
76946 + e_FM_DMA_EXT_BUS_EBS_AND_SOS /**< AXI ebs + sos priority */
76947 +} e_FmDmaExtBusPri;
76948 +
76949 +/**************************************************************************//**
76950 + @Description Enum for choosing the field that will be output on AID
76951 +*//***************************************************************************/
76952 +typedef enum e_FmDmaAidMode {
76953 + e_FM_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
76954 + e_FM_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
76955 +} e_FmDmaAidMode;
76956 +
76957 +/**************************************************************************//**
76958 + @Description Enum for selecting FPM Catastrophic error behavior
76959 +*//***************************************************************************/
76960 +typedef enum e_FmCatastrophicErr {
76961 + e_FM_CATASTROPHIC_ERR_STALL_PORT = 0, /**< Port_ID is stalled (only reset can release it) */
76962 + e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only erroneous task is stalled */
76963 +} e_FmCatastrophicErr;
76964 +
76965 +/**************************************************************************//**
76966 + @Description Enum for selecting FPM DMA Error behavior
76967 +*//***************************************************************************/
76968 +typedef enum e_FmDmaErr {
76969 + e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic
76970 + error (e_FmCatastrophicErr)*/
76971 + e_FM_DMA_ERR_REPORT /**< Dma error is just reported */
76972 +} e_FmDmaErr;
76973 +
76974 +/**************************************************************************//**
76975 + @Description Enum for selecting DMA Emergency level by BMI emergency signal
76976 +*//***************************************************************************/
76977 +typedef enum e_FmDmaEmergencyLevel {
76978 + e_FM_DMA_EM_EBS = 0, /**< EBS emergency */
76979 + e_FM_DMA_EM_SOS /**< SOS emergency */
76980 +} e_FmDmaEmergencyLevel;
76981 +
76982 +/**************************************************************************//**
76983 + @Collection Enum for selecting DMA Emergency options
76984 +*//***************************************************************************/
76985 +typedef uint32_t fmEmergencyBus_t; /**< DMA emergency options */
76986 +
76987 +#define FM_DMA_MURAM_READ_EMERGENCY 0x00800000 /**< Enable emergency for MURAM1 */
76988 +#define FM_DMA_MURAM_WRITE_EMERGENCY 0x00400000 /**< Enable emergency for MURAM2 */
76989 +#define FM_DMA_EXT_BUS_EMERGENCY 0x00100000 /**< Enable emergency for external bus */
76990 +/* @} */
76991 +
76992 +/**************************************************************************//**
76993 + @Description A structure for defining DMA emergency level
76994 +*//***************************************************************************/
76995 +typedef struct t_FmDmaEmergency {
76996 + fmEmergencyBus_t emergencyBusSelect; /**< An OR of the busses where emergency
76997 + should be enabled */
76998 + e_FmDmaEmergencyLevel emergencyLevel; /**< EBS/SOS */
76999 +} t_FmDmaEmergency;
77000 +
77001 +/**************************************************************************//*
77002 + @Description structure for defining FM threshold
77003 +*//***************************************************************************/
77004 +typedef struct t_FmThresholds {
77005 + uint8_t dispLimit; /**< The number of times a frames may
77006 + be passed in the FM before assumed to
77007 + be looping. */
77008 + uint8_t prsDispTh; /**< This is the number pf packets that may be
77009 + queued in the parser dispatch queue*/
77010 + uint8_t plcrDispTh; /**< This is the number pf packets that may be
77011 + queued in the policer dispatch queue*/
77012 + uint8_t kgDispTh; /**< This is the number pf packets that may be
77013 + queued in the keygen dispatch queue*/
77014 + uint8_t bmiDispTh; /**< This is the number pf packets that may be
77015 + queued in the BMI dispatch queue*/
77016 + uint8_t qmiEnqDispTh; /**< This is the number pf packets that may be
77017 + queued in the QMI enqueue dispatch queue*/
77018 + uint8_t qmiDeqDispTh; /**< This is the number pf packets that may be
77019 + queued in the QMI dequeue dispatch queue*/
77020 + uint8_t fmCtl1DispTh; /**< This is the number pf packets that may be
77021 + queued in fmCtl1 dispatch queue*/
77022 + uint8_t fmCtl2DispTh; /**< This is the number pf packets that may be
77023 + queued in fmCtl2 dispatch queue*/
77024 +} t_FmThresholds;
77025 +
77026 +/**************************************************************************//*
77027 + @Description structure for defining DMA thresholds
77028 +*//***************************************************************************/
77029 +typedef struct t_FmDmaThresholds {
77030 + uint8_t assertEmergency; /**< When this value is reached,
77031 + assert emergency (Threshold)*/
77032 + uint8_t clearEmergency; /**< After emergency is asserted, it is held
77033 + until this value is reached (Hystheresis) */
77034 +} t_FmDmaThresholds;
77035 +
77036 +/**************************************************************************//**
77037 + @Function t_FmResetOnInitOverrideCallback
77038 +
77039 + @Description FMan specific reset on init user callback routine,
77040 + will be used to override the standard FMan reset on init procedure
77041 +
77042 + @Param[in] h_Fm - FMan handler
77043 +*//***************************************************************************/
77044 +typedef void (t_FmResetOnInitOverrideCallback)(t_Handle h_Fm);
77045 +
77046 +/**************************************************************************//**
77047 + @Function FM_ConfigResetOnInit
77048 +
77049 + @Description Define whether to reset the FM before initialization.
77050 + Change the default configuration [DEFAULT_resetOnInit].
77051 +
77052 + @Param[in] h_Fm A handle to an FM Module.
77053 + @Param[in] enable When TRUE, FM will be reset before any initialization.
77054 +
77055 + @Return E_OK on success; Error code otherwise.
77056 +
77057 + @Cautions Allowed only following FM_Config() and before FM_Init().
77058 + This routine should NOT be called from guest-partition
77059 + (i.e. guestId != NCSW_MASTER_ID)
77060 +*//***************************************************************************/
77061 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable);
77062 +
77063 +/**************************************************************************//**
77064 + @Function FM_ConfigResetOnInitOverrideCallback
77065 +
77066 + @Description Define a special reset of FM before initialization.
77067 + Change the default configuration [DEFAULT_resetOnInitOverrideCallback].
77068 +
77069 + @Param[in] h_Fm A handle to an FM Module.
77070 + @Param[in] f_ResetOnInitOverride FM specific reset on init user callback routine.
77071 +
77072 + @Return E_OK on success; Error code otherwise.
77073 +
77074 + @Cautions Allowed only following FM_Config() and before FM_Init().
77075 + This routine should NOT be called from guest-partition
77076 + (i.e. guestId != NCSW_MASTER_ID)
77077 +*//***************************************************************************/
77078 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride);
77079 +
77080 +/**************************************************************************//**
77081 + @Function FM_ConfigTotalFifoSize
77082 +
77083 + @Description Define Total FIFO size for the whole FM.
77084 + Calling this routine changes the total Fifo size in the internal driver
77085 + data base from its default configuration [DEFAULT_totalFifoSize]
77086 +
77087 + @Param[in] h_Fm A handle to an FM Module.
77088 + @Param[in] totalFifoSize The selected new value.
77089 +
77090 + @Return E_OK on success; Error code otherwise.
77091 +
77092 + @Cautions Allowed only following FM_Config() and before FM_Init().
77093 + This routine should NOT be called from guest-partition
77094 + (i.e. guestId != NCSW_MASTER_ID)
77095 +*//***************************************************************************/
77096 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize);
77097 +
77098 + /**************************************************************************//**
77099 + @Function FM_ConfigDmaCacheOverride
77100 +
77101 + @Description Define cache override mode.
77102 + Calling this routine changes the cache override mode
77103 + in the internal driver data base from its default configuration [DEFAULT_cacheOverride]
77104 +
77105 + @Param[in] h_Fm A handle to an FM Module.
77106 + @Param[in] cacheOverride The selected new value.
77107 +
77108 + @Return E_OK on success; Error code otherwise.
77109 +
77110 + @Cautions Allowed only following FM_Config() and before FM_Init().
77111 + This routine should NOT be called from guest-partition
77112 + (i.e. guestId != NCSW_MASTER_ID)
77113 +*//***************************************************************************/
77114 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride);
77115 +
77116 +/**************************************************************************//**
77117 + @Function FM_ConfigDmaAidOverride
77118 +
77119 + @Description Define DMA AID override mode.
77120 + Calling this routine changes the AID override mode
77121 + in the internal driver data base from its default configuration [DEFAULT_aidOverride]
77122 +
77123 + @Param[in] h_Fm A handle to an FM Module.
77124 + @Param[in] aidOverride The selected new value.
77125 +
77126 + @Return E_OK on success; Error code otherwise.
77127 +
77128 + @Cautions Allowed only following FM_Config() and before FM_Init().
77129 + This routine should NOT be called from guest-partition
77130 + (i.e. guestId != NCSW_MASTER_ID)
77131 +*//***************************************************************************/
77132 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride);
77133 +
77134 +/**************************************************************************//**
77135 + @Function FM_ConfigDmaAidMode
77136 +
77137 + @Description Define DMA AID mode.
77138 + Calling this routine changes the AID mode in the internal
77139 + driver data base from its default configuration [DEFAULT_aidMode]
77140 +
77141 + @Param[in] h_Fm A handle to an FM Module.
77142 + @Param[in] aidMode The selected new value.
77143 +
77144 + @Return E_OK on success; Error code otherwise.
77145 +
77146 + @Cautions Allowed only following FM_Config() and before FM_Init().
77147 + This routine should NOT be called from guest-partition
77148 + (i.e. guestId != NCSW_MASTER_ID)
77149 +*//***************************************************************************/
77150 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode);
77151 +
77152 +/**************************************************************************//**
77153 + @Function FM_ConfigDmaAxiDbgNumOfBeats
77154 +
77155 + @Description Define DMA AXI number of beats.
77156 + Calling this routine changes the AXI number of beats in the internal
77157 + driver data base from its default configuration [DEFAULT_axiDbgNumOfBeats]
77158 +
77159 + @Param[in] h_Fm A handle to an FM Module.
77160 + @Param[in] axiDbgNumOfBeats The selected new value.
77161 +
77162 + @Return E_OK on success; Error code otherwise.
77163 +
77164 + @Cautions Allowed only following FM_Config() and before FM_Init().
77165 + This routine should NOT be called from guest-partition
77166 + (i.e. guestId != NCSW_MASTER_ID)
77167 +*//***************************************************************************/
77168 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats);
77169 +
77170 +/**************************************************************************//**
77171 + @Function FM_ConfigDmaCamNumOfEntries
77172 +
77173 + @Description Define number of CAM entries.
77174 + Calling this routine changes the number of CAM entries in the internal
77175 + driver data base from its default configuration [DEFAULT_dmaCamNumOfEntries].
77176 +
77177 + @Param[in] h_Fm A handle to an FM Module.
77178 + @Param[in] numOfEntries The selected new value.
77179 +
77180 + @Return E_OK on success; Error code otherwise.
77181 +
77182 + @Cautions Allowed only following FM_Config() and before FM_Init().
77183 + This routine should NOT be called from guest-partition
77184 + (i.e. guestId != NCSW_MASTER_ID)
77185 +*//***************************************************************************/
77186 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries);
77187 +
77188 +/**************************************************************************//**
77189 + @Function FM_ConfigEnableCounters
77190 +
77191 + @Description Obsolete, always return E_OK.
77192 +
77193 + @Param[in] h_Fm A handle to an FM Module.
77194 +
77195 + @Return E_OK on success; Error code otherwise.
77196 +*//***************************************************************************/
77197 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm);
77198 +
77199 +/**************************************************************************//**
77200 + @Function FM_ConfigDmaDbgCounter
77201 +
77202 + @Description Define DMA debug counter.
77203 + Calling this routine changes the number of the DMA debug counter in the internal
77204 + driver data base from its default configuration [DEFAULT_dmaDbgCntMode].
77205 +
77206 + @Param[in] h_Fm A handle to an FM Module.
77207 + @Param[in] fmDmaDbgCntMode An enum selecting the debug counter mode.
77208 +
77209 + @Return E_OK on success; Error code otherwise.
77210 +
77211 + @Cautions Allowed only following FM_Config() and before FM_Init().
77212 + This routine should NOT be called from guest-partition
77213 + (i.e. guestId != NCSW_MASTER_ID)
77214 +*//***************************************************************************/
77215 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode);
77216 +
77217 +/**************************************************************************//**
77218 + @Function FM_ConfigDmaStopOnBusErr
77219 +
77220 + @Description Define bus error behavior.
77221 + Calling this routine changes the bus error behavior definition
77222 + in the internal driver data base from its default
77223 + configuration [DEFAULT_dmaStopOnBusError].
77224 +
77225 + @Param[in] h_Fm A handle to an FM Module.
77226 + @Param[in] stop TRUE to stop on bus error, FALSE to continue.
77227 +
77228 + @Return E_OK on success; Error code otherwise.
77229 +
77230 + @Cautions Allowed only following FM_Config() and before FM_Init().
77231 + Only if bus error is enabled.
77232 + This routine should NOT be called from guest-partition
77233 + (i.e. guestId != NCSW_MASTER_ID)
77234 +*//***************************************************************************/
77235 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop);
77236 +
77237 +/**************************************************************************//**
77238 + @Function FM_ConfigDmaEmergency
77239 +
77240 + @Description Define DMA emergency.
77241 + Calling this routine changes the DMA emergency definition
77242 + in the internal driver data base from its default
77243 + configuration where's it's disabled.
77244 +
77245 + @Param[in] h_Fm A handle to an FM Module.
77246 + @Param[in] p_Emergency An OR mask of all required options.
77247 +
77248 + @Return E_OK on success; Error code otherwise.
77249 +
77250 + @Cautions Allowed only following FM_Config() and before FM_Init().
77251 + This routine should NOT be called from guest-partition
77252 + (i.e. guestId != NCSW_MASTER_ID)
77253 +*//***************************************************************************/
77254 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency);
77255 +
77256 +/**************************************************************************//**
77257 + @Function FM_ConfigDmaErr
77258 +
77259 + @Description DMA error treatment.
77260 + Calling this routine changes the DMA error treatment
77261 + in the internal driver data base from its default
77262 + configuration [DEFAULT_dmaErr].
77263 +
77264 + @Param[in] h_Fm A handle to an FM Module.
77265 + @Param[in] dmaErr The selected new choice.
77266 +
77267 + @Return E_OK on success; Error code otherwise.
77268 +
77269 + @Cautions Allowed only following FM_Config() and before FM_Init().
77270 + This routine should NOT be called from guest-partition
77271 + (i.e. guestId != NCSW_MASTER_ID)
77272 +*//***************************************************************************/
77273 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr);
77274 +
77275 +/**************************************************************************//**
77276 + @Function FM_ConfigCatastrophicErr
77277 +
77278 + @Description Define FM behavior on catastrophic error.
77279 + Calling this routine changes the FM behavior on catastrophic
77280 + error in the internal driver data base from its default
77281 + [DEFAULT_catastrophicErr].
77282 +
77283 + @Param[in] h_Fm A handle to an FM Module.
77284 + @Param[in] catastrophicErr The selected new choice.
77285 +
77286 + @Return E_OK on success; Error code otherwise.
77287 +
77288 + @Cautions Allowed only following FM_Config() and before FM_Init().
77289 + This routine should NOT be called from guest-partition
77290 + (i.e. guestId != NCSW_MASTER_ID)
77291 +*//***************************************************************************/
77292 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr);
77293 +
77294 +/**************************************************************************//**
77295 + @Function FM_ConfigEnableMuramTestMode
77296 +
77297 + @Description Enable MURAM test mode.
77298 + Calling this routine changes the internal driver data base
77299 + from its default selection of test mode where it's disabled.
77300 + This routine is only avaiable on old FM revisions (FMan v2).
77301 +
77302 + @Param[in] h_Fm A handle to an FM Module.
77303 +
77304 + @Return E_OK on success; Error code otherwise.
77305 +
77306 + @Cautions Allowed only following FM_Config() and before FM_Init().
77307 + This routine should NOT be called from guest-partition
77308 + (i.e. guestId != NCSW_MASTER_ID)
77309 +*//***************************************************************************/
77310 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm);
77311 +
77312 +/**************************************************************************//**
77313 + @Function FM_ConfigEnableIramTestMode
77314 +
77315 + @Description Enable IRAM test mode.
77316 + Calling this routine changes the internal driver data base
77317 + from its default selection of test mode where it's disabled.
77318 + This routine is only avaiable on old FM revisions (FMan v2).
77319 +
77320 + @Param[in] h_Fm A handle to an FM Module.
77321 +
77322 + @Return E_OK on success; Error code otherwise.
77323 +
77324 + @Cautions Allowed only following FM_Config() and before FM_Init().
77325 + This routine should NOT be called from guest-partition
77326 + (i.e. guestId != NCSW_MASTER_ID)
77327 +*//***************************************************************************/
77328 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm);
77329 +
77330 +/**************************************************************************//**
77331 + @Function FM_ConfigHaltOnExternalActivation
77332 +
77333 + @Description Define FM behavior on external halt activation.
77334 + Calling this routine changes the FM behavior on external halt
77335 + activation in the internal driver data base from its default
77336 + [DEFAULT_haltOnExternalActivation].
77337 +
77338 + @Param[in] h_Fm A handle to an FM Module.
77339 + @Param[in] enable TRUE to enable halt on external halt
77340 + activation.
77341 +
77342 + @Return E_OK on success; Error code otherwise.
77343 +
77344 + @Cautions Allowed only following FM_Config() and before FM_Init().
77345 + This routine should NOT be called from guest-partition
77346 + (i.e. guestId != NCSW_MASTER_ID)
77347 +*//***************************************************************************/
77348 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable);
77349 +
77350 +/**************************************************************************//**
77351 + @Function FM_ConfigHaltOnUnrecoverableEccError
77352 +
77353 + @Description Define FM behavior on external halt activation.
77354 + Calling this routine changes the FM behavior on unrecoverable
77355 + ECC error in the internal driver data base from its default
77356 + [DEFAULT_haltOnUnrecoverableEccError].
77357 + This routine is only avaiable on old FM revisions (FMan v2).
77358 +
77359 + @Param[in] h_Fm A handle to an FM Module.
77360 + @Param[in] enable TRUE to enable halt on unrecoverable Ecc error
77361 +
77362 + @Return E_OK on success; Error code otherwise.
77363 +
77364 + @Cautions Allowed only following FM_Config() and before FM_Init().
77365 + This routine should NOT be called from guest-partition
77366 + (i.e. guestId != NCSW_MASTER_ID)
77367 +*//***************************************************************************/
77368 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable);
77369 +
77370 +/**************************************************************************//**
77371 + @Function FM_ConfigException
77372 +
77373 + @Description Define FM exceptions.
77374 + Calling this routine changes the exceptions defaults in the
77375 + internal driver data base where all exceptions are enabled.
77376 +
77377 + @Param[in] h_Fm A handle to an FM Module.
77378 + @Param[in] exception The exception to be selected.
77379 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
77380 +
77381 + @Return E_OK on success; Error code otherwise.
77382 +
77383 + @Cautions Allowed only following FM_Config() and before FM_Init().
77384 + This routine should NOT be called from guest-partition
77385 + (i.e. guestId != NCSW_MASTER_ID)
77386 +*//***************************************************************************/
77387 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
77388 +
77389 +/**************************************************************************//**
77390 + @Function FM_ConfigExternalEccRamsEnable
77391 +
77392 + @Description Select external ECC enabling.
77393 + Calling this routine changes the ECC enabling control in the internal
77394 + driver data base from its default [DEFAULT_externalEccRamsEnable].
77395 + When this option is enabled Rams ECC enabling is not effected
77396 + by FM_EnableRamsEcc/FM_DisableRamsEcc, but by a JTAG.
77397 +
77398 + @Param[in] h_Fm A handle to an FM Module.
77399 + @Param[in] enable TRUE to enable this option.
77400 +
77401 + @Return E_OK on success; Error code otherwise.
77402 +
77403 + @Cautions Allowed only following FM_Config() and before FM_Init().
77404 + This routine should NOT be called from guest-partition
77405 + (i.e. guestId != NCSW_MASTER_ID)
77406 +*//***************************************************************************/
77407 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable);
77408 +
77409 +/**************************************************************************//**
77410 + @Function FM_ConfigTnumAgingPeriod
77411 +
77412 + @Description Define Tnum aging period.
77413 + Calling this routine changes the Tnum aging of dequeue TNUMs
77414 + in the QMI in the internal driver data base from its default
77415 + [DEFAULT_tnumAgingPeriod].
77416 +
77417 + @Param[in] h_Fm A handle to an FM Module.
77418 + @Param[in] tnumAgingPeriod Tnum Aging Period in microseconds.
77419 + Note that period is recalculated in units of
77420 + 64 FM clocks. Driver will pick the closest
77421 + possible period.
77422 +
77423 + @Return E_OK on success; Error code otherwise.
77424 +
77425 + @Cautions Allowed only following FM_Config() and before FM_Init().
77426 + This routine should NOT be called from guest-partition
77427 + (i.e. guestId != NCSW_MASTER_ID)
77428 + NOTE that if some MAC is configured for PFC, '0' value is NOT
77429 + allowed.
77430 +*//***************************************************************************/
77431 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod);
77432 +
77433 +/**************************************************************************//*
77434 + @Function FM_ConfigDmaEmergencySmoother
77435 +
77436 + @Description Define DMA emergency smoother.
77437 + Calling this routine changes the definition of the minimum
77438 + amount of DATA beats transferred on the AXI READ and WRITE
77439 + ports before lowering the emergency level.
77440 + By default smoother is disabled.
77441 +
77442 + @Param[in] h_Fm A handle to an FM Module.
77443 + @Param[in] emergencyCnt emergency switching counter.
77444 +
77445 + @Return E_OK on success; Error code otherwise.
77446 +
77447 + @Cautions Allowed only following FM_Config() and before FM_Init().
77448 + This routine should NOT be called from guest-partition
77449 + (i.e. guestId != NCSW_MASTER_ID)
77450 +*//***************************************************************************/
77451 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt);
77452 +
77453 +/**************************************************************************//*
77454 + @Function FM_ConfigThresholds
77455 +
77456 + @Description Calling this routine changes the internal driver data base
77457 + from its default FM threshold configuration:
77458 + dispLimit: [DEFAULT_dispLimit]
77459 + prsDispTh: [DEFAULT_prsDispTh]
77460 + plcrDispTh: [DEFAULT_plcrDispTh]
77461 + kgDispTh: [DEFAULT_kgDispTh]
77462 + bmiDispTh: [DEFAULT_bmiDispTh]
77463 + qmiEnqDispTh: [DEFAULT_qmiEnqDispTh]
77464 + qmiDeqDispTh: [DEFAULT_qmiDeqDispTh]
77465 + fmCtl1DispTh: [DEFAULT_fmCtl1DispTh]
77466 + fmCtl2DispTh: [DEFAULT_fmCtl2DispTh]
77467 +
77468 +
77469 + @Param[in] h_Fm A handle to an FM Module.
77470 + @Param[in] p_FmThresholds A structure of threshold parameters.
77471 +
77472 + @Return E_OK on success; Error code otherwise.
77473 +
77474 + @Cautions Allowed only following FM_Config() and before FM_Init().
77475 + This routine should NOT be called from guest-partition
77476 + (i.e. guestId != NCSW_MASTER_ID)
77477 +*//***************************************************************************/
77478 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds);
77479 +
77480 +/**************************************************************************//*
77481 + @Function FM_ConfigDmaSosEmergencyThreshold
77482 +
77483 + @Description Calling this routine changes the internal driver data base
77484 + from its default dma SOS emergency configuration [DEFAULT_dmaSosEmergency]
77485 +
77486 + @Param[in] h_Fm A handle to an FM Module.
77487 + @Param[in] dmaSosEmergency The selected new value.
77488 +
77489 + @Return E_OK on success; Error code otherwise.
77490 +
77491 + @Cautions Allowed only following FM_Config() and before FM_Init().
77492 + This routine should NOT be called from guest-partition
77493 + (i.e. guestId != NCSW_MASTER_ID)
77494 +*//***************************************************************************/
77495 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency);
77496 +
77497 +/**************************************************************************//*
77498 + @Function FM_ConfigDmaWriteBufThresholds
77499 +
77500 + @Description Calling this routine changes the internal driver data base
77501 + from its default configuration of DMA write buffer threshold
77502 + assertEmergency: [DEFAULT_dmaWriteIntBufLow]
77503 + clearEmergency: [DEFAULT_dmaWriteIntBufHigh]
77504 + This routine is only avaiable on old FM revisions (FMan v2).
77505 +
77506 + @Param[in] h_Fm A handle to an FM Module.
77507 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77508 + When 'assertEmergency' value is reached, emergency is asserted,
77509 + then it is held until 'clearEmergency' value is reached.
77510 +
77511 + @Return E_OK on success; Error code otherwise.
77512 +
77513 + @Cautions Allowed only following FM_Config() and before FM_Init().
77514 + This routine should NOT be called from guest-partition
77515 + (i.e. guestId != NCSW_MASTER_ID)
77516 +*//***************************************************************************/
77517 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77518 +
77519 + /**************************************************************************//*
77520 + @Function FM_ConfigDmaCommQThresholds
77521 +
77522 + @Description Calling this routine changes the internal driver data base
77523 + from its default configuration of DMA command queue threshold
77524 + assertEmergency: [DEFAULT_dmaCommQLow]
77525 + clearEmergency: [DEFAULT_dmaCommQHigh]
77526 +
77527 + @Param[in] h_Fm A handle to an FM Module.
77528 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77529 + When 'assertEmergency' value is reached, emergency is asserted,
77530 + then it is held until 'clearEmergency' value is reached..
77531 +
77532 + @Return E_OK on success; Error code otherwise.
77533 +
77534 + @Cautions Allowed only following FM_Config() and before FM_Init().
77535 + This routine should NOT be called from guest-partition
77536 + (i.e. guestId != NCSW_MASTER_ID)
77537 +*//***************************************************************************/
77538 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77539 +
77540 +/**************************************************************************//*
77541 + @Function FM_ConfigDmaReadBufThresholds
77542 +
77543 + @Description Calling this routine changes the internal driver data base
77544 + from its default configuration of DMA read buffer threshold
77545 + assertEmergency: [DEFAULT_dmaReadIntBufLow]
77546 + clearEmergency: [DEFAULT_dmaReadIntBufHigh]
77547 + This routine is only avaiable on old FM revisions (FMan v2).
77548 +
77549 + @Param[in] h_Fm A handle to an FM Module.
77550 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77551 + When 'assertEmergency' value is reached, emergency is asserted,
77552 + then it is held until 'clearEmergency' value is reached..
77553 +
77554 + @Return E_OK on success; Error code otherwise.
77555 +
77556 + @Cautions Allowed only following FM_Config() and before FM_Init().
77557 + This routine should NOT be called from guest-partition
77558 + (i.e. guestId != NCSW_MASTER_ID)
77559 +*//***************************************************************************/
77560 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77561 +
77562 +/**************************************************************************//*
77563 + @Function FM_ConfigDmaWatchdog
77564 +
77565 + @Description Calling this routine changes the internal driver data base
77566 + from its default watchdog configuration, which is disabled
77567 + [DEFAULT_dmaWatchdog].
77568 +
77569 + @Param[in] h_Fm A handle to an FM Module.
77570 + @Param[in] watchDogValue The selected new value - in microseconds.
77571 +
77572 + @Return E_OK on success; Error code otherwise.
77573 +
77574 + @Cautions Allowed only following FM_Config() and before FM_Init().
77575 + This routine should NOT be called from guest-partition
77576 + (i.e. guestId != NCSW_MASTER_ID)
77577 +*//***************************************************************************/
77578 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue);
77579 +
77580 +/** @} */ /* end of FM_advanced_init_grp group */
77581 +/** @} */ /* end of FM_init_grp group */
77582 +
77583 +
77584 +/**************************************************************************//**
77585 + @Group FM_runtime_control_grp FM Runtime Control Unit
77586 +
77587 + @Description FM Runtime control unit API functions, definitions and enums.
77588 + The FM driver provides a set of control routines.
77589 + These routines may only be called after the module was fully
77590 + initialized (both configuration and initialization routines were
77591 + called). They are typically used to get information from hardware
77592 + (status, counters/statistics, revision etc.), to modify a current
77593 + state or to force/enable a required action. Run-time control may
77594 + be called whenever necessary and as many times as needed.
77595 + @{
77596 +*//***************************************************************************/
77597 +
77598 +/**************************************************************************//**
77599 + @Collection General FM defines.
77600 +*//***************************************************************************/
77601 +#define FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
77602 + FM_MAX_NUM_OF_1G_RX_PORTS + \
77603 + FM_MAX_NUM_OF_10G_RX_PORTS + \
77604 + FM_MAX_NUM_OF_1G_TX_PORTS + \
77605 + FM_MAX_NUM_OF_10G_TX_PORTS) /**< Number of available FM ports */
77606 +/* @} */
77607 +
77608 +/**************************************************************************//*
77609 + @Description A Structure for Port bandwidth requirement. Port is identified
77610 + by type and relative id.
77611 +*//***************************************************************************/
77612 +typedef struct t_FmPortBandwidth {
77613 + e_FmPortType type; /**< FM port type */
77614 + uint8_t relativePortId; /**< Type relative port id */
77615 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
77616 +} t_FmPortBandwidth;
77617 +
77618 +/**************************************************************************//*
77619 + @Description A Structure containing an array of Port bandwidth requirements.
77620 + The user should state the ports requiring bandwidth in terms of
77621 + percentage - i.e. all port's bandwidths in the array must add
77622 + up to 100.
77623 +*//***************************************************************************/
77624 +typedef struct t_FmPortsBandwidthParams {
77625 + uint8_t numOfPorts; /**< The number of relevant ports, which is the
77626 + number of valid entries in the array below */
77627 + t_FmPortBandwidth portsBandwidths[FM_MAX_NUM_OF_VALID_PORTS];
77628 + /**< for each port, it's bandwidth (all port's
77629 + bandwidths must add up to 100.*/
77630 +} t_FmPortsBandwidthParams;
77631 +
77632 +/**************************************************************************//**
77633 + @Description DMA Emergency control on MURAM
77634 +*//***************************************************************************/
77635 +typedef enum e_FmDmaMuramPort {
77636 + e_FM_DMA_MURAM_PORT_WRITE, /**< MURAM write port */
77637 + e_FM_DMA_MURAM_PORT_READ /**< MURAM read port */
77638 +} e_FmDmaMuramPort;
77639 +
77640 +/**************************************************************************//**
77641 + @Description Enum for defining FM counters
77642 +*//***************************************************************************/
77643 +typedef enum e_FmCounters {
77644 + e_FM_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI total enqueued frames counter */
77645 + e_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
77646 + e_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
77647 + e_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
77648 + e_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
77649 + e_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
77650 + e_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
77651 + e_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
77652 + e_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
77653 + e_FM_COUNTERS_DEQ_CONFIRM /**< QMI dequeue confirm counter */
77654 +} e_FmCounters;
77655 +
77656 +/**************************************************************************//**
77657 + @Description A Structure for returning FM revision information
77658 +*//***************************************************************************/
77659 +typedef struct t_FmRevisionInfo {
77660 + uint8_t majorRev; /**< Major revision */
77661 + uint8_t minorRev; /**< Minor revision */
77662 +} t_FmRevisionInfo;
77663 +
77664 +/**************************************************************************//**
77665 + @Description A Structure for returning FM ctrl code revision information
77666 +*//***************************************************************************/
77667 +typedef struct t_FmCtrlCodeRevisionInfo {
77668 + uint16_t packageRev; /**< Package revision */
77669 + uint8_t majorRev; /**< Major revision */
77670 + uint8_t minorRev; /**< Minor revision */
77671 +} t_FmCtrlCodeRevisionInfo;
77672 +
77673 +/**************************************************************************//**
77674 + @Description A Structure for defining DMA status
77675 +*//***************************************************************************/
77676 +typedef struct t_FmDmaStatus {
77677 + bool cmqNotEmpty; /**< Command queue is not empty */
77678 + bool busError; /**< Bus error occurred */
77679 + bool readBufEccError; /**< Double ECC error on buffer Read (Valid for FM rev < 6)*/
77680 + bool writeBufEccSysError; /**< Double ECC error on buffer write from system side (Valid for FM rev < 6)*/
77681 + bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side (Valid for FM rev < 6) */
77682 + bool singlePortEccError; /**< Single Port ECC error from FM side (Valid for FM rev >= 6)*/
77683 +} t_FmDmaStatus;
77684 +
77685 +/**************************************************************************//**
77686 + @Description A Structure for obtaining FM controller monitor values
77687 +*//***************************************************************************/
77688 +typedef struct t_FmCtrlMon {
77689 + uint8_t percentCnt[2]; /**< Percentage value */
77690 +} t_FmCtrlMon;
77691 +
77692 +
77693 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
77694 +/**************************************************************************//**
77695 + @Function FM_DumpRegs
77696 +
77697 + @Description Dumps all FM registers
77698 +
77699 + @Param[in] h_Fm A handle to an FM Module.
77700 +
77701 + @Return E_OK on success;
77702 +
77703 + @Cautions Allowed only following FM_Init().
77704 +*//***************************************************************************/
77705 +t_Error FM_DumpRegs(t_Handle h_Fm);
77706 +#endif /* (defined(DEBUG_ERRORS) && ... */
77707 +
77708 +/**************************************************************************//**
77709 + @Function FM_SetException
77710 +
77711 + @Description Calling this routine enables/disables the specified exception.
77712 +
77713 + @Param[in] h_Fm A handle to an FM Module.
77714 + @Param[in] exception The exception to be selected.
77715 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
77716 +
77717 + @Return E_OK on success; Error code otherwise.
77718 +
77719 + @Cautions Allowed only following FM_Init().
77720 + This routine should NOT be called from guest-partition
77721 + (i.e. guestId != NCSW_MASTER_ID)
77722 +*//***************************************************************************/
77723 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
77724 +
77725 +/**************************************************************************//**
77726 + @Function FM_EnableRamsEcc
77727 +
77728 + @Description Enables ECC mechanism for all the different FM RAM's; E.g. IRAM,
77729 + MURAM, Parser, Keygen, Policer, etc.
77730 + Note:
77731 + If FM_ConfigExternalEccRamsEnable was called to enable external
77732 + setting of ECC, this routine effects IRAM ECC only.
77733 + This routine is also called by the driver if an ECC exception is
77734 + enabled.
77735 +
77736 + @Param[in] h_Fm A handle to an FM Module.
77737 +
77738 + @Return E_OK on success; Error code otherwise.
77739 +
77740 + @Cautions Allowed only following FM_Config() and before FM_Init().
77741 + This routine should NOT be called from guest-partition
77742 + (i.e. guestId != NCSW_MASTER_ID)
77743 +*//***************************************************************************/
77744 +t_Error FM_EnableRamsEcc(t_Handle h_Fm);
77745 +
77746 +/**************************************************************************//**
77747 + @Function FM_DisableRamsEcc
77748 +
77749 + @Description Disables ECC mechanism for all the different FM RAM's; E.g. IRAM,
77750 + MURAM, Parser, Keygen, Policer, etc.
77751 + Note:
77752 + If FM_ConfigExternalEccRamsEnable was called to enable external
77753 + setting of ECC, this routine effects IRAM ECC only.
77754 + In opposed to FM_EnableRamsEcc, this routine must be called
77755 + explicitly to disable all Rams ECC.
77756 +
77757 + @Param[in] h_Fm A handle to an FM Module.
77758 +
77759 + @Return E_OK on success; Error code otherwise.
77760 +
77761 + @Cautions Allowed only following FM_Config() and before FM_Init().
77762 + This routine should NOT be called from guest-partition
77763 + (i.e. guestId != NCSW_MASTER_ID)
77764 +*//***************************************************************************/
77765 +t_Error FM_DisableRamsEcc(t_Handle h_Fm);
77766 +
77767 +/**************************************************************************//**
77768 + @Function FM_GetRevision
77769 +
77770 + @Description Returns the FM revision
77771 +
77772 + @Param[in] h_Fm A handle to an FM Module.
77773 + @Param[out] p_FmRevisionInfo A structure of revision information parameters.
77774 +
77775 + @Return E_OK on success; Error code otherwise.
77776 +
77777 + @Cautions Allowed only following FM_Init().
77778 +*//***************************************************************************/
77779 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
77780 +
77781 +/**************************************************************************//**
77782 + @Function FM_GetFmanCtrlCodeRevision
77783 +
77784 + @Description Returns the Fman controller code revision
77785 +
77786 + @Param[in] h_Fm A handle to an FM Module.
77787 + @Param[out] p_RevisionInfo A structure of revision information parameters.
77788 +
77789 + @Return E_OK on success; Error code otherwise.
77790 +
77791 + @Cautions Allowed only following FM_Init().
77792 +*//***************************************************************************/
77793 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo);
77794 +
77795 +/**************************************************************************//**
77796 + @Function FM_GetCounter
77797 +
77798 + @Description Reads one of the FM counters.
77799 +
77800 + @Param[in] h_Fm A handle to an FM Module.
77801 + @Param[in] counter The requested counter.
77802 +
77803 + @Return Counter's current value.
77804 +
77805 + @Cautions Allowed only following FM_Init().
77806 + Note that it is user's responsibility to call this routine only
77807 + for enabled counters, and there will be no indication if a
77808 + disabled counter is accessed.
77809 +*//***************************************************************************/
77810 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter);
77811 +
77812 +/**************************************************************************//**
77813 + @Function FM_ModifyCounter
77814 +
77815 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
77816 +
77817 + @Param[in] h_Fm A handle to an FM Module.
77818 + @Param[in] counter The requested counter.
77819 + @Param[in] val The requested value to be written into the counter.
77820 +
77821 + @Return E_OK on success; Error code otherwise.
77822 +
77823 + @Cautions Allowed only following FM_Init().
77824 + This routine should NOT be called from guest-partition
77825 + (i.e. guestId != NCSW_MASTER_ID)
77826 +*//***************************************************************************/
77827 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val);
77828 +
77829 +/**************************************************************************//**
77830 + @Function FM_Resume
77831 +
77832 + @Description Release FM after halt FM command or after unrecoverable ECC error.
77833 +
77834 + @Param[in] h_Fm A handle to an FM Module.
77835 +
77836 + @Return E_OK on success; Error code otherwise.
77837 +
77838 + @Cautions Allowed only following FM_Init().
77839 + This routine should NOT be called from guest-partition
77840 + (i.e. guestId != NCSW_MASTER_ID)
77841 +*//***************************************************************************/
77842 +void FM_Resume(t_Handle h_Fm);
77843 +
77844 +/**************************************************************************//**
77845 + @Function FM_SetDmaEmergency
77846 +
77847 + @Description Manual emergency set
77848 +
77849 + @Param[in] h_Fm A handle to an FM Module.
77850 + @Param[in] muramPort MURAM direction select.
77851 + @Param[in] enable TRUE to manually enable emergency, FALSE to disable.
77852 +
77853 + @Return None.
77854 +
77855 + @Cautions Allowed only following FM_Init().
77856 + This routine should NOT be called from guest-partition
77857 + (i.e. guestId != NCSW_MASTER_ID)
77858 +*//***************************************************************************/
77859 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable);
77860 +
77861 +/**************************************************************************//**
77862 + @Function FM_SetDmaExtBusPri
77863 +
77864 + @Description Set the DMA external bus priority
77865 +
77866 + @Param[in] h_Fm A handle to an FM Module.
77867 + @Param[in] pri External bus priority select
77868 +
77869 + @Return None.
77870 +
77871 + @Cautions Allowed only following FM_Init().
77872 + This routine should NOT be called from guest-partition
77873 + (i.e. guestId != NCSW_MASTER_ID)
77874 +*//***************************************************************************/
77875 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri);
77876 +
77877 +/**************************************************************************//**
77878 + @Function FM_GetDmaStatus
77879 +
77880 + @Description Reads the DMA current status
77881 +
77882 + @Param[in] h_Fm A handle to an FM Module.
77883 + @Param[out] p_FmDmaStatus A structure of DMA status parameters.
77884 +
77885 + @Cautions Allowed only following FM_Init().
77886 +*//***************************************************************************/
77887 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus);
77888 +
77889 +/**************************************************************************//**
77890 + @Function FM_ErrorIsr
77891 +
77892 + @Description FM interrupt-service-routine for errors.
77893 +
77894 + @Param[in] h_Fm A handle to an FM Module.
77895 +
77896 + @Return E_OK on success; E_EMPTY if no errors found in register, other
77897 + error code otherwise.
77898 +
77899 + @Cautions Allowed only following FM_Init().
77900 + This routine should NOT be called from guest-partition
77901 + (i.e. guestId != NCSW_MASTER_ID)
77902 +*//***************************************************************************/
77903 +t_Error FM_ErrorIsr(t_Handle h_Fm);
77904 +
77905 +/**************************************************************************//**
77906 + @Function FM_EventIsr
77907 +
77908 + @Description FM interrupt-service-routine for normal events.
77909 +
77910 + @Param[in] h_Fm A handle to an FM Module.
77911 +
77912 + @Cautions Allowed only following FM_Init().
77913 + This routine should NOT be called from guest-partition
77914 + (i.e. guestId != NCSW_MASTER_ID)
77915 +*//***************************************************************************/
77916 +void FM_EventIsr(t_Handle h_Fm);
77917 +
77918 +/**************************************************************************//**
77919 + @Function FM_GetSpecialOperationCoding
77920 +
77921 + @Description Return a specific coding according to the input mask.
77922 +
77923 + @Param[in] h_Fm A handle to an FM Module.
77924 + @Param[in] spOper special operation mask.
77925 + @Param[out] p_SpOperCoding special operation code.
77926 +
77927 + @Return E_OK on success; Error code otherwise.
77928 +
77929 + @Cautions Allowed only following FM_Init().
77930 +*//***************************************************************************/
77931 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
77932 + fmSpecialOperations_t spOper,
77933 + uint8_t *p_SpOperCoding);
77934 +
77935 +/**************************************************************************//**
77936 + @Function FM_CtrlMonStart
77937 +
77938 + @Description Start monitoring utilization of all available FM controllers.
77939 +
77940 + In order to obtain FM controllers utilization the following sequence
77941 + should be used:
77942 + -# FM_CtrlMonStart()
77943 + -# FM_CtrlMonStop()
77944 + -# FM_CtrlMonGetCounters() - issued for each FM controller
77945 +
77946 + @Param[in] h_Fm A handle to an FM Module.
77947 +
77948 + @Return E_OK on success; Error code otherwise.
77949 +
77950 + @Cautions Allowed only following FM_Init().
77951 + This routine should NOT be called from guest-partition
77952 + (i.e. guestId != NCSW_MASTER_ID).
77953 +*//***************************************************************************/
77954 +t_Error FM_CtrlMonStart(t_Handle h_Fm);
77955 +
77956 +/**************************************************************************//**
77957 + @Function FM_CtrlMonStop
77958 +
77959 + @Description Stop monitoring utilization of all available FM controllers.
77960 +
77961 + In order to obtain FM controllers utilization the following sequence
77962 + should be used:
77963 + -# FM_CtrlMonStart()
77964 + -# FM_CtrlMonStop()
77965 + -# FM_CtrlMonGetCounters() - issued for each FM controller
77966 +
77967 + @Param[in] h_Fm A handle to an FM Module.
77968 +
77969 + @Return E_OK on success; Error code otherwise.
77970 +
77971 + @Cautions Allowed only following FM_Init().
77972 + This routine should NOT be called from guest-partition
77973 + (i.e. guestId != NCSW_MASTER_ID).
77974 +*//***************************************************************************/
77975 +t_Error FM_CtrlMonStop(t_Handle h_Fm);
77976 +
77977 +/**************************************************************************//**
77978 + @Function FM_CtrlMonGetCounters
77979 +
77980 + @Description Obtain FM controller utilization parameters.
77981 +
77982 + In order to obtain FM controllers utilization the following sequence
77983 + should be used:
77984 + -# FM_CtrlMonStart()
77985 + -# FM_CtrlMonStop()
77986 + -# FM_CtrlMonGetCounters() - issued for each FM controller
77987 +
77988 + @Param[in] h_Fm A handle to an FM Module.
77989 + @Param[in] fmCtrlIndex FM Controller index for that utilization results
77990 + are requested.
77991 + @Param[in] p_Mon Pointer to utilization results structure.
77992 +
77993 + @Return E_OK on success; Error code otherwise.
77994 +
77995 + @Cautions Allowed only following FM_Init().
77996 + This routine should NOT be called from guest-partition
77997 + (i.e. guestId != NCSW_MASTER_ID).
77998 +*//***************************************************************************/
77999 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon);
78000 +
78001 +
78002 +/**************************************************************************//*
78003 + @Function FM_ForceIntr
78004 +
78005 + @Description Causes an interrupt event on the requested source.
78006 +
78007 + @Param[in] h_Fm A handle to an FM Module.
78008 + @Param[in] exception An exception to be forced.
78009 +
78010 + @Return E_OK on success; Error code if the exception is not enabled,
78011 + or is not able to create interrupt.
78012 +
78013 + @Cautions Allowed only following FM_Init().
78014 + This routine should NOT be called from guest-partition
78015 + (i.e. guestId != NCSW_MASTER_ID)
78016 +*//***************************************************************************/
78017 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception);
78018 +
78019 +/**************************************************************************//*
78020 + @Function FM_SetPortsBandwidth
78021 +
78022 + @Description Sets relative weights between ports when accessing common resources.
78023 +
78024 + @Param[in] h_Fm A handle to an FM Module.
78025 + @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e.
78026 + total must equal 100.
78027 +
78028 + @Return E_OK on success; Error code otherwise.
78029 +
78030 + @Cautions Allowed only following FM_Init().
78031 + This routine should NOT be called from guest-partition
78032 + (i.e. guestId != NCSW_MASTER_ID)
78033 +*//***************************************************************************/
78034 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth);
78035 +
78036 +/**************************************************************************//*
78037 + @Function FM_GetMuramHandle
78038 +
78039 + @Description Gets the corresponding MURAM handle
78040 +
78041 + @Param[in] h_Fm A handle to an FM Module.
78042 +
78043 + @Return MURAM handle; NULL otherwise.
78044 +
78045 + @Cautions Allowed only following FM_Init().
78046 + This routine should NOT be called from guest-partition
78047 + (i.e. guestId != NCSW_MASTER_ID)
78048 +*//***************************************************************************/
78049 +t_Handle FM_GetMuramHandle(t_Handle h_Fm);
78050 +
78051 +/** @} */ /* end of FM_runtime_control_grp group */
78052 +/** @} */ /* end of FM_lib_grp group */
78053 +/** @} */ /* end of FM_grp group */
78054 +
78055 +
78056 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
78057 +typedef t_FmFirmwareParams t_FmPcdFirmwareParams;
78058 +typedef t_FmBufferPrefixContent t_FmPortBufferPrefixContent;
78059 +typedef t_FmExtPoolParams t_FmPortExtPoolParams;
78060 +typedef t_FmExtPools t_FmPortExtPools;
78061 +typedef t_FmBackupBmPools t_FmPortBackupBmPools;
78062 +typedef t_FmBufPoolDepletion t_FmPortBufPoolDepletion;
78063 +typedef e_FmDmaSwapOption e_FmPortDmaSwapOption;
78064 +typedef e_FmDmaCacheOption e_FmPortDmaCacheOption;
78065 +
78066 +#define FM_CONTEXTA_GET_OVVERIDE FM_CONTEXTA_GET_OVERRIDE
78067 +#define FM_CONTEXTA_SET_OVVERIDE FM_CONTEXTA_SET_OVERRIDE
78068 +
78069 +#define e_FM_EX_BMI_PIPELINE_ECC e_FM_EX_BMI_STORAGE_PROFILE_ECC
78070 +#define e_FM_PORT_DMA_NO_SWP e_FM_DMA_NO_SWP
78071 +#define e_FM_PORT_DMA_SWP_PPC_LE e_FM_DMA_SWP_PPC_LE
78072 +#define e_FM_PORT_DMA_SWP_BE e_FM_DMA_SWP_BE
78073 +#define e_FM_PORT_DMA_NO_STASH e_FM_DMA_NO_STASH
78074 +#define e_FM_PORT_DMA_STASH e_FM_DMA_STASH
78075 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
78076 +
78077 +
78078 +#endif /* __FM_EXT */
78079 --- /dev/null
78080 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
78081 @@ -0,0 +1,887 @@
78082 +/*
78083 + * Copyright 2008-2012 Freescale Semiconductor Inc.
78084 + *
78085 + * Redistribution and use in source and binary forms, with or without
78086 + * modification, are permitted provided that the following conditions are met:
78087 + * * Redistributions of source code must retain the above copyright
78088 + * notice, this list of conditions and the following disclaimer.
78089 + * * Redistributions in binary form must reproduce the above copyright
78090 + * notice, this list of conditions and the following disclaimer in the
78091 + * documentation and/or other materials provided with the distribution.
78092 + * * Neither the name of Freescale Semiconductor nor the
78093 + * names of its contributors may be used to endorse or promote products
78094 + * derived from this software without specific prior written permission.
78095 + *
78096 + *
78097 + * ALTERNATIVELY, this software may be distributed under the terms of the
78098 + * GNU General Public License ("GPL") as published by the Free Software
78099 + * Foundation, either version 2 of that License or (at your option) any
78100 + * later version.
78101 + *
78102 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
78103 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78104 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78105 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
78106 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78107 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78108 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
78109 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78110 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
78111 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78112 + */
78113 +
78114 +
78115 +/**************************************************************************//**
78116 + @File fm_mac_ext.h
78117 +
78118 + @Description FM MAC ...
78119 +*//***************************************************************************/
78120 +#ifndef __FM_MAC_EXT_H
78121 +#define __FM_MAC_EXT_H
78122 +
78123 +#include "std_ext.h"
78124 +#include "enet_ext.h"
78125 +
78126 +
78127 +/**************************************************************************//**
78128 +
78129 + @Group FM_grp Frame Manager API
78130 +
78131 + @Description FM API functions, definitions and enums
78132 +
78133 + @{
78134 +*//***************************************************************************/
78135 +
78136 +/**************************************************************************//**
78137 + @Group FM_mac_grp FM MAC
78138 +
78139 + @Description FM MAC API functions, definitions and enums
78140 +
78141 + @{
78142 +*//***************************************************************************/
78143 +
78144 +#define FM_MAC_NO_PFC 0xff
78145 +
78146 +
78147 +/**************************************************************************//**
78148 + @Description FM MAC Exceptions
78149 +*//***************************************************************************/
78150 +typedef enum e_FmMacExceptions {
78151 + e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0 /**< 10GEC MDIO scan event interrupt */
78152 + ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL /**< 10GEC MDIO command completion interrupt */
78153 + ,e_FM_MAC_EX_10G_REM_FAULT /**< 10GEC, mEMAC Remote fault interrupt */
78154 + ,e_FM_MAC_EX_10G_LOC_FAULT /**< 10GEC, mEMAC Local fault interrupt */
78155 + ,e_FM_MAC_EX_10G_1TX_ECC_ER /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
78156 + ,e_FM_MAC_EX_10G_TX_FIFO_UNFL /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
78157 + ,e_FM_MAC_EX_10G_TX_FIFO_OVFL /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
78158 + ,e_FM_MAC_EX_10G_TX_ER /**< 10GEC Transmit frame error interrupt */
78159 + ,e_FM_MAC_EX_10G_RX_FIFO_OVFL /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
78160 + ,e_FM_MAC_EX_10G_RX_ECC_ER /**< 10GEC, mEMAC Receive frame ECC error interrupt */
78161 + ,e_FM_MAC_EX_10G_RX_JAB_FRM /**< 10GEC Receive jabber frame interrupt */
78162 + ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM /**< 10GEC Receive oversized frame interrupt */
78163 + ,e_FM_MAC_EX_10G_RX_RUNT_FRM /**< 10GEC Receive runt frame interrupt */
78164 + ,e_FM_MAC_EX_10G_RX_FRAG_FRM /**< 10GEC Receive fragment frame interrupt */
78165 + ,e_FM_MAC_EX_10G_RX_LEN_ER /**< 10GEC Receive payload length error interrupt */
78166 + ,e_FM_MAC_EX_10G_RX_CRC_ER /**< 10GEC Receive CRC error interrupt */
78167 + ,e_FM_MAC_EX_10G_RX_ALIGN_ER /**< 10GEC Receive alignment error interrupt */
78168 + ,e_FM_MAC_EX_1G_BAB_RX /**< dTSEC Babbling receive error */
78169 + ,e_FM_MAC_EX_1G_RX_CTL /**< dTSEC Receive control (pause frame) interrupt */
78170 + ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET /**< dTSEC Graceful transmit stop complete */
78171 + ,e_FM_MAC_EX_1G_BAB_TX /**< dTSEC Babbling transmit error */
78172 + ,e_FM_MAC_EX_1G_TX_CTL /**< dTSEC Transmit control (pause frame) interrupt */
78173 + ,e_FM_MAC_EX_1G_TX_ERR /**< dTSEC Transmit error */
78174 + ,e_FM_MAC_EX_1G_LATE_COL /**< dTSEC Late collision */
78175 + ,e_FM_MAC_EX_1G_COL_RET_LMT /**< dTSEC Collision retry limit */
78176 + ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN /**< dTSEC Transmit FIFO underrun */
78177 + ,e_FM_MAC_EX_1G_MAG_PCKT /**< dTSEC Magic Packet detection */
78178 + ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET /**< dTSEC MII management read completion */
78179 + ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET /**< dTSEC MII management write completion */
78180 + ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET /**< dTSEC Graceful receive stop complete */
78181 + ,e_FM_MAC_EX_1G_TX_DATA_ERR /**< dTSEC Internal data error on transmit */
78182 + ,e_FM_MAC_EX_1G_RX_DATA_ERR /**< dTSEC Internal data error on receive */
78183 + ,e_FM_MAC_EX_1G_1588_TS_RX_ERR /**< dTSEC Time-Stamp Receive Error */
78184 + ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL /**< dTSEC MIB counter overflow */
78185 + ,e_FM_MAC_EX_TS_FIFO_ECC_ERR /**< mEMAC Time-stamp FIFO ECC error interrupt;
78186 + not supported on T4240/B4860 rev1 chips */
78187 + ,e_FM_MAC_EX_MAGIC_PACKET_INDICATION = e_FM_MAC_EX_1G_MAG_PCKT
78188 + /**< mEMAC Magic Packet Indication Interrupt */
78189 +} e_FmMacExceptions;
78190 +
78191 +/**************************************************************************//**
78192 + @Description TM MAC statistics level
78193 +*//***************************************************************************/
78194 +typedef enum e_FmMacStatisticsLevel {
78195 + e_FM_MAC_NONE_STATISTICS = 0, /**< No statistics */
78196 + e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; Optimized for performance */
78197 + e_FM_MAC_FULL_STATISTICS /**< All counters available; Not optimized for performance */
78198 +} e_FmMacStatisticsLevel;
78199 +
78200 +
78201 +#if (DPAA_VERSION >= 11)
78202 +/**************************************************************************//**
78203 + @Description Priority Flow Control Parameters
78204 +*//***************************************************************************/
78205 +typedef struct t_FmMacPfcParams {
78206 + bool pfcEnable; /**< Enable/Disable PFC */
78207 +
78208 + 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*/
78209 +
78210 + 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*/
78211 +
78212 +
78213 +} t_FmMacPfcParams;
78214 +#endif /* (DPAA_VERSION >= 11) */
78215 +
78216 +/**************************************************************************//**
78217 + @Function t_FmMacExceptionCallback
78218 +
78219 + @Description Fm Mac Exception Callback from FM MAC to the user
78220 +
78221 + @Param[in] h_App - Handle to the upper layer handler
78222 +
78223 + @Param[in] exceptions - The exception that occurred
78224 +
78225 + @Return void.
78226 +*//***************************************************************************/
78227 +typedef void (t_FmMacExceptionCallback)(t_Handle h_App, e_FmMacExceptions exceptions);
78228 +
78229 +
78230 +/**************************************************************************//**
78231 + @Description TM MAC statistics rfc3635
78232 +*//***************************************************************************/
78233 +typedef struct t_FmMacStatistics {
78234 +/* RMON */
78235 + uint64_t eStatPkts64; /**< r-10G tr-DT 64 byte frame counter */
78236 + uint64_t eStatPkts65to127; /**< r-10G 65 to 127 byte frame counter */
78237 + uint64_t eStatPkts128to255; /**< r-10G 128 to 255 byte frame counter */
78238 + uint64_t eStatPkts256to511; /**< r-10G 256 to 511 byte frame counter */
78239 + uint64_t eStatPkts512to1023; /**< r-10G 512 to 1023 byte frame counter */
78240 + uint64_t eStatPkts1024to1518; /**< r-10G 1024 to 1518 byte frame counter */
78241 + uint64_t eStatPkts1519to1522; /**< r-10G 1519 to 1522 byte good frame count */
78242 +/* */
78243 + uint64_t eStatFragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
78244 + uint64_t eStatJabbers; /**< Total number of packets longer than valid maximum length octets */
78245 + uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client (during receive). */
78246 + uint64_t eStatCRCAlignErrors; /**< Incremented when frames of correct length but with CRC error are received.*/
78247 + uint64_t eStatUndersizePkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
78248 + This count does not include range length errors */
78249 + uint64_t eStatOversizePkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
78250 + a valid FCS and otherwise well formed */
78251 +/* Pause */
78252 + uint64_t teStatPause; /**< Pause MAC Control received */
78253 + uint64_t reStatPause; /**< Pause MAC Control sent */
78254 +/* MIB II */
78255 + uint64_t ifInOctets; /**< Total number of byte received. */
78256 + uint64_t ifInPkts; /**< Total number of packets received.*/
78257 + uint64_t ifInUcastPkts; /**< Total number of unicast frame received;
78258 + NOTE: this counter is not supported on dTSEC MAC */
78259 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received*/
78260 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
78261 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX. */
78262 + uint64_t ifInErrors; /**< Number of frames received with error:
78263 + - FIFO Overflow Error
78264 + - CRC Error
78265 + - Frame Too Long Error
78266 + - Alignment Error
78267 + - The dedicated Error Code (0xfe, not a code error) was received */
78268 + uint64_t ifOutOctets; /**< Total number of byte sent. */
78269 + uint64_t ifOutPkts; /**< Total number of packets sent .*/
78270 + uint64_t ifOutUcastPkts; /**< Total number of unicast frame sent;
78271 + NOTE: this counter is not supported on dTSEC MAC */
78272 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
78273 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
78274 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
78275 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
78276 + - FIFO Overflow Error
78277 + - FIFO Underflow Error
78278 + - Other */
78279 +} t_FmMacStatistics;
78280 +
78281 +/**************************************************************************//**
78282 + @Description FM MAC Frame Size Counters
78283 +*//***************************************************************************/
78284 +typedef struct t_FmMacFrameSizeCounters {
78285 +
78286 + uint64_t count_pkts_64; /**< 64 byte frame counter */
78287 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
78288 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
78289 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
78290 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
78291 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
78292 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
78293 +} t_FmMacFrameSizeCounters;
78294 +
78295 +/**************************************************************************//**
78296 + @Group FM_mac_init_grp FM MAC Initialization Unit
78297 +
78298 + @Description FM MAC Initialization Unit
78299 +
78300 + @{
78301 +*//***************************************************************************/
78302 +
78303 +/**************************************************************************//**
78304 + @Description FM MAC config input
78305 +*//***************************************************************************/
78306 +typedef struct t_FmMacParams {
78307 + uintptr_t baseAddr; /**< Base of memory mapped FM MAC registers */
78308 + t_EnetAddr addr; /**< MAC address of device; First octet is sent first */
78309 + uint8_t macId; /**< MAC ID;
78310 + numbering of dTSEC and 1G-mEMAC:
78311 + 0 - FM_MAX_NUM_OF_1G_MACS;
78312 + numbering of 10G-MAC (TGEC) and 10G-mEMAC:
78313 + 0 - FM_MAX_NUM_OF_10G_MACS */
78314 + e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed);
78315 + Note that the speed should indicate the maximum rate that
78316 + this MAC should support rather than the actual speed;
78317 + i.e. user should use the FM_MAC_AdjustLink() routine to
78318 + provide accurate speed;
78319 + In case of mEMAC RGMII mode, the MAC is configured to RGMII
78320 + automatic mode, where actual speed/duplex mode information
78321 + is provided by PHY automatically in-band; FM_MAC_AdjustLink()
78322 + function should be used to switch to manual RGMII speed/duplex mode
78323 + configuration if RGMII PHY doesn't support in-band status signaling;
78324 + In addition, in mEMAC, in case where user is using the higher MACs
78325 + (i.e. the MACs that should support 10G), user should pass here
78326 + speed=10000 even if the interface is not allowing that (e.g. SGMII). */
78327 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
78328 + int mdioIrq; /**< MDIO exceptions interrupt source - not valid for all
78329 + MACs; MUST be set to 'NO_IRQ' for MACs that don't have
78330 + mdio-irq, or for polling */
78331 + t_FmMacExceptionCallback *f_Event; /**< MDIO Events Callback Routine */
78332 + t_FmMacExceptionCallback *f_Exception; /**< Exception Callback Routine */
78333 + t_Handle h_App; /**< A handle to an application layer object; This handle will
78334 + be passed by the driver upon calling the above callbacks */
78335 +} t_FmMacParams;
78336 +
78337 +
78338 +/**************************************************************************//**
78339 + @Function FM_MAC_Config
78340 +
78341 + @Description Creates descriptor for the FM MAC module.
78342 +
78343 + The routine returns a handle (descriptor) to the FM MAC object.
78344 + This descriptor must be passed as first parameter to all other
78345 + FM MAC function calls.
78346 +
78347 + No actual initialization or configuration of FM MAC hardware is
78348 + done by this routine.
78349 +
78350 + @Param[in] p_FmMacParam - Pointer to data structure of parameters
78351 +
78352 + @Retval Handle to FM MAC object, or NULL for Failure.
78353 +*//***************************************************************************/
78354 +t_Handle FM_MAC_Config(t_FmMacParams *p_FmMacParam);
78355 +
78356 +/**************************************************************************//**
78357 + @Function FM_MAC_Init
78358 +
78359 + @Description Initializes the FM MAC module
78360 +
78361 + @Param[in] h_FmMac - FM module descriptor
78362 +
78363 + @Return E_OK on success; Error code otherwise.
78364 +*//***************************************************************************/
78365 +t_Error FM_MAC_Init(t_Handle h_FmMac);
78366 +
78367 +/**************************************************************************//**
78368 + @Function FM_Free
78369 +
78370 + @Description Frees all resources that were assigned to FM MAC module.
78371 +
78372 + Calling this routine invalidates the descriptor.
78373 +
78374 + @Param[in] h_FmMac - FM module descriptor
78375 +
78376 + @Return E_OK on success; Error code otherwise.
78377 +*//***************************************************************************/
78378 +t_Error FM_MAC_Free(t_Handle h_FmMac);
78379 +
78380 +
78381 +/**************************************************************************//**
78382 + @Group FM_mac_advanced_init_grp FM MAC Advanced Configuration Unit
78383 +
78384 + @Description Configuration functions used to change default values.
78385 +
78386 + @{
78387 +*//***************************************************************************/
78388 +
78389 +/**************************************************************************//**
78390 + @Function FM_MAC_ConfigResetOnInit
78391 +
78392 + @Description Tell the driver whether to reset the FM MAC before initialization or
78393 + not. It changes the default configuration [DEFAULT_resetOnInit].
78394 +
78395 + @Param[in] h_FmMac A handle to a FM MAC Module.
78396 + @Param[in] enable When TRUE, FM will be reset before any initialization.
78397 +
78398 + @Return E_OK on success; Error code otherwise.
78399 +
78400 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78401 +*//***************************************************************************/
78402 +t_Error FM_MAC_ConfigResetOnInit(t_Handle h_FmMac, bool enable);
78403 +
78404 +/**************************************************************************//**
78405 + @Function FM_MAC_ConfigLoopback
78406 +
78407 + @Description Enable/Disable internal loopback mode
78408 +
78409 + @Param[in] h_FmMac A handle to a FM MAC Module.
78410 + @Param[in] enable TRUE to enable or FALSE to disable.
78411 +
78412 + @Return E_OK on success; Error code otherwise.
78413 +
78414 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78415 +*//***************************************************************************/
78416 +t_Error FM_MAC_ConfigLoopback(t_Handle h_FmMac, bool enable);
78417 +
78418 +/**************************************************************************//**
78419 + @Function FM_MAC_ConfigMaxFrameLength
78420 +
78421 + @Description Setup maximum Rx Frame Length (in 1G MAC, effects also Tx)
78422 +
78423 + @Param[in] h_FmMac A handle to a FM MAC Module.
78424 + @Param[in] newVal MAX Frame length
78425 +
78426 + @Return E_OK on success; Error code otherwise.
78427 +
78428 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78429 +*//***************************************************************************/
78430 +t_Error FM_MAC_ConfigMaxFrameLength(t_Handle h_FmMac, uint16_t newVal);
78431 +
78432 +/**************************************************************************//**
78433 + @Function FM_MAC_ConfigWan
78434 +
78435 + @Description ENABLE WAN mode in 10G-MAC
78436 +
78437 + @Param[in] h_FmMac A handle to a FM MAC Module.
78438 + @Param[in] enable TRUE to enable or FALSE to disable.
78439 +
78440 + @Return E_OK on success; Error code otherwise.
78441 +
78442 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78443 +*//***************************************************************************/
78444 +t_Error FM_MAC_ConfigWan(t_Handle h_FmMac, bool enable);
78445 +
78446 +/**************************************************************************//**
78447 + @Function FM_MAC_ConfigPadAndCrc
78448 +
78449 + @Description Config PAD and CRC mode
78450 +
78451 + @Param[in] h_FmMac A handle to a FM MAC Module.
78452 + @Param[in] enable TRUE to enable or FALSE to disable.
78453 +
78454 + @Return E_OK on success; Error code otherwise.
78455 +
78456 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78457 + Not supported on 10G-MAC (i.e. CRC & PAD are added automatically
78458 + by HW); on mEMAC, this routine supports only PAD (i.e. CRC is
78459 + added automatically by HW).
78460 +*//***************************************************************************/
78461 +t_Error FM_MAC_ConfigPadAndCrc(t_Handle h_FmMac, bool enable);
78462 +
78463 +/**************************************************************************//**
78464 + @Function FM_MAC_ConfigHalfDuplex
78465 +
78466 + @Description Config Half Duplex Mode
78467 +
78468 + @Param[in] h_FmMac A handle to a FM MAC Module.
78469 + @Param[in] enable TRUE to enable or FALSE to disable.
78470 +
78471 + @Return E_OK on success; Error code otherwise.
78472 +
78473 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78474 +*//***************************************************************************/
78475 +t_Error FM_MAC_ConfigHalfDuplex(t_Handle h_FmMac, bool enable);
78476 +
78477 +/**************************************************************************//**
78478 + @Function FM_MAC_ConfigTbiPhyAddr
78479 +
78480 + @Description Configures the address of internal TBI PHY.
78481 +
78482 + @Param[in] h_FmMac A handle to a FM MAC Module.
78483 + @Param[in] newVal TBI PHY address (1-31).
78484 +
78485 + @Return E_OK on success; Error code otherwise.
78486 +
78487 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78488 +*//***************************************************************************/
78489 +t_Error FM_MAC_ConfigTbiPhyAddr(t_Handle h_FmMac, uint8_t newVal);
78490 +
78491 +/**************************************************************************//**
78492 + @Function FM_MAC_ConfigLengthCheck
78493 +
78494 + @Description Configure the frame length checking.
78495 +
78496 + @Param[in] h_FmMac A handle to a FM MAC Module.
78497 + @Param[in] enable TRUE to enable or FALSE to disable.
78498 +
78499 + @Return E_OK on success; Error code otherwise.
78500 +
78501 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78502 +*//***************************************************************************/
78503 +t_Error FM_MAC_ConfigLengthCheck(t_Handle h_FmMac, bool enable);
78504 +
78505 +/**************************************************************************//**
78506 + @Function FM_MAC_ConfigException
78507 +
78508 + @Description Change Exception selection from default
78509 +
78510 + @Param[in] h_FmMac A handle to a FM MAC Module.
78511 + @Param[in] ex Type of the desired exceptions
78512 + @Param[in] enable TRUE to enable the specified exception, FALSE to disable it.
78513 +
78514 + @Return E_OK on success; Error code otherwise.
78515 +
78516 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78517 +*//***************************************************************************/
78518 +t_Error FM_MAC_ConfigException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
78519 +
78520 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
78521 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac);
78522 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
78523 +/** @} */ /* end of FM_mac_advanced_init_grp group */
78524 +/** @} */ /* end of FM_mac_init_grp group */
78525 +
78526 +
78527 +/**************************************************************************//**
78528 + @Group FM_mac_runtime_control_grp FM MAC Runtime Control Unit
78529 +
78530 + @Description FM MAC Runtime control unit API functions, definitions and enums.
78531 +
78532 + @{
78533 +*//***************************************************************************/
78534 +
78535 +/**************************************************************************//**
78536 + @Function FM_MAC_Enable
78537 +
78538 + @Description Enable the MAC
78539 +
78540 + @Param[in] h_FmMac A handle to a FM MAC Module.
78541 + @Param[in] mode Mode of operation (RX, TX, Both)
78542 +
78543 + @Return E_OK on success; Error code otherwise.
78544 +
78545 + @Cautions Allowed only following FM_MAC_Init().
78546 +*//***************************************************************************/
78547 +t_Error FM_MAC_Enable(t_Handle h_FmMac, e_CommMode mode);
78548 +
78549 +/**************************************************************************//**
78550 + @Function FM_MAC_Disable
78551 +
78552 + @Description DISABLE the MAC
78553 +
78554 + @Param[in] h_FmMac A handle to a FM MAC Module.
78555 + @Param[in] mode Define what part to Disable (RX, TX or BOTH)
78556 +
78557 + @Return E_OK on success; Error code otherwise.
78558 +
78559 + @Cautions Allowed only following FM_MAC_Init().
78560 +*//***************************************************************************/
78561 +t_Error FM_MAC_Disable(t_Handle h_FmMac, e_CommMode mode);
78562 +
78563 +/**************************************************************************//**
78564 + @Function FM_MAC_Resume
78565 +
78566 + @Description Re-init the MAC after suspend
78567 +
78568 + @Param[in] h_FmMac A handle to a FM MAC Module.
78569 +
78570 + @Return E_OK on success; Error code otherwise.
78571 +
78572 + @Cautions Allowed only following FM_MAC_Init().
78573 +*//***************************************************************************/
78574 +t_Error FM_MAC_Resume(t_Handle h_FmMac);
78575 +
78576 +/**************************************************************************//**
78577 + @Function FM_MAC_Enable1588TimeStamp
78578 +
78579 + @Description Enables the TSU operation.
78580 +
78581 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78582 +
78583 + @Return E_OK on success; Error code otherwise.
78584 +
78585 + @Cautions Allowed only following FM_MAC_Init().
78586 +*//***************************************************************************/
78587 +t_Error FM_MAC_Enable1588TimeStamp(t_Handle h_Fm);
78588 +
78589 +/**************************************************************************//**
78590 + @Function FM_MAC_Disable1588TimeStamp
78591 +
78592 + @Description Disables the TSU operation.
78593 +
78594 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78595 +
78596 + @Return E_OK on success; Error code otherwise.
78597 +
78598 + @Cautions Allowed only following FM_MAC_Init().
78599 +*//***************************************************************************/
78600 +t_Error FM_MAC_Disable1588TimeStamp(t_Handle h_Fm);
78601 +
78602 +/**************************************************************************//**
78603 + @Function FM_MAC_SetTxAutoPauseFrames
78604 +
78605 + @Description Enable/Disable transmission of Pause-Frames.
78606 + The routine changes the default configuration [DEFAULT_TX_PAUSE_TIME].
78607 +
78608 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78609 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78610 + Each quanta represents a 512 bit-times; Note that '0'
78611 + as an input here will be used as disabling the
78612 + transmission of the pause-frames.
78613 +
78614 + @Return E_OK on success; Error code otherwise.
78615 +
78616 + @Cautions Allowed only following FM_MAC_Init().
78617 +*//***************************************************************************/
78618 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
78619 + uint16_t pauseTime);
78620 +
78621 + /**************************************************************************//**
78622 + @Function FM_MAC_SetTxPauseFrames
78623 +
78624 + @Description Enable/Disable transmission of Pause-Frames.
78625 + The routine changes the default configuration:
78626 + pause-time - [DEFAULT_TX_PAUSE_TIME]
78627 + threshold-time - [0]
78628 +
78629 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78630 + @Param[in] priority - the PFC class of service; use 'FM_MAC_NO_PFC'
78631 + to indicate legacy pause support (i.e. no PFC).
78632 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78633 + Each quanta represents a 512 bit-times;
78634 + Note that '0' as an input here will be used as disabling the
78635 + transmission of the pause-frames.
78636 + @Param[in] threshTime - Pause Threshold equanta value used by the MAC to retransmit pause frame.
78637 + if the situation causing a pause frame to be sent didn't finish when the timer
78638 + reached the threshold quanta, the MAC will retransmit the pause frame.
78639 + Each quanta represents a 512 bit-times.
78640 +
78641 + @Return E_OK on success; Error code otherwise.
78642 +
78643 + @Cautions Allowed only following FM_MAC_Init().
78644 + In order for PFC to work properly the user must configure
78645 + TNUM-aging in the tx-port it is recommended that pre-fetch and
78646 + rate limit in the tx port should be disabled;
78647 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
78648 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
78649 + in the 'priority' field.
78650 +*//***************************************************************************/
78651 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
78652 + uint8_t priority,
78653 + uint16_t pauseTime,
78654 + uint16_t threshTime);
78655 +
78656 +/**************************************************************************//**
78657 + @Function FM_MAC_SetRxIgnorePauseFrames
78658 +
78659 + @Description Enable/Disable ignoring of Pause-Frames.
78660 +
78661 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78662 + @Param[in] en - boolean indicates whether to ignore the incoming pause
78663 + frames or not.
78664 +
78665 + @Return E_OK on success; Error code otherwise.
78666 +
78667 + @Cautions Allowed only following FM_MAC_Init().
78668 +*//***************************************************************************/
78669 +t_Error FM_MAC_SetRxIgnorePauseFrames(t_Handle h_FmMac, bool en);
78670 +
78671 +/**************************************************************************//**
78672 + @Function FM_MAC_SetWakeOnLan
78673 +
78674 + @Description Enable/Disable Wake On Lan support
78675 +
78676 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78677 + @Param[in] en - boolean indicates whether to enable Wake On Lan
78678 + support or not.
78679 +
78680 + @Return E_OK on success; Error code otherwise.
78681 +
78682 + @Cautions Allowed only following FM_MAC_Init().
78683 +*//***************************************************************************/
78684 +t_Error FM_MAC_SetWakeOnLan(t_Handle h_FmMac, bool en);
78685 +
78686 +/**************************************************************************//**
78687 + @Function FM_MAC_ResetCounters
78688 +
78689 + @Description reset all statistics counters
78690 +
78691 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78692 +
78693 + @Return E_OK on success; Error code otherwise.
78694 +
78695 + @Cautions Allowed only following FM_MAC_Init().
78696 +*//***************************************************************************/
78697 +t_Error FM_MAC_ResetCounters(t_Handle h_FmMac);
78698 +
78699 +/**************************************************************************//**
78700 + @Function FM_MAC_SetException
78701 +
78702 + @Description Enable/Disable a specific Exception
78703 +
78704 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78705 + @Param[in] ex - Type of the desired exceptions
78706 + @Param[in] enable - TRUE to enable the specified exception, FALSE to disable it.
78707 +
78708 +
78709 + @Return E_OK on success; Error code otherwise.
78710 +
78711 + @Cautions Allowed only following FM_MAC_Init().
78712 +*//***************************************************************************/
78713 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
78714 +
78715 +/**************************************************************************//**
78716 + @Function FM_MAC_SetStatistics
78717 +
78718 + @Description Define Statistics level.
78719 + Where applicable, the routine also enables the MIB counters
78720 + overflow interrupt in order to keep counters accurate
78721 + and account for overflows.
78722 + This routine is relevant only for dTSEC.
78723 +
78724 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78725 + @Param[in] statisticsLevel - Full statistics level provides all standard counters but may
78726 + reduce performance. Partial statistics provides only special
78727 + event counters (errors etc.). If selected, regular counters (such as
78728 + byte/packet) will be invalid and will return -1.
78729 +
78730 + @Return E_OK on success; Error code otherwise.
78731 +
78732 + @Cautions Allowed only following FM_MAC_Init().
78733 +*//***************************************************************************/
78734 +t_Error FM_MAC_SetStatistics(t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
78735 +
78736 +/**************************************************************************//**
78737 + @Function FM_MAC_GetStatistics
78738 +
78739 + @Description get all statistics counters
78740 +
78741 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78742 + @Param[in] p_Statistics - Structure with statistics
78743 +
78744 + @Return E_OK on success; Error code otherwise.
78745 +
78746 + @Cautions Allowed only following FM_Init().
78747 +*//***************************************************************************/
78748 +t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
78749 +
78750 +/**************************************************************************//**
78751 + @Function FM_MAC_GetFrameSizeCounters
78752 +
78753 + @Description get MAC statistics counters for different frame size
78754 +
78755 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78756 + @Param[in] p_FrameSizeCounters - Structure with counters
78757 + @Param[in] type - Type of counters to be read
78758 +
78759 + @Return E_OK on success; Error code otherwise.
78760 +
78761 + @Cautions Allowed only following FM_Init().
78762 +*//***************************************************************************/
78763 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
78764 +
78765 +/**************************************************************************//**
78766 + @Function FM_MAC_ModifyMacAddr
78767 +
78768 + @Description Replace the main MAC Address
78769 +
78770 + @Param[in] h_FmMac - A handle to a FM Module.
78771 + @Param[in] p_EnetAddr - Ethernet Mac address
78772 +
78773 + @Return E_OK on success; Error code otherwise.
78774 +
78775 + @Cautions Allowed only after FM_MAC_Init().
78776 +*//***************************************************************************/
78777 +t_Error FM_MAC_ModifyMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78778 +
78779 +/**************************************************************************//**
78780 + @Function FM_MAC_AddHashMacAddr
78781 +
78782 + @Description Add an Address to the hash table. This is for filter purpose only.
78783 +
78784 + @Param[in] h_FmMac - A handle to a FM Module.
78785 + @Param[in] p_EnetAddr - Ethernet Mac address
78786 +
78787 + @Return E_OK on success; Error code otherwise.
78788 +
78789 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
78790 + @Cautions Some address need to be filterd out in upper FM blocks.
78791 +*//***************************************************************************/
78792 +t_Error FM_MAC_AddHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78793 +
78794 +/**************************************************************************//**
78795 + @Function FM_MAC_RemoveHashMacAddr
78796 +
78797 + @Description Delete an Address to the hash table. This is for filter purpose only.
78798 +
78799 + @Param[in] h_FmMac - A handle to a FM Module.
78800 + @Param[in] p_EnetAddr - Ethernet Mac address
78801 +
78802 + @Return E_OK on success; Error code otherwise.
78803 +
78804 + @Cautions Allowed only following FM_MAC_Init().
78805 +*//***************************************************************************/
78806 +t_Error FM_MAC_RemoveHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78807 +
78808 +/**************************************************************************//**
78809 + @Function FM_MAC_AddExactMatchMacAddr
78810 +
78811 + @Description Add a unicast or multicast mac address for exact-match filtering
78812 + (8 on dTSEC, 2 for 10G-MAC)
78813 +
78814 + @Param[in] h_FmMac - A handle to a FM Module.
78815 + @Param[in] p_EnetAddr - MAC Address to ADD
78816 +
78817 + @Return E_OK on success; Error code otherwise.
78818 +
78819 + @Cautions Allowed only after FM_MAC_Init().
78820 +*//***************************************************************************/
78821 +t_Error FM_MAC_AddExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78822 +
78823 +/**************************************************************************//**
78824 + @Function FM_MAC_RemovelExactMatchMacAddr
78825 +
78826 + @Description Remove a uni cast or multi cast mac address.
78827 +
78828 + @Param[in] h_FmMac - A handle to a FM Module.
78829 + @Param[in] p_EnetAddr - MAC Address to remove
78830 +
78831 + @Return E_OK on success; Error code otherwise..
78832 +
78833 + @Cautions Allowed only after FM_MAC_Init().
78834 +*//***************************************************************************/
78835 +t_Error FM_MAC_RemovelExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78836 +
78837 +/**************************************************************************//**
78838 + @Function FM_MAC_SetPromiscuous
78839 +
78840 + @Description Enable/Disable MAC Promiscuous mode for ALL mac addresses.
78841 +
78842 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78843 + @Param[in] enable - TRUE to enable or FALSE to disable.
78844 +
78845 + @Return E_OK on success; Error code otherwise.
78846 +
78847 + @Cautions Allowed only after FM_MAC_Init().
78848 +*//***************************************************************************/
78849 +t_Error FM_MAC_SetPromiscuous(t_Handle h_FmMac, bool enable);
78850 +
78851 +/**************************************************************************//**
78852 + @Function FM_MAC_AdjustLink
78853 +
78854 + @Description Adjusts the Ethernet link with new speed/duplex setup.
78855 + This routine is relevant for dTSEC and mEMAC.
78856 + In case of mEMAC, this routine is also used for manual
78857 + re-configuration of RGMII speed and duplex mode for
78858 + RGMII PHYs not supporting in-band status information
78859 + to MAC.
78860 +
78861 + @Param[in] h_FmMac - A handle to a FM Module.
78862 + @Param[in] speed - Ethernet speed.
78863 + @Param[in] fullDuplex - TRUE for full-duplex mode;
78864 + FALSE for half-duplex mode.
78865 +
78866 + @Return E_OK on success; Error code otherwise.
78867 +*//***************************************************************************/
78868 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
78869 +
78870 +/**************************************************************************//**
78871 + @Function FM_MAC_RestartAutoneg
78872 +
78873 + @Description Restarts the auto-negotiation process.
78874 + When auto-negotiation process is invoked under traffic the
78875 + auto-negotiation process between the internal SGMII PHY and the
78876 + external PHY does not always complete successfully. Calling this
78877 + function will restart the auto-negotiation process that will end
78878 + successfully. It is recommended to call this function after issuing
78879 + auto-negotiation restart command to the Eth Phy.
78880 + This routine is relevant only for dTSEC.
78881 +
78882 + @Param[in] h_FmMac - A handle to a FM Module.
78883 +
78884 + @Return E_OK on success; Error code otherwise.
78885 +*//***************************************************************************/
78886 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac);
78887 +
78888 +/**************************************************************************//**
78889 + @Function FM_MAC_GetId
78890 +
78891 + @Description Return the MAC ID
78892 +
78893 + @Param[in] h_FmMac - A handle to a FM Module.
78894 + @Param[out] p_MacId - MAC ID of device
78895 +
78896 + @Return E_OK on success; Error code otherwise.
78897 +
78898 + @Cautions Allowed only after FM_MAC_Init().
78899 +*//***************************************************************************/
78900 +t_Error FM_MAC_GetId(t_Handle h_FmMac, uint32_t *p_MacId);
78901 +
78902 +/**************************************************************************//**
78903 + @Function FM_MAC_GetVesrion
78904 +
78905 + @Description Return Mac HW chip version
78906 +
78907 + @Param[in] h_FmMac - A handle to a FM Module.
78908 + @Param[out] p_MacVresion - Mac version as defined by the chip
78909 +
78910 + @Return E_OK on success; Error code otherwise.
78911 +
78912 + @Cautions Allowed only after FM_MAC_Init().
78913 +*//***************************************************************************/
78914 +t_Error FM_MAC_GetVesrion(t_Handle h_FmMac, uint32_t *p_MacVresion);
78915 +
78916 +/**************************************************************************//**
78917 + @Function FM_MAC_MII_WritePhyReg
78918 +
78919 + @Description Write data into Phy Register
78920 +
78921 + @Param[in] h_FmMac - A handle to a FM Module.
78922 + @Param[in] phyAddr - Phy Address on the MII bus
78923 + @Param[in] reg - Register Number.
78924 + @Param[in] data - Data to write.
78925 +
78926 + @Return E_OK on success; Error code otherwise.
78927 +
78928 + @Cautions Allowed only after FM_MAC_Init().
78929 +*//***************************************************************************/
78930 +t_Error FM_MAC_MII_WritePhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
78931 +
78932 +/**************************************************************************//**
78933 + @Function FM_MAC_MII_ReadPhyReg
78934 +
78935 + @Description Read data from Phy Register
78936 +
78937 + @Param[in] h_FmMac - A handle to a FM Module.
78938 + @Param[in] phyAddr - Phy Address on the MII bus
78939 + @Param[in] reg - Register Number.
78940 + @Param[out] p_Data - Data from PHY.
78941 +
78942 + @Return E_OK on success; Error code otherwise.
78943 +
78944 + @Cautions Allowed only after FM_MAC_Init().
78945 +*//***************************************************************************/
78946 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
78947 +
78948 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
78949 +/**************************************************************************//**
78950 + @Function FM_MAC_DumpRegs
78951 +
78952 + @Description Dump internal registers
78953 +
78954 + @Param[in] h_FmMac - A handle to a FM Module.
78955 +
78956 + @Return E_OK on success; Error code otherwise.
78957 +
78958 + @Cautions Allowed only after FM_MAC_Init().
78959 +*//***************************************************************************/
78960 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac);
78961 +#endif /* (defined(DEBUG_ERRORS) && ... */
78962 +
78963 +/** @} */ /* end of FM_mac_runtime_control_grp group */
78964 +/** @} */ /* end of FM_mac_grp group */
78965 +/** @} */ /* end of FM_grp group */
78966 +
78967 +
78968 +#endif /* __FM_MAC_EXT_H */
78969 --- /dev/null
78970 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
78971 @@ -0,0 +1,1271 @@
78972 +/*
78973 + * Copyright 2008-2015 Freescale Semiconductor Inc.
78974 + *
78975 + * Redistribution and use in source and binary forms, with or without
78976 + * modification, are permitted provided that the following conditions are met:
78977 + * * Redistributions of source code must retain the above copyright
78978 + * notice, this list of conditions and the following disclaimer.
78979 + * * Redistributions in binary form must reproduce the above copyright
78980 + * notice, this list of conditions and the following disclaimer in the
78981 + * documentation and/or other materials provided with the distribution.
78982 + * * Neither the name of Freescale Semiconductor nor the
78983 + * names of its contributors may be used to endorse or promote products
78984 + * derived from this software without specific prior written permission.
78985 + *
78986 + *
78987 + * ALTERNATIVELY, this software may be distributed under the terms of the
78988 + * GNU General Public License ("GPL") as published by the Free Software
78989 + * Foundation, either version 2 of that License or (at your option) any
78990 + * later version.
78991 + *
78992 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
78993 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78994 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78995 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
78996 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78997 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78998 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
78999 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
79000 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
79001 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79002 + */
79003 +
79004 +/**************************************************************************//**
79005 + @File fm_macsec_ext.h
79006 +
79007 + @Description FM MACSEC ...
79008 +*//***************************************************************************/
79009 +#ifndef __FM_MACSEC_EXT_H
79010 +#define __FM_MACSEC_EXT_H
79011 +
79012 +#include "std_ext.h"
79013 +
79014 +
79015 +/**************************************************************************//**
79016 + @Group FM_grp Frame Manager API
79017 +
79018 + @Description FM API functions, definitions and enums
79019 +
79020 + @{
79021 +*//***************************************************************************/
79022 +
79023 +/**************************************************************************//**
79024 + @Group FM_MACSEC_grp FM MACSEC
79025 +
79026 + @Description FM MACSEC API functions, definitions and enums
79027 +
79028 + @{
79029 +*//***************************************************************************/
79030 +
79031 +/**************************************************************************//**
79032 + @Description MACSEC Exceptions
79033 +*//***************************************************************************/
79034 +typedef enum e_FmMacsecExceptions {
79035 + e_FM_MACSEC_EX_SINGLE_BIT_ECC, /**< Single bit ECC error */
79036 + e_FM_MACSEC_EX_MULTI_BIT_ECC /**< Multi bit ECC error */
79037 +} e_FmMacsecExceptions;
79038 +
79039 +
79040 +/**************************************************************************//**
79041 + @Group FM_MACSEC_init_grp FM-MACSEC Initialization Unit
79042 +
79043 + @Description FM MACSEC Initialization Unit
79044 +
79045 + @{
79046 +*//***************************************************************************/
79047 +
79048 +/**************************************************************************//**
79049 + @Function t_FmMacsecExceptionsCallback
79050 +
79051 + @Description Exceptions user callback routine, will be called upon an
79052 + exception passing the exception identification.
79053 +
79054 + @Param[in] h_App A handle to an application layer object; This handle
79055 + will be passed by the driver upon calling this callback.
79056 + @Param[in] exception The exception.
79057 +*//***************************************************************************/
79058 +typedef void (t_FmMacsecExceptionsCallback) ( t_Handle h_App,
79059 + e_FmMacsecExceptions exception);
79060 +
79061 +
79062 +/**************************************************************************//**
79063 + @Description FM MACSEC config input
79064 +*//***************************************************************************/
79065 +typedef struct t_FmMacsecParams {
79066 + t_Handle h_Fm; /**< A handle to the FM object related to */
79067 + bool guestMode; /**< Partition-id */
79068 + union {
79069 + struct {
79070 + uint8_t fmMacId; /**< FM MAC id */
79071 + } guestParams;
79072 +
79073 + struct {
79074 + uintptr_t baseAddr; /**< Base of memory mapped FM MACSEC registers */
79075 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
79076 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
79077 + t_Handle h_App; /**< A handle to an application layer object; This handle will
79078 + be passed by the driver upon calling the above callbacks */
79079 + } nonGuestParams;
79080 + };
79081 +} t_FmMacsecParams;
79082 +
79083 +/**************************************************************************//**
79084 + @Function FM_MACSEC_Config
79085 +
79086 + @Description Creates descriptor for the FM MACSEC module;
79087 +
79088 + The routine returns a handle (descriptor) to the FM MACSEC object;
79089 + This descriptor must be passed as first parameter to all other
79090 + FM MACSEC function calls;
79091 +
79092 + No actual initialization or configuration of FM MACSEC hardware is
79093 + done by this routine.
79094 +
79095 + @Param[in] p_FmMacsecParam Pointer to data structure of parameters.
79096 +
79097 + @Retval Handle to FM MACSEC object, or NULL for Failure.
79098 +*//***************************************************************************/
79099 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam);
79100 +
79101 +/**************************************************************************//**
79102 + @Function FM_MACSEC_Init
79103 +
79104 + @Description Initializes the FM MACSEC module.
79105 +
79106 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79107 +
79108 + @Return E_OK on success; Error code otherwise.
79109 +*//***************************************************************************/
79110 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec);
79111 +
79112 +/**************************************************************************//**
79113 + @Function FM_MACSEC_Free
79114 +
79115 + @Description Frees all resources that were assigned to FM MACSEC module;
79116 +
79117 + Calling this routine invalidates the descriptor.
79118 +
79119 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79120 +
79121 + @Return E_OK on success; Error code otherwise.
79122 +*//***************************************************************************/
79123 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec);
79124 +
79125 +
79126 +/**************************************************************************//**
79127 + @Group FM_MACSEC_advanced_init_grp FM-MACSEC Advanced Configuration Unit
79128 +
79129 + @Description Configuration functions used to change default values.
79130 +
79131 + @{
79132 +*//***************************************************************************/
79133 +
79134 +/**************************************************************************//**
79135 + @Description enum for unknown sci frame treatment
79136 +*//***************************************************************************/
79137 +typedef enum e_FmMacsecUnknownSciFrameTreatment {
79138 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH = 0, /**< Controlled port - Strict mode */
79139 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, /**< If C bit clear deliver on controlled port, else discard
79140 + Controlled port - Check or Disable mode */
79141 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, /**< Controlled port - Strict mode */
79142 + 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,
79143 + else discard on uncontrolled port and deliver on controlled port
79144 + Controlled port - Check or Disable mode */
79145 +} e_FmMacsecUnknownSciFrameTreatment;
79146 +
79147 +/**************************************************************************//**
79148 + @Description enum for untag frame treatment
79149 +*//***************************************************************************/
79150 +typedef enum e_FmMacsecUntagFrameTreatment {
79151 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED = 0, /**< Controlled port - Strict mode */
79152 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, /**< Controlled port - Strict mode */
79153 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED /**< Controlled port - Strict mode */
79154 +} e_FmMacsecUntagFrameTreatment;
79155 +
79156 +/**************************************************************************//**
79157 + @Function FM_MACSEC_ConfigUnknownSciFrameTreatment
79158 +
79159 + @Description Change the treatment for received frames with unknown sci from its default
79160 + configuration [DEFAULT_unknownSciFrameTreatment].
79161 +
79162 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79163 + @Param[in] treatMode The selected mode.
79164 +
79165 + @Return E_OK on success; Error code otherwise.
79166 +
79167 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79168 +*//***************************************************************************/
79169 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
79170 +
79171 +/**************************************************************************//**
79172 + @Function FM_MACSEC_ConfigInvalidTagsFrameTreatment
79173 +
79174 + @Description Change the treatment for received frames with invalid tags or
79175 + a zero value PN or an invalid ICV from its default configuration
79176 + [DEFAULT_invalidTagsFrameTreatment].
79177 +
79178 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79179 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79180 + In both cases discard on the controlled port;
79181 + this provide Strict, Check or Disable mode.
79182 +
79183 + @Return E_OK on success; Error code otherwise.
79184 +
79185 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79186 +*//***************************************************************************/
79187 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79188 +
79189 +/**************************************************************************//**
79190 + @Function FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment
79191 +
79192 + @Description Change the treatment for received frames with the Encryption bit
79193 + set and the Changed Text bit clear from its default configuration
79194 + [DEFAULT_encryptWithNoChangedTextFrameTreatment].
79195 +
79196 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79197 + @Param[in] discardUncontrolled If True discard on the uncontrolled port, else deliver;
79198 + In both cases discard on the controlled port;
79199 + this provide Strict, Check or Disable mode.
79200 +
79201 + @Return E_OK on success; Error code otherwise.
79202 +
79203 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79204 +*//***************************************************************************/
79205 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled);
79206 +
79207 +/**************************************************************************//**
79208 + @Function FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment
79209 +
79210 + @Description Change the treatment for received frames with the Encryption bit
79211 + clear and the Changed Text bit set from its default configuration
79212 + [DEFAULT_changedTextWithNoEncryptFrameTreatment].
79213 +
79214 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79215 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79216 + In both cases discard on the controlled port;
79217 + this provide Strict, Check or Disable mode.
79218 +
79219 + @Return E_OK on success; Error code otherwise.
79220 +
79221 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79222 +*//***************************************************************************/
79223 +t_Error FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79224 +
79225 +/**************************************************************************//**
79226 + @Function FM_MACSEC_ConfigUntagFrameTreatment
79227 +
79228 + @Description Change the treatment for received frames without the MAC security tag (SecTAG)
79229 + from its default configuration [DEFAULT_untagFrameTreatment].
79230 +
79231 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79232 + @Param[in] treatMode The selected mode.
79233 +
79234 + @Return E_OK on success; Error code otherwise.
79235 +
79236 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79237 +*//***************************************************************************/
79238 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
79239 +
79240 +/**************************************************************************//**
79241 + @Function FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment
79242 +
79243 + @Description Change the treatment for received frames with only SCB bit set
79244 + from its default configuration [DEFAULT_onlyScbIsSetFrameTreatment].
79245 +
79246 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79247 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79248 + In both cases discard on the controlled port;
79249 + this provide Strict, Check or Disable mode.
79250 +
79251 + @Return E_OK on success; Error code otherwise.
79252 +
79253 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79254 +*//***************************************************************************/
79255 +t_Error FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79256 +
79257 +/**************************************************************************//**
79258 + @Function FM_MACSEC_ConfigPnExhaustionThreshold
79259 +
79260 + @Description It's provide the ability to configure a PN exhaustion threshold;
79261 + When the NextPn crosses this value an interrupt event
79262 + is asserted to warn that the active SA should re-key.
79263 +
79264 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79265 + @Param[in] pnExhThr If the threshold is reached, an interrupt event
79266 + is asserted to re-key.
79267 +
79268 + @Return E_OK on success; Error code otherwise.
79269 +
79270 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79271 +*//***************************************************************************/
79272 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr);
79273 +
79274 +/**************************************************************************//**
79275 + @Function FM_MACSEC_ConfigKeysUnreadable
79276 +
79277 + @Description Turn on privacy mode; All the keys and their hash values can't be read any more;
79278 + Can not be cleared unless hard reset.
79279 +
79280 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79281 +
79282 + @Return E_OK on success; Error code otherwise.
79283 +
79284 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79285 +*//***************************************************************************/
79286 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec);
79287 +
79288 +/**************************************************************************//**
79289 + @Function FM_MACSEC_ConfigSectagWithoutSCI
79290 +
79291 + @Description Promise that all generated Sectag will be without SCI included.
79292 +
79293 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79294 +
79295 + @Return E_OK on success; Error code otherwise.
79296 +
79297 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79298 +*//***************************************************************************/
79299 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec);
79300 +
79301 +/**************************************************************************//**
79302 + @Function FM_MACSEC_ConfigException
79303 +
79304 + @Description Calling this routine changes the internal driver data base
79305 + from its default selection of exceptions enablement;
79306 + By default all exceptions are enabled.
79307 +
79308 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79309 + @Param[in] exception The exception to be selected.
79310 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79311 +
79312 + @Return E_OK on success; Error code otherwise.
79313 +
79314 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79315 +*//***************************************************************************/
79316 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79317 +
79318 +/** @} */ /* end of FM_MACSEC_advanced_init_grp group */
79319 +/** @} */ /* end of FM_MACSEC_init_grp group */
79320 +
79321 +
79322 +/**************************************************************************//**
79323 + @Group FM_MACSEC_runtime_control_grp FM-MACSEC Runtime Control Data Unit
79324 +
79325 + @Description FM MACSEC runtime control data unit API functions, definitions and enums.
79326 +
79327 + @{
79328 +*//***************************************************************************/
79329 +
79330 +/**************************************************************************//**
79331 + @Function FM_MACSEC_GetRevision
79332 +
79333 + @Description Return MACSEC HW chip revision
79334 +
79335 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79336 + @Param[out] p_MacsecRevision MACSEC revision as defined by the chip.
79337 +
79338 + @Return E_OK on success; Error code otherwise.
79339 +
79340 + @Cautions Allowed only after FM_MACSEC_Init().
79341 +*//***************************************************************************/
79342 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
79343 +
79344 +/**************************************************************************//**
79345 + @Function FM_MACSEC_Enable
79346 +
79347 + @Description This routine should be called after MACSEC is initialized for enabling all
79348 + MACSEC engines according to their existing configuration.
79349 +
79350 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79351 +
79352 + @Return E_OK on success; Error code otherwise.
79353 +
79354 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is disabled.
79355 +*//***************************************************************************/
79356 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec);
79357 +
79358 +/**************************************************************************//**
79359 + @Function FM_MACSEC_Disable
79360 +
79361 + @Description This routine may be called when MACSEC is enabled in order to
79362 + disable all MACSEC engines; The MACSEC is working in bypass mode.
79363 +
79364 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79365 +
79366 + @Return E_OK on success; Error code otherwise.
79367 +
79368 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is enabled.
79369 +*//***************************************************************************/
79370 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec);
79371 +
79372 +/**************************************************************************//**
79373 + @Function FM_MACSEC_SetException
79374 +
79375 + @Description Calling this routine enables/disables the specified exception.
79376 +
79377 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79378 + @Param[in] exception The exception to be selected.
79379 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79380 +
79381 + @Return E_OK on success; Error code otherwise.
79382 +
79383 + @Cautions Allowed only following FM_MACSEC_Init().
79384 +*//***************************************************************************/
79385 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79386 +
79387 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
79388 +/**************************************************************************//**
79389 + @Function FM_MACSEC_DumpRegs
79390 +
79391 + @Description Dump internal registers.
79392 +
79393 + @Param[in] h_FmMacsec - FM MACSEC module descriptor.
79394 +
79395 + @Return E_OK on success; Error code otherwise.
79396 +
79397 + @Cautions Allowed only after FM_MACSEC_Init().
79398 +*//***************************************************************************/
79399 +t_Error FM_MACSEC_DumpRegs(t_Handle h_FmMacsec);
79400 +#endif /* (defined(DEBUG_ERRORS) && ... */
79401 +
79402 +#ifdef VERIFICATION_SUPPORT
79403 +/********************* VERIFICATION ONLY ********************************/
79404 +/**************************************************************************//**
79405 + @Function FM_MACSEC_BackdoorSet
79406 +
79407 + @Description Set register of the MACSEC memory map
79408 +
79409 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79410 + @Param[out] offset Register offset.
79411 + @Param[out] value Value to write.
79412 +
79413 +
79414 + @Return None
79415 +
79416 + @Cautions Allowed only following FM_MACSEC_Init().
79417 +*//***************************************************************************/
79418 +t_Error FM_MACSEC_BackdoorSet(t_Handle h_FmMacsec, uint32_t offset, uint32_t value);
79419 +
79420 +/**************************************************************************//**
79421 + @Function FM_MACSEC_BackdoorGet
79422 +
79423 + @Description Read from register of the MACSEC memory map.
79424 +
79425 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79426 + @Param[out] offset Register offset.
79427 +
79428 + @Return Value read
79429 +
79430 + @Cautions Allowed only following FM_MACSEC_Init().
79431 +*//***************************************************************************/
79432 +uint32_t FM_MACSEC_BackdoorGet(t_Handle h_FmMacsec, uint32_t offset);
79433 +#endif /* VERIFICATION_SUPPORT */
79434 +
79435 +/** @} */ /* end of FM_MACSEC_runtime_control_grp group */
79436 +
79437 +
79438 +/**************************************************************************//**
79439 + @Group FM_MACSEC_SECY_grp FM-MACSEC SecY
79440 +
79441 + @Description FM-MACSEC SecY API functions, definitions and enums
79442 +
79443 + @{
79444 +*//***************************************************************************/
79445 +
79446 +typedef uint8_t macsecSAKey_t[32];
79447 +typedef uint64_t macsecSCI_t;
79448 +typedef uint8_t macsecAN_t;
79449 +
79450 +/**************************************************************************//**
79451 +@Description MACSEC SECY Cipher Suite
79452 +*//***************************************************************************/
79453 +typedef enum e_FmMacsecSecYCipherSuite {
79454 + e_FM_MACSEC_SECY_GCM_AES_128 = 0, /**< GCM-AES-128 */
79455 +#if (DPAA_VERSION >= 11)
79456 + e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
79457 +#endif /* (DPAA_VERSION >= 11) */
79458 +} e_FmMacsecSecYCipherSuite;
79459 +
79460 +/**************************************************************************//**
79461 + @Description MACSEC SECY Exceptions
79462 +*//***************************************************************************/
79463 +typedef enum e_FmMacsecSecYExceptions {
79464 + e_FM_MACSEC_SECY_EX_FRAME_DISCARDED /**< Frame Discarded */
79465 +} e_FmMacsecSecYExceptions;
79466 +
79467 +/**************************************************************************//**
79468 + @Description MACSEC SECY Events
79469 +*//***************************************************************************/
79470 +typedef enum e_FmMacsecSecYEvents {
79471 + e_FM_MACSEC_SECY_EV_NEXT_PN /**< Next Packet Number exhaustion threshold reached */
79472 +} e_FmMacsecSecYEvents;
79473 +
79474 +/**************************************************************************//**
79475 + @Collection MACSEC SECY Frame Discarded Descriptor error
79476 +*//***************************************************************************/
79477 +typedef uint8_t macsecTxScFrameDiscardedErrSelect_t; /**< typedef for defining Frame Discarded Descriptor errors */
79478 +
79479 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_NEXT_PN_ZERO 0x8000 /**< NextPn == 0 */
79480 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_SC_DISBALE 0x4000 /**< SC is disable */
79481 +/* @} */
79482 +
79483 +/**************************************************************************//**
79484 + @Function t_FmMacsecSecYExceptionsCallback
79485 +
79486 + @Description Exceptions user callback routine, will be called upon an
79487 + exception passing the exception identification.
79488 +
79489 + @Param[in] h_App A handle to an application layer object; This handle
79490 + will be passed by the driver upon calling this callback.
79491 + @Param[in] exception The exception.
79492 +*//***************************************************************************/
79493 +typedef void (t_FmMacsecSecYExceptionsCallback) ( t_Handle h_App,
79494 + e_FmMacsecSecYExceptions exception);
79495 +
79496 +/**************************************************************************//**
79497 + @Function t_FmMacsecSecYEventsCallback
79498 +
79499 + @Description Events user callback routine, will be called upon an
79500 + event passing the event identification.
79501 +
79502 + @Param[in] h_App A handle to an application layer object; This handle
79503 + will be passed by the driver upon calling this callback.
79504 + @Param[in] event The event.
79505 +*//***************************************************************************/
79506 +typedef void (t_FmMacsecSecYEventsCallback) ( t_Handle h_App,
79507 + e_FmMacsecSecYEvents event);
79508 +
79509 +/**************************************************************************//**
79510 + @Description RFC2863 MIB
79511 +*//***************************************************************************/
79512 +typedef struct t_MIBStatistics {
79513 + uint64_t ifInOctets; /**< Total number of byte received */
79514 + uint64_t ifInPkts; /**< Total number of packets received */
79515 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received */
79516 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
79517 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX :
79518 + - InPktsNoTag,
79519 + - InPktsLate,
79520 + - InPktsOverrun */
79521 + uint64_t ifInErrors; /**< Number of frames received with error:
79522 + - InPktsBadTag,
79523 + - InPktsNoSCI,
79524 + - InPktsNotUsingSA
79525 + - InPktsNotValid */
79526 + uint64_t ifOutOctets; /**< Total number of byte sent */
79527 + uint64_t ifOutPkts; /**< Total number of packets sent */
79528 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
79529 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
79530 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A! */
79531 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
79532 + - FIFO Overflow Error
79533 + - FIFO Underflow Error
79534 + - Other */
79535 +} t_MIBStatistics;
79536 +
79537 +/**************************************************************************//**
79538 + @Description MACSEC SecY Rx SA Statistics
79539 +*//***************************************************************************/
79540 +typedef struct t_FmMacsecSecYRxSaStatistics {
79541 + uint32_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79542 + frame validation frame validation with the validateFrame not set to disable */
79543 + uint32_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79544 + validation with the validateFrame set to check */
79545 + uint32_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79546 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79547 + uint32_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79548 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79549 + uint32_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79550 + with validateFrame not in the strict mode and the C bit is cleared */
79551 +} t_FmMacsecSecYRxSaStatistics;
79552 +
79553 +/**************************************************************************//**
79554 + @Description MACSEC SecY Tx SA Statistics
79555 +*//***************************************************************************/
79556 +typedef struct t_FmMacsecSecYTxSaStatistics {
79557 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79558 + be transmitted, which were integrity protected */
79559 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79560 + be transmitted, which were confidentiality protected */
79561 +} t_FmMacsecSecYTxSaStatistics;
79562 +
79563 +/**************************************************************************//**
79564 + @Description MACSEC SecY Rx SC Statistics
79565 +*//***************************************************************************/
79566 +typedef struct t_FmMacsecSecYRxScStatistics {
79567 + uint64_t inPktsUnchecked; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79568 + that are not validated with the validateFrame set to disable */
79569 + uint64_t inPktsDelayed; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79570 + that have their PN smaller than the lowest_PN with the validateFrame set to
79571 + disable or replayProtect disabled */
79572 + uint64_t inPktsLate; /**< The number of frames with resolved SCI, discarded on the controlled port,
79573 + that have their PN smaller than the lowest_PN with the validateFrame set to
79574 + Check or Strict and replayProtect enabled */
79575 + uint64_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79576 + frame validation frame validation with the validateFrame not set to disable */
79577 + uint64_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79578 + validation with the validateFrame set to check */
79579 + uint64_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79580 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79581 + uint64_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79582 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79583 + uint64_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79584 + with validateFrame not in the strict mode and the C bit is cleared */
79585 +} t_FmMacsecSecYRxScStatistics;
79586 +
79587 +/**************************************************************************//**
79588 + @Description MACSEC SecY Tx SC Statistics
79589 +*//***************************************************************************/
79590 +typedef struct t_FmMacsecSecYTxScStatistics {
79591 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79592 + be transmitted, which were integrity protected */
79593 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79594 + be transmitted, which were confidentiality protected */
79595 +} t_FmMacsecSecYTxScStatistics;
79596 +
79597 +/**************************************************************************//**
79598 + @Description MACSEC SecY Statistics
79599 +*//***************************************************************************/
79600 +typedef struct t_FmMacsecSecYStatistics {
79601 + t_MIBStatistics mibCtrlStatistics; /**< Controlled port MIB statistics */
79602 + t_MIBStatistics mibNonCtrlStatistics; /**< Uncontrolled port MIB statistics */
79603 +/* Frame verification statistics */
79604 + uint64_t inPktsUntagged; /**< The number of received packets without the MAC security tag
79605 + (SecTAG) with validateFrames which is not in the strict mode */
79606 + uint64_t inPktsNoTag; /**< The number of received packets discarded without the
79607 + MAC security tag (SecTAG) with validateFrames which is in the strict mode */
79608 + uint64_t inPktsBadTag; /**< The number of received packets discarded with an invalid
79609 + SecTAG or a zero value PN or an invalid ICV */
79610 + uint64_t inPktsUnknownSCI; /**< The number of received packets with unknown SCI with the
79611 + condition : validateFrames is not in the strict mode and the
79612 + C bit in the SecTAG is not set */
79613 + uint64_t inPktsNoSCI; /**< The number of received packets discarded with unknown SCI
79614 + information with the condition : validateFrames is in the strict mode
79615 + or the C bit in the SecTAG is set */
79616 + uint64_t inPktsOverrun; /**< The number of packets discarded because the number of
79617 + received packets exceeded the cryptographic performance capabilities */
79618 +/* Frame validation statistics */
79619 + uint64_t inOctetsValidated; /**< The number of octets of plaintext recovered from received frames with
79620 + resolved SCI that were integrity protected but not encrypted */
79621 + uint64_t inOctetsDecrypted; /**< The number of octets of plaintext recovered from received frames with
79622 + resolved SCI that were integrity protected and encrypted */
79623 +/* Frame generation statistics */
79624 + uint64_t outPktsUntagged; /**< The number of frames, that the user of the controlled port requested to
79625 + be transmitted, with protectFrame false */
79626 + uint64_t outPktsTooLong; /**< The number of frames, that the user of the controlled port requested to
79627 + be transmitted, discarded due to length being larger than Maximum Frame Length (MACSEC_MFL) */
79628 +/* Frame protection statistics */
79629 + uint64_t outOctetsProtected; /**< The number of octets of User Data in transmitted frames that were
79630 + integrity protected but not encrypted */
79631 + uint64_t outOctetsEncrypted; /**< The number of octets of User Data in transmitted frames that were
79632 + both integrity protected and encrypted */
79633 +} t_FmMacsecSecYStatistics;
79634 +
79635 +
79636 +/**************************************************************************//**
79637 + @Description MACSEC SecY SC Params
79638 +*//***************************************************************************/
79639 +typedef struct t_FmMacsecSecYSCParams {
79640 + macsecSCI_t sci; /**< The secure channel identification of the SC */
79641 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for the SC */
79642 +} t_FmMacsecSecYSCParams;
79643 +
79644 +/**************************************************************************//**
79645 + @Group FM_MACSEC_SECY_init_grp FM-MACSEC SecY Initialization Unit
79646 +
79647 + @Description FM-MACSEC SecY Initialization Unit
79648 +
79649 + @{
79650 +*//***************************************************************************/
79651 +
79652 +/**************************************************************************//**
79653 + @Description enum for validate frames
79654 +*//***************************************************************************/
79655 +typedef enum e_FmMacsecValidFrameBehavior {
79656 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE = 0, /**< disable the validation function */
79657 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, /**< enable the validation function but only for checking
79658 + without filtering out invalid frames */
79659 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT /**< enable the validation function and also strictly filter
79660 + out those invalid frames */
79661 +} e_FmMacsecValidFrameBehavior;
79662 +
79663 +/**************************************************************************//**
79664 + @Description enum for sci insertion
79665 +*//***************************************************************************/
79666 +typedef enum e_FmMacsecSciInsertionMode {
79667 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG = 0, /**< explicit sci in the sectag */
79668 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, /**< mac sa is overwritten with the sci*/
79669 + e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP /**< implicit point-to-point sci (pre-shared) */
79670 +} e_FmMacsecSciInsertionMode;
79671 +
79672 +/**************************************************************************//**
79673 + @Description FM MACSEC SecY config input
79674 +*//***************************************************************************/
79675 +typedef struct t_FmMacsecSecYParams {
79676 + t_Handle h_FmMacsec; /**< A handle to the FM MACSEC object */
79677 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
79678 + uint32_t numReceiveChannels; /**< Number of receive channels dedicated to this SecY */
79679 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< Callback routine to be called by the driver upon SecY exception */
79680 + t_FmMacsecSecYEventsCallback *f_Event; /**< Callback routine to be called by the driver upon SecY event */
79681 + t_Handle h_App; /**< A handle to an application layer object; This handle will
79682 + be passed by the driver upon calling the above callbacks */
79683 +} t_FmMacsecSecYParams;
79684 +
79685 +/**************************************************************************//**
79686 + @Function FM_MACSEC_SECY_Config
79687 +
79688 + @Description Creates descriptor for the FM MACSEC SECY module;
79689 +
79690 + The routine returns a handle (descriptor) to the FM MACSEC SECY object;
79691 + This descriptor must be passed as first parameter to all other
79692 + FM MACSEC SECY function calls;
79693 + No actual initialization or configuration of FM MACSEC SecY hardware is
79694 + done by this routine.
79695 +
79696 + @Param[in] p_FmMacsecSecYParam Pointer to data structure of parameters.
79697 +
79698 + @Return Handle to FM MACSEC SECY object, or NULL for Failure.
79699 +*//***************************************************************************/
79700 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam);
79701 +
79702 +/**************************************************************************//**
79703 + @Function FM_MACSEC_SECY_Init
79704 +
79705 + @Description Initializes the FM MACSEC SECY module.
79706 +
79707 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79708 +
79709 + @Return E_OK on success; Error code otherwise.
79710 +*//***************************************************************************/
79711 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY);
79712 +
79713 +/**************************************************************************//**
79714 + @Function FM_MACSEC_SECY_Free
79715 +
79716 + @Description Frees all resources that were assigned to FM MACSEC SECY module.
79717 +
79718 + Calling this routine invalidates the descriptor.
79719 +
79720 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79721 +
79722 + @Return E_OK on success; Error code otherwise.
79723 +*//***************************************************************************/
79724 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY);
79725 +
79726 +/**************************************************************************//**
79727 + @Group FM_MACSEC_SECY_advanced_init_grp FM-MACSEC SecY Advanced Configuration Unit
79728 +
79729 + @Description Configuration functions used to change default values.
79730 +
79731 + @{
79732 +*//***************************************************************************/
79733 +
79734 +/**************************************************************************//**
79735 + @Function FM_MACSEC_SECY_ConfigSciInsertionMode
79736 +
79737 + @Description Calling this routine changes the SCI-insertion-mode in the
79738 + internal driver data base from its default configuration
79739 + [DEFAULT_sciInsertionMode]
79740 +
79741 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79742 + @Param[in] sciInsertionMode Sci insertion mode
79743 +
79744 + @Return E_OK on success; Error code otherwise.
79745 +
79746 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79747 +
79748 +*//***************************************************************************/
79749 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode);
79750 +
79751 +/**************************************************************************//**
79752 + @Function FM_MACSEC_SECY_ConfigProtectFrames
79753 +
79754 + @Description Calling this routine changes the protect-frame mode in the
79755 + internal driver data base from its default configuration
79756 + [DEFAULT_protectFrames]
79757 +
79758 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79759 + @Param[in] protectFrames If FALSE, frames are transmitted without modification
79760 +
79761 + @Return E_OK on success; Error code otherwise.
79762 +
79763 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79764 +
79765 +*//***************************************************************************/
79766 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames);
79767 +
79768 +/**************************************************************************//**
79769 + @Function FM_MACSEC_SECY_ConfigReplayWindow
79770 +
79771 + @Description Calling this routine changes the replay-window settings in the
79772 + internal driver data base from its default configuration
79773 + [DEFAULT_replayEnable], [DEFAULT_replayWindow]
79774 +
79775 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79776 + @Param[in] replayProtect; Replay protection function mode
79777 + @Param[in] replayWindow; The size of the replay window
79778 +
79779 + @Return E_OK on success; Error code otherwise.
79780 +
79781 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79782 +
79783 +*//***************************************************************************/
79784 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow);
79785 +
79786 +/**************************************************************************//**
79787 + @Function FM_MACSEC_SECY_ConfigValidationMode
79788 +
79789 + @Description Calling this routine changes the frame-validation-behavior mode
79790 + in the internal driver data base from its default configuration
79791 + [DEFAULT_validateFrames]
79792 +
79793 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79794 + @Param[in] validateFrames Validation function mode
79795 +
79796 + @Return E_OK on success; Error code otherwise.
79797 +
79798 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79799 +
79800 +*//***************************************************************************/
79801 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames);
79802 +
79803 +/**************************************************************************//**
79804 + @Function FM_MACSEC_SECY_ConfigConfidentiality
79805 +
79806 + @Description Calling this routine changes the confidentiality settings in the
79807 + internal driver data base from its default configuration
79808 + [DEFAULT_confidentialityEnable], [DEFAULT_confidentialityOffset]
79809 +
79810 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79811 + @Param[in] confidentialityEnable TRUE - confidentiality protection and integrity protection
79812 + FALSE - no confidentiality protection, only integrity protection
79813 + @Param[in] confidentialityOffset The number of initial octets of each MSDU without confidentiality protection
79814 + common values are 0, 30, and 50
79815 +
79816 + @Return E_OK on success; Error code otherwise.
79817 +
79818 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79819 +
79820 +*//***************************************************************************/
79821 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset);
79822 +
79823 +/**************************************************************************//**
79824 + @Function FM_MACSEC_SECY_ConfigPointToPoint
79825 +
79826 + @Description configure this SecY to work in point-to-point mode, means that
79827 + it will have only one rx sc;
79828 +
79829 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79830 +
79831 + @Return E_OK on success; Error code otherwise.
79832 +
79833 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79834 + Can be called only once in a system; only the first secY that will call this
79835 + routine will be able to operate in Point-To-Point mode.
79836 +*//***************************************************************************/
79837 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY);
79838 +
79839 +/**************************************************************************//**
79840 + @Function FM_MACSEC_SECY_ConfigException
79841 +
79842 + @Description Calling this routine changes the internal driver data base
79843 + from its default selection of exceptions enablement;
79844 + By default all exceptions are enabled.
79845 +
79846 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79847 + @Param[in] exception The exception to be selected.
79848 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79849 +
79850 + @Return E_OK on success; Error code otherwise.
79851 +
79852 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
79853 +*//***************************************************************************/
79854 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable);
79855 +
79856 +/**************************************************************************//**
79857 + @Function FM_MACSEC_SECY_ConfigEvent
79858 +
79859 + @Description Calling this routine changes the internal driver data base
79860 + from its default selection of events enablement;
79861 + By default all events are enabled.
79862 +
79863 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79864 + @Param[in] event The event to be selected.
79865 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79866 +
79867 + @Return E_OK on success; Error code otherwise.
79868 +
79869 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
79870 +*//***************************************************************************/
79871 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
79872 +
79873 +/** @} */ /* end of FM_MACSEC_SECY_advanced_init_grp group */
79874 +/** @} */ /* end of FM_MACSEC_SECY_init_grp group */
79875 +
79876 +
79877 +/**************************************************************************//**
79878 + @Group FM_MACSEC_SECY_runtime_control_grp FM-MACSEC SecY Runtime Control Unit
79879 +
79880 + @Description FM MACSEC SECY Runtime control unit API functions, definitions and enums.
79881 +
79882 + @{
79883 +*//***************************************************************************/
79884 +
79885 +/**************************************************************************//**
79886 + @Function FM_MACSEC_SECY_CreateRxSc
79887 +
79888 + @Description Create a receive secure channel.
79889 +
79890 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79891 + @Param[in] scParams secure channel params.
79892 +
79893 + @Return E_OK on success; Error code otherwise.
79894 +
79895 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79896 +*//***************************************************************************/
79897 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams);
79898 +
79899 +/**************************************************************************//**
79900 + @Function FM_MACSEC_SECY_DeleteRxSc
79901 +
79902 + @Description Deleting an initialized secure channel.
79903 +
79904 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79905 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79906 +
79907 + @Return E_OK on success; Error code otherwise.
79908 +
79909 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
79910 +*//***************************************************************************/
79911 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc);
79912 +
79913 +/**************************************************************************//**
79914 + @Function FM_MACSEC_SECY_CreateRxSa
79915 +
79916 + @Description Create a receive secure association for the secure channel;
79917 + the SA cannot be used to receive frames until FM_MACSEC_SECY_RxSaEnableReceive is called.
79918 +
79919 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79920 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79921 + @Param[in] an association number represent the SA.
79922 + @Param[in] lowestPn the lowest acceptable PN value for a received frame.
79923 + @Param[in] key the desired key for this SA.
79924 +
79925 + @Return E_OK on success; Error code otherwise.
79926 +
79927 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
79928 +*//***************************************************************************/
79929 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
79930 +
79931 +/**************************************************************************//**
79932 + @Function FM_MACSEC_SECY_DeleteRxSa
79933 +
79934 + @Description Deleting an initialized secure association.
79935 +
79936 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79937 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79938 + @Param[in] an association number represent the SA.
79939 +
79940 + @Return E_OK on success; Error code otherwise.
79941 +
79942 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79943 +*//***************************************************************************/
79944 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
79945 +
79946 +/**************************************************************************//**
79947 + @Function FM_MACSEC_SECY_RxSaEnableReceive
79948 +
79949 + @Description Enabling the SA to receive frames.
79950 +
79951 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79952 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79953 + @Param[in] an association number represent the SA.
79954 +
79955 + @Return E_OK on success; Error code otherwise.
79956 +
79957 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
79958 +*//***************************************************************************/
79959 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
79960 +
79961 +/**************************************************************************//**
79962 + @Function FM_MACSEC_SECY_RxSaDisableReceive
79963 +
79964 + @Description Disabling the SA from receive frames.
79965 +
79966 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79967 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79968 + @Param[in] an association number represent the SA.
79969 +
79970 + @Return E_OK on success; Error code otherwise.
79971 +
79972 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
79973 +*//***************************************************************************/
79974 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
79975 +
79976 +/**************************************************************************//**
79977 + @Function FM_MACSEC_SECY_RxSaUpdateNextPn
79978 +
79979 + @Description Update the next packet number expected on RX;
79980 + The value of nextPN shall be set to the greater of its existing value and the
79981 + supplied of updtNextPN (802.1AE-2006 10.7.15).
79982 +
79983 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79984 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79985 + @Param[in] an association number represent the SA.
79986 + @Param[in] updtNextPN the next PN value for a received frame.
79987 +
79988 + @Return E_OK on success; Error code otherwise.
79989 +
79990 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
79991 +*//***************************************************************************/
79992 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN);
79993 +
79994 +/**************************************************************************//**
79995 + @Function FM_MACSEC_SECY_RxSaUpdateLowestPn
79996 +
79997 + @Description Update the lowest packet number expected on RX;
79998 + The value of lowestPN shall be set to the greater of its existing value and the
79999 + supplied of updtLowestPN (802.1AE-2006 10.7.15).
80000 +
80001 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80002 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80003 + @Param[in] an association number represent the SA.
80004 + @Param[in] updtLowestPN the lowest PN acceptable value for a received frame.
80005 +
80006 + @Return E_OK on success; Error code otherwise.
80007 +
80008 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80009 +*//***************************************************************************/
80010 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN);
80011 +
80012 +/**************************************************************************//**
80013 + @Function FM_MACSEC_SECY_RxSaModifyKey
80014 +
80015 + @Description Modify the current key of the SA with a new one.
80016 +
80017 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80018 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80019 + @Param[in] an association number represent the SA.
80020 + @Param[in] key new key to replace the current key.
80021 +
80022 + @Return E_OK on success; Error code otherwise.
80023 +
80024 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80025 +*//***************************************************************************/
80026 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key);
80027 +
80028 +/**************************************************************************//**
80029 + @Function FM_MACSEC_SECY_CreateTxSa
80030 +
80031 + @Description Create a transmit secure association for the secure channel;
80032 + the SA cannot be used to transmit frames until FM_MACSEC_SECY_TxSaSetActivate is called;
80033 + Only one SA can be active at a time.
80034 +
80035 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80036 + @Param[in] an association number represent the SA.
80037 + @Param[in] key the desired key for this SA.
80038 +
80039 + @Return E_OK on success; Error code otherwise.
80040 +
80041 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80042 +*//***************************************************************************/
80043 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key);
80044 +
80045 +/**************************************************************************//**
80046 + @Function FM_MACSEC_SECY_DeleteTxSa
80047 +
80048 + @Description Deleting an initialized secure association.
80049 +
80050 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80051 + @Param[in] an association number represent the SA.
80052 +
80053 + @Return E_OK on success; Error code otherwise.
80054 +
80055 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80056 +*//***************************************************************************/
80057 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an);
80058 +
80059 +/**************************************************************************//**
80060 + @Function FM_MACSEC_SECY_TxSaModifyKey
80061 +
80062 + @Description Modify the key of the inactive SA with a new one.
80063 +
80064 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80065 + @Param[in] nextActiveAn association number represent the next SA to be activated.
80066 + @Param[in] key new key to replace the current key.
80067 +
80068 + @Return E_OK on success; Error code otherwise.
80069 +
80070 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80071 +*//***************************************************************************/
80072 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key);
80073 +
80074 +/**************************************************************************//**
80075 + @Function FM_MACSEC_SECY_TxSaSetActive
80076 +
80077 + @Description Set this SA to the active SA to be used on TX for SC;
80078 + only one SA can be active at a time.
80079 +
80080 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80081 + @Param[in] an association number represent the SA.
80082 +
80083 + @Return E_OK on success; Error code otherwise.
80084 +
80085 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80086 +*//***************************************************************************/
80087 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an);
80088 +
80089 +/**************************************************************************//**
80090 + @Function FM_MACSEC_SECY_TxSaGetActive
80091 +
80092 + @Description Get the active SA that being used for TX.
80093 +
80094 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80095 + @Param[out] p_An the active an.
80096 +
80097 + @Return E_OK on success; Error code otherwise.
80098 +
80099 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80100 +*//***************************************************************************/
80101 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An);
80102 +
80103 +/**************************************************************************//**
80104 + @Function FM_MACSEC_SECY_GetStatistics
80105 +
80106 + @Description get all statistics counters.
80107 +
80108 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80109 + @Param[in] p_Statistics Structure with statistics.
80110 +
80111 + @Return E_OK on success; Error code otherwise.
80112 +
80113 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80114 +*//***************************************************************************/
80115 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics);
80116 +
80117 +/**************************************************************************//**
80118 + @Function FM_MACSEC_SECY_RxScGetStatistics
80119 +
80120 + @Description get all statistics counters.
80121 +
80122 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80123 + @Param[in] h_Sc Rx Sc handle.
80124 + @Param[in] p_Statistics Structure with statistics.
80125 +
80126 + @Return E_OK on success; Error code otherwise.
80127 +
80128 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80129 +*//***************************************************************************/
80130 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics);
80131 +
80132 +/**************************************************************************//**
80133 + @Function FM_MACSEC_SECY_RxSaGetStatistics
80134 +
80135 + @Description get all statistics counters
80136 +
80137 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80138 + @Param[in] h_Sc Rx Sc handle.
80139 + @Param[in] an association number represent the SA.
80140 + @Param[in] p_Statistics Structure with statistics.
80141 +
80142 + @Return E_OK on success; Error code otherwise.
80143 +
80144 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80145 +*//***************************************************************************/
80146 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics);
80147 +
80148 +/**************************************************************************//**
80149 + @Function FM_MACSEC_SECY_TxScGetStatistics
80150 +
80151 + @Description get all statistics counters.
80152 +
80153 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80154 + @Param[in] p_Statistics Structure with statistics.
80155 +
80156 + @Return E_OK on success; Error code otherwise.
80157 +
80158 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80159 +*//***************************************************************************/
80160 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics);
80161 +
80162 +/**************************************************************************//**
80163 + @Function FM_MACSEC_SECY_TxSaGetStatistics
80164 +
80165 + @Description get all statistics counters.
80166 +
80167 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80168 + @Param[in] an association number represent the SA.
80169 + @Param[in] p_Statistics Structure with statistics.
80170 +
80171 + @Return E_OK on success; Error code otherwise.
80172 +
80173 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80174 +*//***************************************************************************/
80175 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics);
80176 +
80177 +/**************************************************************************//**
80178 + @Function FM_MACSEC_SECY_SetException
80179 +
80180 + @Description Calling this routine enables/disables the specified exception.
80181 +
80182 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80183 + @Param[in] exception The exception to be selected.
80184 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80185 +
80186 + @Return E_OK on success; Error code otherwise.
80187 +
80188 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80189 +*//***************************************************************************/
80190 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable);
80191 +
80192 +/**************************************************************************//**
80193 + @Function FM_MACSEC_SECY_SetEvent
80194 +
80195 + @Description Calling this routine enables/disables the specified event.
80196 +
80197 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80198 + @Param[in] event The event to be selected.
80199 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80200 +
80201 + @Return E_OK on success; Error code otherwise.
80202 +
80203 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80204 +*//***************************************************************************/
80205 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
80206 +
80207 +/**************************************************************************//**
80208 + @Function FM_MACSEC_SECY_GetRxScPhysId
80209 +
80210 + @Description return the physical id of the Secure Channel.
80211 +
80212 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80213 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80214 + @Param[out] p_ScPhysId the SC physical id.
80215 +
80216 + @Return E_OK on success; Error code otherwise.
80217 +
80218 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
80219 +*//***************************************************************************/
80220 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId);
80221 +
80222 +/**************************************************************************//**
80223 + @Function FM_MACSEC_SECY_GetTxScPhysId
80224 +
80225 + @Description return the physical id of the Secure Channel.
80226 +
80227 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80228 + @Param[out] p_ScPhysId the SC physical id.
80229 +
80230 + @Return E_OK on success; Error code otherwise.
80231 +
80232 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80233 +*//***************************************************************************/
80234 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId);
80235 +
80236 +/** @} */ /* end of FM_MACSEC_SECY_runtime_control_grp group */
80237 +/** @} */ /* end of FM_MACSEC_SECY_grp group */
80238 +/** @} */ /* end of FM_MACSEC_grp group */
80239 +/** @} */ /* end of FM_grp group */
80240 +
80241 +
80242 +#endif /* __FM_MACSEC_EXT_H */
80243 --- /dev/null
80244 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
80245 @@ -0,0 +1,170 @@
80246 +/*
80247 + * Copyright 2008-2012 Freescale Semiconductor Inc.
80248 + *
80249 + * Redistribution and use in source and binary forms, with or without
80250 + * modification, are permitted provided that the following conditions are met:
80251 + * * Redistributions of source code must retain the above copyright
80252 + * notice, this list of conditions and the following disclaimer.
80253 + * * Redistributions in binary form must reproduce the above copyright
80254 + * notice, this list of conditions and the following disclaimer in the
80255 + * documentation and/or other materials provided with the distribution.
80256 + * * Neither the name of Freescale Semiconductor nor the
80257 + * names of its contributors may be used to endorse or promote products
80258 + * derived from this software without specific prior written permission.
80259 + *
80260 + *
80261 + * ALTERNATIVELY, this software may be distributed under the terms of the
80262 + * GNU General Public License ("GPL") as published by the Free Software
80263 + * Foundation, either version 2 of that License or (at your option) any
80264 + * later version.
80265 + *
80266 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80267 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80268 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80269 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80270 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80271 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80272 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80273 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80274 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80275 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80276 + */
80277 +
80278 +
80279 +/**************************************************************************//**
80280 + @File fm_muram_ext.h
80281 +
80282 + @Description FM MURAM Application Programming Interface.
80283 +*//***************************************************************************/
80284 +#ifndef __FM_MURAM_EXT
80285 +#define __FM_MURAM_EXT
80286 +
80287 +#include "error_ext.h"
80288 +#include "std_ext.h"
80289 +
80290 +
80291 +/**************************************************************************//**
80292 +
80293 + @Group FM_grp Frame Manager API
80294 +
80295 + @Description FM API functions, definitions and enums
80296 +
80297 + @{
80298 +*//***************************************************************************/
80299 +
80300 +/**************************************************************************//**
80301 + @Group FM_muram_grp FM MURAM
80302 +
80303 + @Description FM MURAM API functions, definitions and enums
80304 +
80305 + @{
80306 +*//***************************************************************************/
80307 +
80308 +/**************************************************************************//**
80309 + @Group FM_muram_init_grp FM MURAM Initialization Unit
80310 +
80311 + @Description FM MURAM initialization API functions, definitions and enums
80312 +
80313 + @{
80314 +*//***************************************************************************/
80315 +
80316 +/**************************************************************************//**
80317 + @Function FM_MURAM_ConfigAndInit
80318 +
80319 + @Description Creates partition in the MURAM.
80320 +
80321 + The routine returns a handle (descriptor) to the MURAM partition.
80322 + This descriptor must be passed as first parameter to all other
80323 + FM-MURAM function calls.
80324 +
80325 + No actual initialization or configuration of FM_MURAM hardware is
80326 + done by this routine.
80327 +
80328 + @Param[in] baseAddress - Pointer to base of memory mapped FM-MURAM.
80329 + @Param[in] size - Size of the FM-MURAM partition.
80330 +
80331 + @Return Handle to FM-MURAM object, or NULL for Failure.
80332 +*//***************************************************************************/
80333 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size);
80334 +
80335 +/**************************************************************************//**
80336 + @Function FM_MURAM_Free
80337 +
80338 + @Description Frees all resources that were assigned to FM-MURAM module.
80339 +
80340 + Calling this routine invalidates the descriptor.
80341 +
80342 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80343 +
80344 + @Return E_OK on success; Error code otherwise.
80345 +*//***************************************************************************/
80346 +t_Error FM_MURAM_Free(t_Handle h_FmMuram);
80347 +
80348 +/** @} */ /* end of FM_muram_init_grp group */
80349 +
80350 +
80351 +/**************************************************************************//**
80352 + @Group FM_muram_ctrl_grp FM MURAM Control Unit
80353 +
80354 + @Description FM MURAM control API functions, definitions and enums
80355 +
80356 + @{
80357 +*//***************************************************************************/
80358 +
80359 +/**************************************************************************//**
80360 + @Function FM_MURAM_AllocMem
80361 +
80362 + @Description Allocate some memory from FM-MURAM partition.
80363 +
80364 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80365 + @Param[in] size - size of the memory to be allocated.
80366 + @Param[in] align - Alignment of the memory.
80367 +
80368 + @Return address of the allocated memory; NULL otherwise.
80369 +*//***************************************************************************/
80370 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align);
80371 +
80372 +/**************************************************************************//**
80373 + @Function FM_MURAM_AllocMemForce
80374 +
80375 + @Description Allocate some specific memory from FM-MURAM partition (according
80376 + to base).
80377 +
80378 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80379 + @Param[in] base - the desired base-address to be allocated.
80380 + @Param[in] size - size of the memory to be allocated.
80381 +
80382 + @Return address of the allocated memory; NULL otherwise.
80383 +*//***************************************************************************/
80384 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size);
80385 +
80386 +/**************************************************************************//**
80387 + @Function FM_MURAM_FreeMem
80388 +
80389 + @Description Free an allocated memory from FM-MURAM partition.
80390 +
80391 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80392 + @Param[in] ptr - A pointer to an allocated memory.
80393 +
80394 + @Return E_OK on success; Error code otherwise.
80395 +*//***************************************************************************/
80396 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr);
80397 +
80398 +/**************************************************************************//**
80399 + @Function FM_MURAM_GetFreeMemSize
80400 +
80401 + @Description Returns the size (in bytes) of free MURAM memory.
80402 +
80403 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80404 +
80405 + @Return Free MURAM memory size in bytes.
80406 +*//***************************************************************************/
80407 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram);
80408 +
80409 +/** @} */ /* end of FM_muram_ctrl_grp group */
80410 +/** @} */ /* end of FM_muram_grp group */
80411 +/** @} */ /* end of FM_grp group */
80412 +
80413 +
80414 +
80415 +#endif /* __FM_MURAM_EXT */
80416 --- /dev/null
80417 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
80418 @@ -0,0 +1,3974 @@
80419 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
80420 + * All rights reserved.
80421 + *
80422 + * Redistribution and use in source and binary forms, with or without
80423 + * modification, are permitted provided that the following conditions are met:
80424 + * * Redistributions of source code must retain the above copyright
80425 + * notice, this list of conditions and the following disclaimer.
80426 + * * Redistributions in binary form must reproduce the above copyright
80427 + * notice, this list of conditions and the following disclaimer in the
80428 + * documentation and/or other materials provided with the distribution.
80429 + * * Neither the name of Freescale Semiconductor nor the
80430 + * names of its contributors may be used to endorse or promote products
80431 + * derived from this software without specific prior written permission.
80432 + *
80433 + *
80434 + * ALTERNATIVELY, this software may be distributed under the terms of the
80435 + * GNU General Public License ("GPL") as published by the Free Software
80436 + * Foundation, either version 2 of that License or (at your option) any
80437 + * later version.
80438 + *
80439 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80440 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80441 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80442 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80443 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80444 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80445 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80446 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80447 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80448 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80449 + */
80450 +
80451 +
80452 +/**************************************************************************//**
80453 + @File fm_pcd_ext.h
80454 +
80455 + @Description FM PCD API definitions
80456 +*//***************************************************************************/
80457 +#ifndef __FM_PCD_EXT
80458 +#define __FM_PCD_EXT
80459 +
80460 +#include "std_ext.h"
80461 +#include "net_ext.h"
80462 +#include "list_ext.h"
80463 +#include "fm_ext.h"
80464 +#include "fsl_fman_kg.h"
80465 +
80466 +
80467 +/**************************************************************************//**
80468 + @Group FM_grp Frame Manager API
80469 +
80470 + @Description Frame Manager Application Programming Interface
80471 +
80472 + @{
80473 +*//***************************************************************************/
80474 +
80475 +/**************************************************************************//**
80476 + @Group FM_PCD_grp FM PCD
80477 +
80478 + @Description Frame Manager PCD (Parse-Classify-Distribute) API.
80479 +
80480 + The FM PCD module is responsible for the initialization of all
80481 + global classifying FM modules. This includes the parser general and
80482 + common registers, the key generator global and common registers,
80483 + and the policer global and common registers.
80484 + In addition, the FM PCD SW module will initialize all required
80485 + key generator schemes, coarse classification flows, and policer
80486 + profiles. When FM module is configured to work with one of these
80487 + entities, it will register to it using the FM PORT API. The PCD
80488 + module will manage the PCD resources - i.e. resource management of
80489 + KeyGen schemes, etc.
80490 +
80491 + @{
80492 +*//***************************************************************************/
80493 +
80494 +/**************************************************************************//**
80495 + @Collection General PCD defines
80496 +*//***************************************************************************/
80497 +#define FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
80498 +
80499 +#define FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
80500 +#define FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
80501 + /**< Number of distinction units is limited by
80502 + register size (32 bits) minus reserved bits
80503 + for private headers. */
80504 +#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
80505 + in a distinction unit */
80506 +#define FM_PCD_KG_NUM_OF_GENERIC_REGS FM_KG_NUM_OF_GENERIC_REGS /**< Total number of generic KeyGen registers */
80507 +#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
80508 + For HW implementation reasons, in most
80509 + cases less than this will be allowed; The
80510 + driver will return an initialization error
80511 + if resource is unavailable. */
80512 +#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
80513 +#define FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
80514 +
80515 +#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
80516 +#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)
80517 + /**< Maximum size of SW parser code */
80518 +
80519 +#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
80520 + insert manipulation */
80521 +
80522 +#if (DPAA_VERSION >= 11)
80523 +#define FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
80524 +#endif /* (DPAA_VERSION >= 11) */
80525 +/* @} */
80526 +
80527 +
80528 +/**************************************************************************//**
80529 + @Group FM_PCD_init_grp FM PCD Initialization Unit
80530 +
80531 + @Description Frame Manager PCD Initialization Unit API
80532 +
80533 + @{
80534 +*//***************************************************************************/
80535 +
80536 +/**************************************************************************//**
80537 + @Description PCD counters
80538 +*//***************************************************************************/
80539 +typedef enum e_FmPcdCounters {
80540 + e_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
80541 + e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
80542 + e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
80543 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
80544 + This is a subset of e_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
80545 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
80546 + This is a subset of e_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
80547 + e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
80548 + e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
80549 + e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
80550 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
80551 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
80552 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
80553 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
80554 + 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. */
80555 + 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. */
80556 + 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. */
80557 + 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. */
80558 + e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
80559 + 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. */
80560 + 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). */
80561 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
80562 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
80563 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
80564 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
80565 + e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
80566 +} e_FmPcdCounters;
80567 +
80568 +/**************************************************************************//**
80569 + @Description PCD interrupts
80570 +*//***************************************************************************/
80571 +typedef enum e_FmPcdExceptions {
80572 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
80573 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
80574 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
80575 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
80576 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
80577 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
80578 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
80579 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
80580 +} e_FmPcdExceptions;
80581 +
80582 +
80583 +/**************************************************************************//**
80584 + @Description Exceptions user callback routine, will be called upon an
80585 + exception passing the exception identification.
80586 +
80587 + @Param[in] h_App - User's application descriptor.
80588 + @Param[in] exception - The exception.
80589 + *//***************************************************************************/
80590 +typedef void (t_FmPcdExceptionCallback) (t_Handle h_App, e_FmPcdExceptions exception);
80591 +
80592 +/**************************************************************************//**
80593 + @Description Exceptions user callback routine, will be called upon an exception
80594 + passing the exception identification.
80595 +
80596 + @Param[in] h_App - User's application descriptor.
80597 + @Param[in] exception - The exception.
80598 + @Param[in] index - id of the relevant source (may be scheme or profile id).
80599 + *//***************************************************************************/
80600 +typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App,
80601 + e_FmPcdExceptions exception,
80602 + uint16_t index);
80603 +
80604 +/**************************************************************************//**
80605 + @Description A callback for enqueuing frame onto a QM queue.
80606 +
80607 + @Param[in] h_QmArg - Application's handle passed to QM module on enqueue.
80608 + @Param[in] p_Fd - Frame descriptor for the frame.
80609 +
80610 + @Return E_OK on success; Error code otherwise.
80611 + *//***************************************************************************/
80612 +typedef t_Error (t_FmPcdQmEnqueueCallback) (t_Handle h_QmArg, void *p_Fd);
80613 +
80614 +/**************************************************************************//**
80615 + @Description Host-Command parameters structure.
80616 +
80617 + When using Host command for PCD functionalities, a dedicated port
80618 + must be used. If this routine is called for a PCD in a single partition
80619 + environment, or it is the Master partition in a Multi-partition
80620 + environment, The port will be initialized by the PCD driver
80621 + initialization routine.
80622 + *//***************************************************************************/
80623 +typedef struct t_FmPcdHcParams {
80624 + uintptr_t portBaseAddr; /**< Virtual Address of Host-Command Port memory mapped registers.*/
80625 + uint8_t portId; /**< Port Id (0-6 relative to Host-Command/Offline-Parsing ports);
80626 + NOTE: When configuring Host Command port for
80627 + FMANv3 devices (DPAA_VERSION 11 and higher),
80628 + portId=0 MUST be used. */
80629 + uint16_t liodnBase; /**< LIODN base for this port, to be used together with LIODN offset
80630 + (irrelevant for P4080 revision 1.0) */
80631 + uint32_t errFqid; /**< Host-Command Port error queue Id. */
80632 + uint32_t confFqid; /**< Host-Command Port confirmation queue Id. */
80633 + uint32_t qmChannel; /**< QM channel dedicated to this Host-Command port;
80634 + will be used by the FM for dequeue. */
80635 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Callback routine for enqueuing a frame to the QM */
80636 + t_Handle h_QmArg; /**< Application's handle passed to QM module on enqueue */
80637 +} t_FmPcdHcParams;
80638 +
80639 +/**************************************************************************//**
80640 + @Description The main structure for PCD initialization
80641 + *//***************************************************************************/
80642 +typedef struct t_FmPcdParams {
80643 + bool prsSupport; /**< TRUE if Parser will be used for any of the FM ports. */
80644 + bool ccSupport; /**< TRUE if Coarse Classification will be used for any
80645 + of the FM ports. */
80646 + bool kgSupport; /**< TRUE if KeyGen will be used for any of the FM ports. */
80647 + bool plcrSupport; /**< TRUE if Policer will be used for any of the FM ports. */
80648 + t_Handle h_Fm; /**< A handle to the FM module. */
80649 + uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition.
80650 + this parameter is relevant if 'kgSupport'=TRUE. */
80651 + bool useHostCommand; /**< Optional for single partition, Mandatory for Multi partition */
80652 + t_FmPcdHcParams hc; /**< Host Command parameters, relevant only if 'useHostCommand'=TRUE;
80653 + Relevant when FM not runs in "guest-mode". */
80654 +
80655 + t_FmPcdExceptionCallback *f_Exception; /**< Callback routine for general PCD exceptions;
80656 + Relevant when FM not runs in "guest-mode". */
80657 + t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Callback routine for specific KeyGen scheme or
80658 + Policer profile exceptions;
80659 + Relevant when FM not runs in "guest-mode". */
80660 + t_Handle h_App; /**< A handle to an application layer object; This handle will
80661 + be passed by the driver upon calling the above callbacks;
80662 + Relevant when FM not runs in "guest-mode". */
80663 + uint8_t partPlcrProfilesBase; /**< The first policer-profile-id dedicated to this partition.
80664 + this parameter is relevant if 'plcrSupport'=TRUE.
80665 + NOTE: this parameter relevant only when working with multiple partitions. */
80666 + uint16_t partNumOfPlcrProfiles; /**< Number of policer-profiles dedicated to this partition.
80667 + this parameter is relevant if 'plcrSupport'=TRUE.
80668 + NOTE: this parameter relevant only when working with multiple partitions. */
80669 +} t_FmPcdParams;
80670 +
80671 +
80672 +/**************************************************************************//**
80673 + @Function FM_PCD_Config
80674 +
80675 + @Description Basic configuration of the PCD module.
80676 + Creates descriptor for the FM PCD module.
80677 +
80678 + @Param[in] p_FmPcdParams A structure of parameters for the initialization of PCD.
80679 +
80680 + @Return A handle to the initialized module.
80681 +*//***************************************************************************/
80682 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams);
80683 +
80684 +/**************************************************************************//**
80685 + @Function FM_PCD_Init
80686 +
80687 + @Description Initialization of the PCD module.
80688 +
80689 + @Param[in] h_FmPcd - FM PCD module descriptor.
80690 +
80691 + @Return E_OK on success; Error code otherwise.
80692 +*//***************************************************************************/
80693 +t_Error FM_PCD_Init(t_Handle h_FmPcd);
80694 +
80695 +/**************************************************************************//**
80696 + @Function FM_PCD_Free
80697 +
80698 + @Description Frees all resources that were assigned to FM module.
80699 +
80700 + Calling this routine invalidates the descriptor.
80701 +
80702 + @Param[in] h_FmPcd - FM PCD module descriptor.
80703 +
80704 + @Return E_OK on success; Error code otherwise.
80705 +*//***************************************************************************/
80706 +t_Error FM_PCD_Free(t_Handle h_FmPcd);
80707 +
80708 +/**************************************************************************//**
80709 + @Group FM_PCD_advanced_cfg_grp FM PCD Advanced Configuration Unit
80710 +
80711 + @Description Frame Manager PCD Advanced Configuration API.
80712 +
80713 + @{
80714 +*//***************************************************************************/
80715 +
80716 +/**************************************************************************//**
80717 + @Function FM_PCD_ConfigException
80718 +
80719 + @Description Calling this routine changes the internal driver data base
80720 + from its default selection of exceptions enabling.
80721 + [DEFAULT_numOfSharedPlcrProfiles].
80722 +
80723 + @Param[in] h_FmPcd FM PCD module descriptor.
80724 + @Param[in] exception The exception to be selected.
80725 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80726 +
80727 + @Return E_OK on success; Error code otherwise.
80728 +
80729 + @Cautions This routine should NOT be called from guest-partition
80730 + (i.e. guestId != NCSW_MASTER_ID)
80731 +*//***************************************************************************/
80732 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
80733 +
80734 +/**************************************************************************//**
80735 + @Function FM_PCD_ConfigHcFramesDataMemory
80736 +
80737 + @Description Configures memory-partition-id for FMan-Controller Host-Command
80738 + frames. Calling this routine changes the internal driver data
80739 + base from its default configuration [0].
80740 +
80741 + @Param[in] h_FmPcd FM PCD module descriptor.
80742 + @Param[in] memId Memory partition ID.
80743 +
80744 + @Return E_OK on success; Error code otherwise.
80745 +
80746 + @Cautions This routine may be called only if 'useHostCommand' was TRUE
80747 + when FM_PCD_Config() routine was called.
80748 +*//***************************************************************************/
80749 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId);
80750 +
80751 +/**************************************************************************//**
80752 + @Function FM_PCD_ConfigPlcrNumOfSharedProfiles
80753 +
80754 + @Description Calling this routine changes the internal driver data base
80755 + from its default selection of exceptions enablement.
80756 + [DEFAULT_numOfSharedPlcrProfiles].
80757 +
80758 + @Param[in] h_FmPcd FM PCD module descriptor.
80759 + @Param[in] numOfSharedPlcrProfiles Number of profiles to
80760 + be shared between ports on this partition
80761 +
80762 + @Return E_OK on success; Error code otherwise.
80763 +*//***************************************************************************/
80764 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles);
80765 +
80766 +/**************************************************************************//**
80767 + @Function FM_PCD_ConfigPlcrAutoRefreshMode
80768 +
80769 + @Description Calling this routine changes the internal driver data base
80770 + from its default selection of exceptions enablement.
80771 + By default auto-refresh is [DEFAULT_plcrAutoRefresh].
80772 +
80773 + @Param[in] h_FmPcd FM PCD module descriptor.
80774 + @Param[in] enable TRUE to enable, FALSE to disable
80775 +
80776 + @Return E_OK on success; Error code otherwise.
80777 +
80778 + @Cautions This routine should NOT be called from guest-partition
80779 + (i.e. guestId != NCSW_MASTER_ID)
80780 +*//***************************************************************************/
80781 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable);
80782 +
80783 +/**************************************************************************//**
80784 + @Function FM_PCD_ConfigPrsMaxCycleLimit
80785 +
80786 + @Description Calling this routine changes the internal data structure for
80787 + the maximum parsing time from its default value
80788 + [DEFAULT_MAX_PRS_CYC_LIM].
80789 +
80790 + @Param[in] h_FmPcd FM PCD module descriptor.
80791 + @Param[in] value 0 to disable the mechanism, or new
80792 + maximum parsing time.
80793 +
80794 + @Return E_OK on success; Error code otherwise.
80795 +
80796 + @Cautions This routine should NOT be called from guest-partition
80797 + (i.e. guestId != NCSW_MASTER_ID)
80798 +*//***************************************************************************/
80799 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value);
80800 +
80801 +/** @} */ /* end of FM_PCD_advanced_cfg_grp group */
80802 +/** @} */ /* end of FM_PCD_init_grp group */
80803 +
80804 +
80805 +/**************************************************************************//**
80806 + @Group FM_PCD_Runtime_grp FM PCD Runtime Unit
80807 +
80808 + @Description Frame Manager PCD Runtime Unit API
80809 +
80810 + The runtime control allows creation of PCD infrastructure modules
80811 + such as Network Environment Characteristics, Classification Plan
80812 + Groups and Coarse Classification Trees.
80813 + It also allows on-the-fly initialization, modification and removal
80814 + of PCD modules such as KeyGen schemes, coarse classification nodes
80815 + and Policer profiles.
80816 +
80817 + In order to explain the programming model of the PCD driver interface
80818 + a few terms should be explained, and will be used below.
80819 + - Distinction Header - One of the 16 protocols supported by the FM parser,
80820 + or one of the SHIM headers (1 or 2). May be a header with a special
80821 + option (see below).
80822 + - Interchangeable Headers Group - This is a group of Headers recognized
80823 + by either one of them. For example, if in a specific context the user
80824 + chooses to treat IPv4 and IPV6 in the same way, they may create an
80825 + interchangeable Headers Unit consisting of these 2 headers.
80826 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
80827 + Group.
80828 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
80829 + IPv6, includes multicast, broadcast and other protocol specific options.
80830 + In terms of hardware it relates to the options available in the classification
80831 + plan.
80832 + - Network Environment Characteristics - a set of Distinction Units that define
80833 + the total recognizable header selection for a certain environment. This is
80834 + NOT the list of all headers that will ever appear in a flow, but rather
80835 + everything that needs distinction in a flow, where distinction is made by KeyGen
80836 + schemes and coarse classification action descriptors.
80837 +
80838 + The PCD runtime modules initialization is done in stages. The first stage after
80839 + initializing the PCD module itself is to establish a Network Flows Environment
80840 + Definition. The application may choose to establish one or more such environments.
80841 + Later, when needed, the application will have to state, for some of its modules,
80842 + to which single environment it belongs.
80843 +
80844 + @{
80845 +*//***************************************************************************/
80846 +
80847 +/**************************************************************************//**
80848 + @Description A structure for SW parser labels
80849 + *//***************************************************************************/
80850 +typedef struct t_FmPcdPrsLabelParams {
80851 + uint32_t instructionOffset; /**< SW parser label instruction offset (2 bytes
80852 + resolution), relative to Parser RAM. */
80853 + e_NetHeaderType hdr; /**< The existence of this header will invoke
80854 + the SW parser code; Use HEADER_TYPE_NONE
80855 + to indicate that sw parser is to run
80856 + independent of the existence of any protocol
80857 + (run before HW parser). */
80858 + uint8_t indexPerHdr; /**< Normally 0, if more than one SW parser
80859 + attachments for the same header, use this
80860 + index to distinguish between them. */
80861 +} t_FmPcdPrsLabelParams;
80862 +
80863 +/**************************************************************************//**
80864 + @Description A structure for SW parser
80865 + *//***************************************************************************/
80866 +typedef struct t_FmPcdPrsSwParams {
80867 + bool override; /**< FALSE to invoke a check that nothing else
80868 + was loaded to this address, including
80869 + internal patches.
80870 + TRUE to override any existing code.*/
80871 + uint32_t size; /**< SW parser code size */
80872 + uint16_t base; /**< SW parser base (in instruction counts!
80873 + must be larger than 0x20)*/
80874 + uint8_t *p_Code; /**< SW parser code */
80875 + uint32_t swPrsDataParams[FM_PCD_PRS_NUM_OF_HDRS];
80876 + /**< SW parser data (parameters) */
80877 + uint8_t numOfLabels; /**< Number of labels for SW parser. */
80878 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
80879 + /**< SW parser labels table, containing
80880 + numOfLabels entries */
80881 +} t_FmPcdPrsSwParams;
80882 +
80883 +
80884 +/**************************************************************************//**
80885 + @Function FM_PCD_Enable
80886 +
80887 + @Description This routine should be called after PCD is initialized for enabling all
80888 + PCD engines according to their existing configuration.
80889 +
80890 + @Param[in] h_FmPcd FM PCD module descriptor.
80891 +
80892 + @Return E_OK on success; Error code otherwise.
80893 +
80894 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80895 +*//***************************************************************************/
80896 +t_Error FM_PCD_Enable(t_Handle h_FmPcd);
80897 +
80898 +/**************************************************************************//**
80899 + @Function FM_PCD_Disable
80900 +
80901 + @Description This routine may be called when PCD is enabled in order to
80902 + disable all PCD engines. It may be called
80903 + only when none of the ports in the system are using the PCD.
80904 +
80905 + @Param[in] h_FmPcd FM PCD module descriptor.
80906 +
80907 + @Return E_OK on success; Error code otherwise.
80908 +
80909 + @Cautions Allowed only following FM_PCD_Init() and when PCD is enabled.
80910 +*//***************************************************************************/
80911 +t_Error FM_PCD_Disable(t_Handle h_FmPcd);
80912 +
80913 +/**************************************************************************//**
80914 + @Function FM_PCD_GetCounter
80915 +
80916 + @Description Reads one of the FM PCD counters.
80917 +
80918 + @Param[in] h_FmPcd FM PCD module descriptor.
80919 + @Param[in] counter The requested counter.
80920 +
80921 + @Return Counter's current value.
80922 +
80923 + @Cautions Allowed only following FM_PCD_Init().
80924 + Note that it is user's responsibility to call this routine only
80925 + for enabled counters, and there will be no indication if a
80926 + disabled counter is accessed.
80927 +*//***************************************************************************/
80928 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter);
80929 +
80930 +/**************************************************************************//**
80931 +@Function FM_PCD_PrsLoadSw
80932 +
80933 +@Description This routine may be called in order to load software parsing code.
80934 +
80935 +
80936 +@Param[in] h_FmPcd FM PCD module descriptor.
80937 +@Param[in] p_SwPrs A pointer to a structure of software
80938 + parser parameters, including the software
80939 + parser image.
80940 +
80941 +@Return E_OK on success; Error code otherwise.
80942 +
80943 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80944 + This routine should NOT be called from guest-partition
80945 + (i.e. guestId != NCSW_MASTER_ID)
80946 +*//***************************************************************************/
80947 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs);
80948 +
80949 +/**************************************************************************//**
80950 +@Function FM_PCD_SetAdvancedOffloadSupport
80951 +
80952 +@Description This routine must be called in order to support the following features:
80953 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
80954 +
80955 +@Param[in] h_FmPcd FM PCD module descriptor.
80956 +
80957 +@Return E_OK on success; Error code otherwise.
80958 +
80959 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80960 + This routine should NOT be called from guest-partition
80961 + (i.e. guestId != NCSW_MASTER_ID)
80962 +*//***************************************************************************/
80963 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd);
80964 +
80965 +/**************************************************************************//**
80966 + @Function FM_PCD_KgSetDfltValue
80967 +
80968 + @Description Calling this routine sets a global default value to be used
80969 + by the KeyGen when parser does not recognize a required
80970 + field/header.
80971 + By default default values are 0.
80972 +
80973 + @Param[in] h_FmPcd FM PCD module descriptor.
80974 + @Param[in] valueId 0,1 - one of 2 global default values.
80975 + @Param[in] value The requested default value.
80976 +
80977 + @Return E_OK on success; Error code otherwise.
80978 +
80979 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80980 + This routine should NOT be called from guest-partition
80981 + (i.e. guestId != NCSW_MASTER_ID)
80982 +*//***************************************************************************/
80983 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value);
80984 +
80985 +/**************************************************************************//**
80986 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
80987 +
80988 + @Description Calling this routine allows the KeyGen to access data past
80989 + the parser finishing point.
80990 +
80991 + @Param[in] h_FmPcd FM PCD module descriptor.
80992 + @Param[in] payloadOffset the number of bytes beyond the parser location.
80993 +
80994 + @Return E_OK on success; Error code otherwise.
80995 +
80996 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80997 + This routine should NOT be called from guest-partition
80998 + (i.e. guestId != NCSW_MASTER_ID)
80999 +*//***************************************************************************/
81000 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset);
81001 +
81002 +/**************************************************************************//**
81003 + @Function FM_PCD_SetException
81004 +
81005 + @Description Calling this routine enables/disables PCD interrupts.
81006 +
81007 + @Param[in] h_FmPcd FM PCD module descriptor.
81008 + @Param[in] exception The exception to be selected.
81009 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81010 +
81011 + @Return E_OK on success; Error code otherwise.
81012 +
81013 + @Cautions Allowed only following FM_PCD_Init().
81014 + This routine should NOT be called from guest-partition
81015 + (i.e. guestId != NCSW_MASTER_ID)
81016 +*//***************************************************************************/
81017 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
81018 +
81019 +/**************************************************************************//**
81020 + @Function FM_PCD_ModifyCounter
81021 +
81022 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
81023 +
81024 + @Param[in] h_FmPcd FM PCD module descriptor.
81025 + @Param[in] counter The requested counter.
81026 + @Param[in] value The requested value to be written into the counter.
81027 +
81028 + @Return E_OK on success; Error code otherwise.
81029 +
81030 + @Cautions Allowed only following FM_PCD_Init().
81031 + This routine should NOT be called from guest-partition
81032 + (i.e. guestId != NCSW_MASTER_ID)
81033 +*//***************************************************************************/
81034 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value);
81035 +
81036 +/**************************************************************************//**
81037 + @Function FM_PCD_SetPlcrStatistics
81038 +
81039 + @Description This routine may be used to enable/disable policer statistics
81040 + counter. By default the statistics is enabled.
81041 +
81042 + @Param[in] h_FmPcd FM PCD module descriptor
81043 + @Param[in] enable TRUE to enable, FALSE to disable.
81044 +
81045 + @Return E_OK on success; Error code otherwise.
81046 +
81047 + @Cautions Allowed only following FM_PCD_Init().
81048 + This routine should NOT be called from guest-partition
81049 + (i.e. guestId != NCSW_MASTER_ID)
81050 +*//***************************************************************************/
81051 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable);
81052 +
81053 +/**************************************************************************//**
81054 + @Function FM_PCD_SetPrsStatistics
81055 +
81056 + @Description Defines whether to gather parser statistics including all ports.
81057 +
81058 + @Param[in] h_FmPcd FM PCD module descriptor.
81059 + @Param[in] enable TRUE to enable, FALSE to disable.
81060 +
81061 + @Return None
81062 +
81063 + @Cautions Allowed only following FM_PCD_Init().
81064 + This routine should NOT be called from guest-partition
81065 + (i.e. guestId != NCSW_MASTER_ID)
81066 +*//***************************************************************************/
81067 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable);
81068 +
81069 +/**************************************************************************//**
81070 + @Function FM_PCD_HcTxConf
81071 +
81072 + @Description This routine should be called to confirm frames that were
81073 + received on the HC confirmation queue.
81074 +
81075 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81076 + @Param[in] p_Fd Frame descriptor of the received frame.
81077 +
81078 + @Cautions Allowed only following FM_PCD_Init(). Allowed only if 'useHostCommand'
81079 + option was selected in the initialization.
81080 +*//***************************************************************************/
81081 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd);
81082 +
81083 +/**************************************************************************//*
81084 + @Function FM_PCD_ForceIntr
81085 +
81086 + @Description Causes an interrupt event on the requested source.
81087 +
81088 + @Param[in] h_FmPcd FM PCD module descriptor.
81089 + @Param[in] exception An exception to be forced.
81090 +
81091 + @Return E_OK on success; Error code if the exception is not enabled,
81092 + or is not able to create interrupt.
81093 +
81094 + @Cautions Allowed only following FM_PCD_Init().
81095 + This routine should NOT be called from guest-partition
81096 + (i.e. guestId != NCSW_MASTER_ID)
81097 +*//***************************************************************************/
81098 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception);
81099 +
81100 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
81101 +/**************************************************************************//**
81102 + @Function FM_PCD_DumpRegs
81103 +
81104 + @Description Dumps all PCD registers
81105 +
81106 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81107 +
81108 + @Return E_OK on success; Error code otherwise.
81109 +
81110 + @Cautions Allowed only following FM_PCD_Init().
81111 + NOTE: this routine may be called only for FM in master mode
81112 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81113 + are mapped.
81114 +*//***************************************************************************/
81115 +t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd);
81116 +
81117 +/**************************************************************************//**
81118 + @Function FM_PCD_KgDumpRegs
81119 +
81120 + @Description Dumps all PCD KG registers
81121 +
81122 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81123 +
81124 + @Return E_OK on success; Error code otherwise.
81125 +
81126 + @Cautions Allowed only following FM_PCD_Init().
81127 + NOTE: this routine may be called only for FM in master mode
81128 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81129 + are mapped.
81130 +*//***************************************************************************/
81131 +t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd);
81132 +
81133 +/**************************************************************************//**
81134 + @Function FM_PCD_PlcrDumpRegs
81135 +
81136 + @Description Dumps all PCD Policer registers
81137 +
81138 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81139 +
81140 + @Return E_OK on success; Error code otherwise.
81141 +
81142 + @Cautions Allowed only following FM_PCD_Init().
81143 + NOTE: this routine may be called only for FM in master mode
81144 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81145 + are mapped.
81146 +*//***************************************************************************/
81147 +t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd);
81148 +
81149 +/**************************************************************************//**
81150 + @Function FM_PCD_PlcrProfileDumpRegs
81151 +
81152 + @Description Dumps all PCD Policer profile registers
81153 +
81154 + @Param[in] h_Profile A handle to a Policer profile.
81155 +
81156 + @Return E_OK on success; Error code otherwise.
81157 +
81158 + @Cautions Allowed only following FM_PCD_Init().
81159 + NOTE: this routine may be called only for FM in master mode
81160 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81161 + are mapped.
81162 +*//***************************************************************************/
81163 +t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_Profile);
81164 +
81165 +/**************************************************************************//**
81166 + @Function FM_PCD_PrsDumpRegs
81167 +
81168 + @Description Dumps all PCD Parser registers
81169 +
81170 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81171 +
81172 + @Return E_OK on success; Error code otherwise.
81173 +
81174 + @Cautions Allowed only following FM_PCD_Init().
81175 + NOTE: this routine may be called only for FM in master mode
81176 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81177 + are mapped.
81178 +*//***************************************************************************/
81179 +t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd);
81180 +
81181 +/**************************************************************************//**
81182 + @Function FM_PCD_HcDumpRegs
81183 +
81184 + @Description Dumps HC Port registers
81185 +
81186 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81187 +
81188 + @Return E_OK on success; Error code otherwise.
81189 +
81190 + @Cautions Allowed only following FM_PCD_Init().
81191 + NOTE: this routine may be called only for FM in master mode
81192 + (i.e. 'guestId'=NCSW_MASTER_ID).
81193 +*//***************************************************************************/
81194 +t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd);
81195 +#endif /* (defined(DEBUG_ERRORS) && ... */
81196 +
81197 +
81198 +
81199 +/**************************************************************************//**
81200 + KeyGen FM_PCD_Runtime_build_grp FM PCD Runtime Building Unit
81201 +
81202 + @Description Frame Manager PCD Runtime Building API
81203 +
81204 + This group contains routines for setting, deleting and modifying
81205 + PCD resources, for defining the total PCD tree.
81206 + @{
81207 +*//***************************************************************************/
81208 +
81209 +/**************************************************************************//**
81210 + @Collection Definitions of coarse classification
81211 + parameters as required by KeyGen (when coarse classification
81212 + is the next engine after this scheme).
81213 +*//***************************************************************************/
81214 +#define FM_PCD_MAX_NUM_OF_CC_TREES 8
81215 +#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16
81216 +#define FM_PCD_MAX_NUM_OF_CC_UNITS 4
81217 +#define FM_PCD_MAX_NUM_OF_KEYS 256
81218 +#define FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
81219 +#define FM_PCD_MAX_SIZE_OF_KEY 56
81220 +#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
81221 +#define FM_PCD_LAST_KEY_INDEX 0xffff
81222 +
81223 +#define FM_PCD_MAX_NUM_OF_CC_NODES 255 /* Obsolete, not used - will be removed in the future */
81224 +/* @} */
81225 +
81226 +/**************************************************************************//**
81227 + @Collection A set of definitions to allow protocol
81228 + special option description.
81229 +*//***************************************************************************/
81230 +typedef uint32_t protocolOpt_t; /**< A general type to define a protocol option. */
81231 +
81232 +typedef protocolOpt_t ethProtocolOpt_t; /**< Ethernet protocol options. */
81233 +#define ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
81234 +#define ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
81235 +
81236 +typedef protocolOpt_t vlanProtocolOpt_t; /**< VLAN protocol options. */
81237 +#define VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
81238 +
81239 +typedef protocolOpt_t mplsProtocolOpt_t; /**< MPLS protocol options. */
81240 +#define MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
81241 +
81242 +typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */
81243 +#define IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
81244 +#define IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
81245 +#define IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
81246 +#define IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
81247 +
81248 +#define IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
81249 + IPV4 Reassembly manipulation requires network
81250 + environment with IPV4 header and IPV4_FRAG_1 option */
81251 +
81252 +typedef protocolOpt_t ipv6ProtocolOpt_t; /**< IPv6 protocol options. */
81253 +#define IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
81254 +#define IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
81255 +#define IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
81256 +
81257 +#define IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
81258 + IPV6 Reassembly manipulation requires network
81259 + environment with IPV6 header and IPV6_FRAG_1 option;
81260 + in case where fragment found, the fragment-extension offset
81261 + may be found at 'shim2' (in parser-result). */
81262 +#if (DPAA_VERSION >= 11)
81263 +typedef protocolOpt_t capwapProtocolOpt_t; /**< CAPWAP protocol options. */
81264 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
81265 + CAPWAP Reassembly manipulation requires network
81266 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
81267 + in case where fragment found, the fragment-extension offset
81268 + may be found at 'shim2' (in parser-result). */
81269 +#endif /* (DPAA_VERSION >= 11) */
81270 +
81271 +
81272 +/* @} */
81273 +
81274 +#define FM_PCD_MANIP_MAX_HDR_SIZE 256
81275 +#define FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
81276 +
81277 +/**************************************************************************//**
81278 + @Collection A set of definitions to support Header Manipulation selection.
81279 +*//***************************************************************************/
81280 +typedef uint32_t hdrManipFlags_t; /**< A general type to define a HMan update command flags. */
81281 +
81282 +typedef hdrManipFlags_t ipv4HdrManipUpdateFlags_t; /**< IPv4 protocol HMan update command flags. */
81283 +
81284 +#define HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
81285 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81286 +#define HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
81287 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81288 +#define HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
81289 +#define HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
81290 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81291 +#define HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
81292 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81293 +
81294 +typedef hdrManipFlags_t ipv6HdrManipUpdateFlags_t; /**< IPv6 protocol HMan update command flags. */
81295 +
81296 +#define HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
81297 + ('trafficClass' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81298 +#define HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
81299 +#define HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
81300 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81301 +#define HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
81302 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81303 +
81304 +typedef hdrManipFlags_t tcpUdpHdrManipUpdateFlags_t;/**< TCP/UDP protocol HMan update command flags. */
81305 +
81306 +#define HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
81307 + ('src' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81308 +#define HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
81309 + ('dst' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81310 +#define HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
81311 +
81312 +/* @} */
81313 +
81314 +/**************************************************************************//**
81315 + @Description A type used for returning the order of the key extraction.
81316 + each value in this array represents the index of the extraction
81317 + command as defined by the user in the initialization extraction array.
81318 + The valid size of this array is the user define number of extractions
81319 + required (also marked by the second '0' in this array).
81320 +*//***************************************************************************/
81321 +typedef uint8_t t_FmPcdKgKeyOrder [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
81322 +
81323 +/**************************************************************************//**
81324 + @Description All PCD engines
81325 +*//***************************************************************************/
81326 +typedef enum e_FmPcdEngine {
81327 + e_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
81328 + e_FM_PCD_DONE, /**< No PCD Engine indicated */
81329 + e_FM_PCD_KG, /**< KeyGen */
81330 + e_FM_PCD_CC, /**< Coarse classifier */
81331 + e_FM_PCD_PLCR, /**< Policer */
81332 + e_FM_PCD_PRS, /**< Parser */
81333 +#if (DPAA_VERSION >= 11)
81334 + e_FM_PCD_FR, /**< Frame-Replicator */
81335 +#endif /* (DPAA_VERSION >= 11) */
81336 + e_FM_PCD_HASH /**< Hash table */
81337 +} e_FmPcdEngine;
81338 +
81339 +/**************************************************************************//**
81340 + @Description Enumeration type for selecting extraction by header types
81341 +*//***************************************************************************/
81342 +typedef enum e_FmPcdExtractByHdrType {
81343 + e_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
81344 + e_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
81345 + e_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
81346 +} e_FmPcdExtractByHdrType;
81347 +
81348 +/**************************************************************************//**
81349 + @Description Enumeration type for selecting extraction source
81350 + (when it is not the header)
81351 +*//***************************************************************************/
81352 +typedef enum e_FmPcdExtractFrom {
81353 + e_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
81354 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
81355 + e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG & CC: Extract from the point where parsing had finished */
81356 + e_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
81357 + e_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
81358 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG only: Extract from the parser result */
81359 + e_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
81360 + e_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
81361 +} e_FmPcdExtractFrom;
81362 +
81363 +/**************************************************************************//**
81364 + @Description Enumeration type for selecting extraction type
81365 +*//***************************************************************************/
81366 +typedef enum e_FmPcdExtractType {
81367 + e_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
81368 + e_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
81369 + e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
81370 +} e_FmPcdExtractType;
81371 +
81372 +/**************************************************************************//**
81373 + @Description Enumeration type for selecting default extraction value
81374 +*//***************************************************************************/
81375 +typedef enum e_FmPcdKgExtractDfltSelect {
81376 + e_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
81377 + e_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
81378 + e_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
81379 + e_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
81380 + e_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
81381 +} e_FmPcdKgExtractDfltSelect;
81382 +
81383 +/**************************************************************************//**
81384 + @Description Enumeration type defining all default groups - each group shares
81385 + a default value, one of four user-initialized values.
81386 +*//***************************************************************************/
81387 +typedef enum e_FmPcdKgKnownFieldsDfltTypes {
81388 + e_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
81389 + e_FM_PCD_KG_TCI, /**< TCI field */
81390 + e_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
81391 + e_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
81392 + e_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
81393 + e_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
81394 + e_FM_PCD_KG_IP_ADDR, /**< IP address */
81395 + e_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
81396 + e_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
81397 + e_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
81398 + e_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
81399 + e_FM_PCD_KG_L4_PORT, /**< L4 Port */
81400 + e_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
81401 + e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
81402 + any data extraction that is not the full
81403 + field described above */
81404 + e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
81405 + any data extraction without validation */
81406 + e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
81407 + extraction from parser result or
81408 + direct use of default value */
81409 +} e_FmPcdKgKnownFieldsDfltTypes;
81410 +
81411 +/**************************************************************************//**
81412 + @Description Enumeration type for defining header index for scenarios with
81413 + multiple (tunneled) headers
81414 +*//***************************************************************************/
81415 +typedef enum e_FmPcdHdrIndex {
81416 + e_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
81417 + to specify regular IP (not tunneled). */
81418 + e_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
81419 + e_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
81420 + e_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
81421 + e_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
81422 +} e_FmPcdHdrIndex;
81423 +
81424 +/**************************************************************************//**
81425 + @Description Enumeration type for selecting the policer profile functional type
81426 +*//***************************************************************************/
81427 +typedef enum e_FmPcdProfileTypeSelection {
81428 + e_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
81429 + e_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
81430 +} e_FmPcdProfileTypeSelection;
81431 +
81432 +/**************************************************************************//**
81433 + @Description Enumeration type for selecting the policer profile algorithm
81434 +*//***************************************************************************/
81435 +typedef enum e_FmPcdPlcrAlgorithmSelection {
81436 + e_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
81437 + e_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
81438 + e_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
81439 +} e_FmPcdPlcrAlgorithmSelection;
81440 +
81441 +/**************************************************************************//**
81442 + @Description Enumeration type for selecting a policer profile color mode
81443 +*//***************************************************************************/
81444 +typedef enum e_FmPcdPlcrColorMode {
81445 + e_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
81446 + e_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
81447 +} e_FmPcdPlcrColorMode;
81448 +
81449 +/**************************************************************************//**
81450 + @Description Enumeration type for selecting a policer profile color
81451 +*//***************************************************************************/
81452 +typedef enum e_FmPcdPlcrColor {
81453 + e_FM_PCD_PLCR_GREEN, /**< Green color code */
81454 + e_FM_PCD_PLCR_YELLOW, /**< Yellow color code */
81455 + e_FM_PCD_PLCR_RED, /**< Red color code */
81456 + e_FM_PCD_PLCR_OVERRIDE /**< Color override code */
81457 +} e_FmPcdPlcrColor;
81458 +
81459 +/**************************************************************************//**
81460 + @Description Enumeration type for selecting the policer profile packet frame length selector
81461 +*//***************************************************************************/
81462 +typedef enum e_FmPcdPlcrFrameLengthSelect {
81463 + e_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
81464 + e_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
81465 + e_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
81466 + e_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
81467 +} e_FmPcdPlcrFrameLengthSelect;
81468 +
81469 +/**************************************************************************//**
81470 + @Description Enumeration type for selecting roll-back frame
81471 +*//***************************************************************************/
81472 +typedef enum e_FmPcdPlcrRollBackFrameSelect {
81473 + e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Roll-back L2 frame length */
81474 + e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Roll-back Full frame length */
81475 +} e_FmPcdPlcrRollBackFrameSelect;
81476 +
81477 +/**************************************************************************//**
81478 + @Description Enumeration type for selecting the policer profile packet or byte mode
81479 +*//***************************************************************************/
81480 +typedef enum e_FmPcdPlcrRateMode {
81481 + e_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
81482 + e_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
81483 +} e_FmPcdPlcrRateMode;
81484 +
81485 +/**************************************************************************//**
81486 + @Description Enumeration type for defining action of frame
81487 +*//***************************************************************************/
81488 +typedef enum e_FmPcdDoneAction {
81489 + e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
81490 + e_FM_PCD_DROP_FRAME /**< Mark this frame as error frame and continue
81491 + to error flow; 'FM_PORT_FRM_ERR_CLS_DISCARD'
81492 + flag will be set for this frame. */
81493 +} e_FmPcdDoneAction;
81494 +
81495 +/**************************************************************************//**
81496 + @Description Enumeration type for selecting the policer counter
81497 +*//***************************************************************************/
81498 +typedef enum e_FmPcdPlcrProfileCounters {
81499 + e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
81500 + e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
81501 + e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
81502 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
81503 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
81504 +} e_FmPcdPlcrProfileCounters;
81505 +
81506 +/**************************************************************************//**
81507 + @Description Enumeration type for selecting the PCD action after extraction
81508 +*//***************************************************************************/
81509 +typedef enum e_FmPcdAction {
81510 + e_FM_PCD_ACTION_NONE, /**< NONE */
81511 + e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction */
81512 + e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction */
81513 +} e_FmPcdAction;
81514 +
81515 +/**************************************************************************//**
81516 + @Description Enumeration type for selecting type of insert manipulation
81517 +*//***************************************************************************/
81518 +typedef enum e_FmPcdManipHdrInsrtType {
81519 + e_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
81520 + e_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
81521 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81522 + e_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
81523 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81524 +} e_FmPcdManipHdrInsrtType;
81525 +
81526 +/**************************************************************************//**
81527 + @Description Enumeration type for selecting type of remove manipulation
81528 +*//***************************************************************************/
81529 +typedef enum e_FmPcdManipHdrRmvType {
81530 + e_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
81531 + e_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
81532 +} e_FmPcdManipHdrRmvType;
81533 +
81534 +/**************************************************************************//**
81535 + @Description Enumeration type for selecting specific L2 fields removal
81536 +*//***************************************************************************/
81537 +typedef enum e_FmPcdManipHdrRmvSpecificL2 {
81538 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
81539 + e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
81540 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
81541 + the header which follows the MPLS header */
81542 + e_FM_PCD_MANIP_HDR_RMV_MPLS, /**< Remove MPLS header (Unlimited MPLS labels) */
81543 + e_FM_PCD_MANIP_HDR_RMV_PPPOE /**< Remove the PPPoE header and PPP protocol field. */
81544 +} e_FmPcdManipHdrRmvSpecificL2;
81545 +
81546 +/**************************************************************************//**
81547 + @Description Enumeration type for selecting specific fields updates
81548 +*//***************************************************************************/
81549 +typedef enum e_FmPcdManipHdrFieldUpdateType {
81550 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
81551 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
81552 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
81553 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
81554 +} e_FmPcdManipHdrFieldUpdateType;
81555 +
81556 +/**************************************************************************//**
81557 + @Description Enumeration type for selecting VLAN updates
81558 +*//***************************************************************************/
81559 +typedef enum e_FmPcdManipHdrFieldUpdateVlan {
81560 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
81561 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
81562 +} e_FmPcdManipHdrFieldUpdateVlan;
81563 +
81564 +/**************************************************************************//**
81565 + @Description Enumeration type for selecting specific L2 header insertion
81566 +*//***************************************************************************/
81567 +typedef enum e_FmPcdManipHdrInsrtSpecificL2 {
81568 + e_FM_PCD_MANIP_HDR_INSRT_MPLS, /**< Insert MPLS header (Unlimited MPLS labels) */
81569 + e_FM_PCD_MANIP_HDR_INSRT_PPPOE /**< Insert PPPOE */
81570 +} e_FmPcdManipHdrInsrtSpecificL2;
81571 +
81572 +#if (DPAA_VERSION >= 11)
81573 +/**************************************************************************//**
81574 + @Description Enumeration type for selecting QoS mapping mode
81575 +
81576 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
81577 + User should instruct the port to read the hash-result
81578 +*//***************************************************************************/
81579 +typedef enum e_FmPcdManipHdrQosMappingMode {
81580 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
81581 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the hash-result. */
81582 +} e_FmPcdManipHdrQosMappingMode;
81583 +
81584 +/**************************************************************************//**
81585 + @Description Enumeration type for selecting QoS source
81586 +
81587 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
81588 + User should left room for the hash-result on input/output buffer
81589 + and instruct the port to read/write the hash-result to the buffer (RPD should be set)
81590 +*//***************************************************************************/
81591 +typedef enum e_FmPcdManipHdrQosSrc {
81592 + e_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
81593 + e_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the hash-result. */
81594 +} e_FmPcdManipHdrQosSrc;
81595 +#endif /* (DPAA_VERSION >= 11) */
81596 +
81597 +/**************************************************************************//**
81598 + @Description Enumeration type for selecting type of header insertion
81599 +*//***************************************************************************/
81600 +typedef enum e_FmPcdManipHdrInsrtByHdrType {
81601 + e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
81602 +#if (DPAA_VERSION >= 11)
81603 + e_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
81604 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
81605 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
81606 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
81607 +#endif /* (DPAA_VERSION >= 11) */
81608 +} e_FmPcdManipHdrInsrtByHdrType;
81609 +
81610 +/**************************************************************************//**
81611 + @Description Enumeration type for selecting specific customCommand
81612 +*//***************************************************************************/
81613 +typedef enum e_FmPcdManipHdrCustomType {
81614 + e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
81615 + e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE, /**< Replace IPv4/IPv6 */
81616 +} e_FmPcdManipHdrCustomType;
81617 +
81618 +/**************************************************************************//**
81619 + @Description Enumeration type for selecting specific customCommand
81620 +*//***************************************************************************/
81621 +typedef enum e_FmPcdManipHdrCustomIpReplace {
81622 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
81623 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
81624 +} e_FmPcdManipHdrCustomIpReplace;
81625 +
81626 +/**************************************************************************//**
81627 + @Description Enumeration type for selecting type of header removal
81628 +*//***************************************************************************/
81629 +typedef enum e_FmPcdManipHdrRmvByHdrType {
81630 + e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
81631 +#if (DPAA_VERSION >= 11)
81632 + e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
81633 +#endif /* (DPAA_VERSION >= 11) */
81634 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81635 + e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
81636 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81637 +} e_FmPcdManipHdrRmvByHdrType;
81638 +
81639 +/**************************************************************************//**
81640 + @Description Enumeration type for selecting type of timeout mode
81641 +*//***************************************************************************/
81642 +typedef enum e_FmPcdManipReassemTimeOutMode {
81643 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
81644 + from the first fragment to the last */
81645 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
81646 +} e_FmPcdManipReassemTimeOutMode;
81647 +
81648 +/**************************************************************************//**
81649 + @Description Enumeration type for selecting type of WaysNumber mode
81650 +*//***************************************************************************/
81651 +typedef enum e_FmPcdManipReassemWaysNumber {
81652 + e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
81653 + e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
81654 + e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
81655 + e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
81656 + e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
81657 + e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
81658 + e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
81659 + e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
81660 +} e_FmPcdManipReassemWaysNumber;
81661 +
81662 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81663 +/**************************************************************************//**
81664 + @Description Enumeration type for selecting type of statistics mode
81665 +*//***************************************************************************/
81666 +typedef enum e_FmPcdStatsType {
81667 + e_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
81668 +} e_FmPcdStatsType;
81669 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81670 +
81671 +/**************************************************************************//**
81672 + @Description Enumeration type for selecting manipulation type
81673 +*//***************************************************************************/
81674 +typedef enum e_FmPcdManipType {
81675 + e_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
81676 + e_FM_PCD_MANIP_REASSEM, /**< Reassembly */
81677 + e_FM_PCD_MANIP_FRAG, /**< Fragmentation */
81678 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
81679 +} e_FmPcdManipType;
81680 +
81681 +/**************************************************************************//**
81682 + @Description Enumeration type for selecting type of statistics mode
81683 +*//***************************************************************************/
81684 +typedef enum e_FmPcdCcStatsMode {
81685 + e_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
81686 + e_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
81687 + e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
81688 +#if (DPAA_VERSION >= 11)
81689 + e_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics;
81690 + This mode is supported only on B4860 device */
81691 +#endif /* (DPAA_VERSION >= 11) */
81692 +} e_FmPcdCcStatsMode;
81693 +
81694 +/**************************************************************************//**
81695 + @Description Enumeration type for determining the action in case an IP packet
81696 + is larger than MTU but its DF (Don't Fragment) bit is set.
81697 +*//***************************************************************************/
81698 +typedef enum e_FmPcdManipDontFragAction {
81699 + e_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
81700 + e_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_FM_PCD_MANIP_DISCARD_PACKET,
81701 + /**< Obsolete, cannot enqueue to error queue;
81702 + In practice, selects to discard packets;
81703 + Will be removed in the future */
81704 + e_FM_PCD_MANIP_FRAGMENT_PACKET, /**< Fragment packet and continue normal processing */
81705 + e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
81706 +} e_FmPcdManipDontFragAction;
81707 +
81708 +/**************************************************************************//**
81709 + @Description Enumeration type for selecting type of special offload manipulation
81710 +*//***************************************************************************/
81711 +typedef enum e_FmPcdManipSpecialOffloadType {
81712 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
81713 +#if (DPAA_VERSION >= 11)
81714 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
81715 +#endif /* (DPAA_VERSION >= 11) */
81716 +} e_FmPcdManipSpecialOffloadType;
81717 +
81718 +
81719 +/**************************************************************************//**
81720 + @Description A Union of protocol dependent special options
81721 +*//***************************************************************************/
81722 +typedef union u_FmPcdHdrProtocolOpt {
81723 + ethProtocolOpt_t ethOpt; /**< Ethernet options */
81724 + vlanProtocolOpt_t vlanOpt; /**< VLAN options */
81725 + mplsProtocolOpt_t mplsOpt; /**< MPLS options */
81726 + ipv4ProtocolOpt_t ipv4Opt; /**< IPv4 options */
81727 + ipv6ProtocolOpt_t ipv6Opt; /**< IPv6 options */
81728 +#if (DPAA_VERSION >= 11)
81729 + capwapProtocolOpt_t capwapOpt; /**< CAPWAP options */
81730 +#endif /* (DPAA_VERSION >= 11) */
81731 +} u_FmPcdHdrProtocolOpt;
81732 +
81733 +/**************************************************************************//**
81734 + @Description A union holding protocol fields
81735 +
81736 +
81737 + Fields supported as "full fields":
81738 + HEADER_TYPE_ETH:
81739 + NET_HEADER_FIELD_ETH_DA
81740 + NET_HEADER_FIELD_ETH_SA
81741 + NET_HEADER_FIELD_ETH_TYPE
81742 +
81743 + HEADER_TYPE_LLC_SNAP:
81744 + NET_HEADER_FIELD_LLC_SNAP_TYPE
81745 +
81746 + HEADER_TYPE_VLAN:
81747 + NET_HEADER_FIELD_VLAN_TCI
81748 + (index may apply:
81749 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81750 + e_FM_PCD_HDR_INDEX_LAST)
81751 +
81752 + HEADER_TYPE_MPLS:
81753 + NET_HEADER_FIELD_MPLS_LABEL_STACK
81754 + (index may apply:
81755 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81756 + e_FM_PCD_HDR_INDEX_2,
81757 + e_FM_PCD_HDR_INDEX_LAST)
81758 +
81759 + HEADER_TYPE_IPv4:
81760 + NET_HEADER_FIELD_IPv4_SRC_IP
81761 + NET_HEADER_FIELD_IPv4_DST_IP
81762 + NET_HEADER_FIELD_IPv4_PROTO
81763 + NET_HEADER_FIELD_IPv4_TOS
81764 + (index may apply:
81765 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81766 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81767 +
81768 + HEADER_TYPE_IPv6:
81769 + NET_HEADER_FIELD_IPv6_SRC_IP
81770 + NET_HEADER_FIELD_IPv6_DST_IP
81771 + NET_HEADER_FIELD_IPv6_NEXT_HDR
81772 + NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC (must come together!)
81773 + (index may apply:
81774 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81775 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81776 +
81777 + (Note that starting from DPAA 1-1, NET_HEADER_FIELD_IPv6_NEXT_HDR applies to
81778 + the last next header indication, meaning the next L4, which may be
81779 + present at the Ipv6 last extension. On earlier revisions this field
81780 + applies to the Next-Header field of the main IPv6 header)
81781 +
81782 + HEADER_TYPE_IP:
81783 + NET_HEADER_FIELD_IP_PROTO
81784 + (index may apply:
81785 + e_FM_PCD_HDR_INDEX_LAST)
81786 + NET_HEADER_FIELD_IP_DSCP
81787 + (index may apply:
81788 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1)
81789 + HEADER_TYPE_GRE:
81790 + NET_HEADER_FIELD_GRE_TYPE
81791 +
81792 + HEADER_TYPE_MINENCAP
81793 + NET_HEADER_FIELD_MINENCAP_SRC_IP
81794 + NET_HEADER_FIELD_MINENCAP_DST_IP
81795 + NET_HEADER_FIELD_MINENCAP_TYPE
81796 +
81797 + HEADER_TYPE_TCP:
81798 + NET_HEADER_FIELD_TCP_PORT_SRC
81799 + NET_HEADER_FIELD_TCP_PORT_DST
81800 + NET_HEADER_FIELD_TCP_FLAGS
81801 +
81802 + HEADER_TYPE_UDP:
81803 + NET_HEADER_FIELD_UDP_PORT_SRC
81804 + NET_HEADER_FIELD_UDP_PORT_DST
81805 +
81806 + HEADER_TYPE_UDP_LITE:
81807 + NET_HEADER_FIELD_UDP_LITE_PORT_SRC
81808 + NET_HEADER_FIELD_UDP_LITE_PORT_DST
81809 +
81810 + HEADER_TYPE_IPSEC_AH:
81811 + NET_HEADER_FIELD_IPSEC_AH_SPI
81812 + NET_HEADER_FIELD_IPSEC_AH_NH
81813 +
81814 + HEADER_TYPE_IPSEC_ESP:
81815 + NET_HEADER_FIELD_IPSEC_ESP_SPI
81816 +
81817 + HEADER_TYPE_SCTP:
81818 + NET_HEADER_FIELD_SCTP_PORT_SRC
81819 + NET_HEADER_FIELD_SCTP_PORT_DST
81820 +
81821 + HEADER_TYPE_DCCP:
81822 + NET_HEADER_FIELD_DCCP_PORT_SRC
81823 + NET_HEADER_FIELD_DCCP_PORT_DST
81824 +
81825 + HEADER_TYPE_PPPoE:
81826 + NET_HEADER_FIELD_PPPoE_PID
81827 + NET_HEADER_FIELD_PPPoE_SID
81828 +
81829 + *****************************************************************
81830 + Fields supported as "from fields":
81831 + HEADER_TYPE_ETH (with or without validation):
81832 + NET_HEADER_FIELD_ETH_TYPE
81833 +
81834 + HEADER_TYPE_VLAN (with or without validation):
81835 + NET_HEADER_FIELD_VLAN_TCI
81836 + (index may apply:
81837 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81838 + e_FM_PCD_HDR_INDEX_LAST)
81839 +
81840 + HEADER_TYPE_IPv4 (without validation):
81841 + NET_HEADER_FIELD_IPv4_PROTO
81842 + (index may apply:
81843 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81844 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81845 +
81846 + HEADER_TYPE_IPv6 (without validation):
81847 + NET_HEADER_FIELD_IPv6_NEXT_HDR
81848 + (index may apply:
81849 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81850 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81851 +
81852 +*//***************************************************************************/
81853 +typedef union t_FmPcdFields {
81854 + headerFieldEth_t eth; /**< Ethernet */
81855 + headerFieldVlan_t vlan; /**< VLAN */
81856 + headerFieldLlcSnap_t llcSnap; /**< LLC SNAP */
81857 + headerFieldPppoe_t pppoe; /**< PPPoE */
81858 + headerFieldMpls_t mpls; /**< MPLS */
81859 + headerFieldIp_t ip; /**< IP */
81860 + headerFieldIpv4_t ipv4; /**< IPv4 */
81861 + headerFieldIpv6_t ipv6; /**< IPv6 */
81862 + headerFieldUdp_t udp; /**< UDP */
81863 + headerFieldUdpLite_t udpLite; /**< UDP Lite */
81864 + headerFieldTcp_t tcp; /**< TCP */
81865 + headerFieldSctp_t sctp; /**< SCTP */
81866 + headerFieldDccp_t dccp; /**< DCCP */
81867 + headerFieldGre_t gre; /**< GRE */
81868 + headerFieldMinencap_t minencap; /**< Minimal Encapsulation */
81869 + headerFieldIpsecAh_t ipsecAh; /**< IPSec AH */
81870 + headerFieldIpsecEsp_t ipsecEsp; /**< IPSec ESP */
81871 + headerFieldUdpEncapEsp_t udpEncapEsp; /**< UDP Encapsulation ESP */
81872 +} t_FmPcdFields;
81873 +
81874 +/**************************************************************************//**
81875 + @Description Parameters for defining header extraction for key generation
81876 +*//***************************************************************************/
81877 +typedef struct t_FmPcdFromHdr {
81878 + uint8_t size; /**< Size in byte */
81879 + uint8_t offset; /**< Byte offset */
81880 +} t_FmPcdFromHdr;
81881 +
81882 +/**************************************************************************//**
81883 + @Description Parameters for defining field extraction for key generation
81884 +*//***************************************************************************/
81885 +typedef struct t_FmPcdFromField {
81886 + t_FmPcdFields field; /**< Field selection */
81887 + uint8_t size; /**< Size in byte */
81888 + uint8_t offset; /**< Byte offset */
81889 +} t_FmPcdFromField;
81890 +
81891 +/**************************************************************************//**
81892 + @Description Parameters for defining a single network environment unit
81893 +
81894 + A distinction unit should be defined if it will later be used
81895 + by one or more PCD engines to distinguish between flows.
81896 +*//***************************************************************************/
81897 +typedef struct t_FmPcdDistinctionUnit {
81898 + struct {
81899 + e_NetHeaderType hdr; /**< One of the headers supported by the FM */
81900 + u_FmPcdHdrProtocolOpt opt; /**< Select only one option ! */
81901 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
81902 +} t_FmPcdDistinctionUnit;
81903 +
81904 +/**************************************************************************//**
81905 + @Description Parameters for defining all different distinction units supported
81906 + by a specific PCD Network Environment Characteristics module.
81907 +
81908 + Each unit represent a protocol or a group of protocols that may
81909 + be used later by the different PCD engines to distinguish
81910 + between flows.
81911 +*//***************************************************************************/
81912 +typedef struct t_FmPcdNetEnvParams {
81913 + uint8_t numOfDistinctionUnits; /**< Number of different units to be identified */
81914 + t_FmPcdDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /**< An array of numOfDistinctionUnits of the
81915 + different units to be identified */
81916 +} t_FmPcdNetEnvParams;
81917 +
81918 +/**************************************************************************//**
81919 + @Description Parameters for defining a single extraction action when
81920 + creating a key
81921 +*//***************************************************************************/
81922 +typedef struct t_FmPcdExtractEntry {
81923 + e_FmPcdExtractType type; /**< Extraction type select */
81924 + union {
81925 + struct {
81926 + e_NetHeaderType hdr; /**< Header selection */
81927 + bool ignoreProtocolValidation;
81928 + /**< Ignore protocol validation */
81929 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
81930 + IP. Otherwise should be cleared. */
81931 + e_FmPcdExtractByHdrType type; /**< Header extraction type select */
81932 + union {
81933 + t_FmPcdFromHdr fromHdr; /**< Extract bytes from header parameters */
81934 + t_FmPcdFromField fromField; /**< Extract bytes from field parameters */
81935 + t_FmPcdFields fullField; /**< Extract full filed parameters */
81936 + } extractByHdrType;
81937 + } extractByHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
81938 + struct {
81939 + e_FmPcdExtractFrom src; /**< Non-header extraction source */
81940 + e_FmPcdAction action; /**< Relevant for CC Only */
81941 + uint16_t icIndxMask; /**< Relevant only for CC when
81942 + action = e_FM_PCD_ACTION_INDEXED_LOOKUP;
81943 + Note that the number of bits that are set within
81944 + this mask must be log2 of the CC-node 'numOfKeys'.
81945 + Note that the mask cannot be set on the lower bits. */
81946 + uint8_t offset; /**< Byte offset */
81947 + uint8_t size; /**< Size in byte */
81948 + } extractNonHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
81949 + };
81950 +} t_FmPcdExtractEntry;
81951 +
81952 +/**************************************************************************//**
81953 + @Description Parameters for defining masks for each extracted field in the key.
81954 +*//***************************************************************************/
81955 +typedef struct t_FmPcdKgExtractMask {
81956 + uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */
81957 + uint8_t offset; /**< Byte offset */
81958 + uint8_t mask; /**< A byte mask (selected bits will be used) */
81959 +} t_FmPcdKgExtractMask;
81960 +
81961 +/**************************************************************************//**
81962 + @Description Parameters for defining default selection per groups of fields
81963 +*//***************************************************************************/
81964 +typedef struct t_FmPcdKgExtractDflt {
81965 + e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select */
81966 + e_FmPcdKgExtractDfltSelect dfltSelect; /**< Default register select */
81967 +} t_FmPcdKgExtractDflt;
81968 +
81969 +/**************************************************************************//**
81970 + @Description Parameters for defining key extraction and hashing
81971 +*//***************************************************************************/
81972 +typedef struct t_FmPcdKgKeyExtractAndHashParams {
81973 + uint32_t privateDflt0; /**< Scheme default register 0 */
81974 + uint32_t privateDflt1; /**< Scheme default register 1 */
81975 + uint8_t numOfUsedExtracts; /**< defines the valid size of the following array */
81976 + t_FmPcdExtractEntry extractArray [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; /**< An array of extractions definition. */
81977 + uint8_t numOfUsedDflts; /**< defines the valid size of the following array */
81978 + t_FmPcdKgExtractDflt dflts[FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
81979 + /**< For each extraction used in this scheme, specify the required
81980 + default register to be used when header is not found.
81981 + types not specified in this array will get undefined value. */
81982 + uint8_t numOfUsedMasks; /**< defines the valid size of the following array */
81983 + t_FmPcdKgExtractMask masks[FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
81984 + uint8_t hashShift; /**< hash result right shift. Select the 24 bits out of the 64 hash
81985 + result. 0 means using the 24 LSB's, otherwise use the
81986 + 24 LSB's after shifting right.*/
81987 + uint32_t hashDistributionNumOfFqids; /**< must be > 1 and a power of 2. Represents the range
81988 + of queues for the key and hash functionality */
81989 + uint8_t hashDistributionFqidsShift; /**< selects the FQID bits that will be effected by the hash */
81990 + bool symmetricHash; /**< TRUE to generate the same hash for frames with swapped source and
81991 + destination fields on all layers; If TRUE, driver will check that for
81992 + all layers, if SRC extraction is selected, DST extraction must also be
81993 + selected, and vice versa. */
81994 +} t_FmPcdKgKeyExtractAndHashParams;
81995 +
81996 +/**************************************************************************//**
81997 + @Description Parameters for defining a single FQID mask (extracted OR).
81998 +*//***************************************************************************/
81999 +typedef struct t_FmPcdKgExtractedOrParams {
82000 + e_FmPcdExtractType type; /**< Extraction type select */
82001 + union {
82002 + struct { /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
82003 + e_NetHeaderType hdr;
82004 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
82005 + IP. Otherwise should be cleared.*/
82006 + bool ignoreProtocolValidation;
82007 + /**< continue extraction even if protocol is not recognized */
82008 + } extractByHdr; /**< Header to extract by */
82009 + e_FmPcdExtractFrom src; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
82010 + };
82011 + uint8_t extractionOffset; /**< Offset for extraction (in bytes). */
82012 + e_FmPcdKgExtractDfltSelect dfltValue; /**< Select register from which extraction is taken if
82013 + field not found */
82014 + uint8_t mask; /**< Extraction mask (specified bits are used) */
82015 + uint8_t bitOffsetInFqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
82016 + the extracted byte; Assume byte is placed as the 8 MSB's in
82017 + a 32 bit word where the lower bits
82018 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
82019 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
82020 + extracted byte will effect the 8 LSB's of the FQID,
82021 + if bitOffsetInFqid=31 than the byte's MSB will effect
82022 + the FQID's LSB; 0 means - no effect on FQID;
82023 + Note that one, and only one of
82024 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
82025 + extracted byte must effect either FQID or Policer profile).*/
82026 + uint8_t bitOffsetInPlcrProfile;
82027 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
82028 + effect using the extracted byte; Assume byte is placed
82029 + as the 8 MSB's in a 16 bit word where the lower bits
82030 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
82031 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
82032 + than the extracted byte will effect the whole policer profile id,
82033 + if bitOffsetInFqid=15 than the byte's MSB will effect
82034 + the Policer Profile id's LSB;
82035 + 0 means - no effect on policer profile; Note that one, and only one of
82036 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
82037 + extracted byte must effect either FQID or Policer profile).*/
82038 +} t_FmPcdKgExtractedOrParams;
82039 +
82040 +/**************************************************************************//**
82041 + @Description Parameters for configuring a scheme counter
82042 +*//***************************************************************************/
82043 +typedef struct t_FmPcdKgSchemeCounter {
82044 + bool update; /**< FALSE to keep the current counter state
82045 + and continue from that point, TRUE to update/reset
82046 + the counter when the scheme is written. */
82047 + uint32_t value; /**< If update=TRUE, this value will be written into the
82048 + counter. clear this field to reset the counter. */
82049 +} t_FmPcdKgSchemeCounter;
82050 +
82051 +/**************************************************************************//**
82052 + @Description Parameters for configuring a policer profile for a KeyGen scheme
82053 + (when policer is the next engine after this scheme).
82054 +*//***************************************************************************/
82055 +typedef struct t_FmPcdKgPlcrProfile {
82056 + bool sharedProfile; /**< TRUE if this profile is shared between ports
82057 + (managed by master partition); Must not be TRUE
82058 + if profile is after Coarse Classification*/
82059 + bool direct; /**< if TRUE, directRelativeProfileId only selects the profile
82060 + id, if FALSE fqidOffsetRelativeProfileIdBase is used
82061 + together with fqidOffsetShift and numOfProfiles
82062 + parameters, to define a range of profiles from
82063 + which the KeyGen result will determine the
82064 + destination policer profile. */
82065 + union {
82066 + uint16_t directRelativeProfileId; /**< Used if 'direct' is TRUE, to select policer profile.
82067 + should indicate the policer profile offset within the
82068 + port's policer profiles or shared window. */
82069 + struct {
82070 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
82071 + final FQID - without the FQID base). */
82072 + uint8_t fqidOffsetRelativeProfileIdBase;
82073 + /**< The base of the FMan Port's relative Storage-Profile ID;
82074 + this value will be "OR'ed" with the KeyGen create FQID
82075 + offset (i.e. not the final FQID - without the FQID base);
82076 + the final result should indicate the Storage-Profile offset
82077 + within the FMan Port's relative Storage-Profiles window/
82078 + (or the SHARED window depends on 'sharedProfile'). */
82079 + uint8_t numOfProfiles; /**< Range of profiles starting at base */
82080 + } indirectProfile; /**< Indirect profile parameters */
82081 + } profileSelect; /**< Direct/indirect profile selection and parameters */
82082 +} t_FmPcdKgPlcrProfile;
82083 +
82084 +#if (DPAA_VERSION >= 11)
82085 +/**************************************************************************//**
82086 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
82087 +*//***************************************************************************/
82088 +typedef struct t_FmPcdKgStorageProfile {
82089 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
82090 + profile id;
82091 + If FALSE, fqidOffsetRelativeProfileIdBase is used
82092 + together with fqidOffsetShift and numOfProfiles
82093 + parameters to define a range of profiles from which
82094 + the KeyGen result will determine the destination
82095 + storage profile. */
82096 + union {
82097 + uint16_t directRelativeProfileId; /**< Used when 'direct' is TRUE, to select a storage profile;
82098 + should indicate the storage profile offset within the
82099 + port's storage profiles window. */
82100 + struct {
82101 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
82102 + final FQID - without the FQID base). */
82103 + uint8_t fqidOffsetRelativeProfileIdBase;
82104 + /**< The base of the FMan Port's relative Storage-Profile ID;
82105 + this value will be "OR'ed" with the KeyGen create FQID
82106 + offset (i.e. not the final FQID - without the FQID base);
82107 + the final result should indicate the Storage-Profile offset
82108 + within the FMan Port's relative Storage-Profiles window. */
82109 + uint8_t numOfProfiles; /**< Range of profiles starting at base. */
82110 + } indirectProfile; /**< Indirect profile parameters. */
82111 + } profileSelect; /**< Direct/indirect profile selection and parameters. */
82112 +} t_FmPcdKgStorageProfile;
82113 +#endif /* (DPAA_VERSION >= 11) */
82114 +
82115 +/**************************************************************************//**
82116 + @Description Parameters for defining CC as the next engine after KeyGen
82117 +*//***************************************************************************/
82118 +typedef struct t_FmPcdKgCc {
82119 + t_Handle h_CcTree; /**< A handle to a CC Tree */
82120 + uint8_t grpId; /**< CC group id within the CC tree */
82121 + bool plcrNext; /**< TRUE if after CC, in case of data frame,
82122 + policing is required. */
82123 + bool bypassPlcrProfileGeneration; /**< TRUE to bypass KeyGen policer profile generation;
82124 + selected profile is the one set at port initialization. */
82125 + t_FmPcdKgPlcrProfile plcrProfile; /**< Valid only if plcrNext = TRUE and
82126 + bypassPlcrProfileGeneration = FALSE */
82127 +} t_FmPcdKgCc;
82128 +
82129 +/**************************************************************************//**
82130 + @Description Parameters for defining initializing a KeyGen scheme
82131 +*//***************************************************************************/
82132 +typedef struct t_FmPcdKgSchemeParams {
82133 + bool modify; /**< TRUE to change an existing scheme */
82134 + union
82135 + {
82136 + uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */
82137 + t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */
82138 + } id;
82139 + bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need
82140 + for match vector; KeyGen will ignore it when matching */
82141 + struct { /**< HL Relevant only if alwaysDirect = FALSE */
82142 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
82143 + by FM_PCD_NetEnvCharacteristicsSet() */
82144 + uint8_t numOfDistinctionUnits; /**< Number of NetEnv units listed in unitIds array */
82145 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
82146 + /**< Indexes as passed to SetNetEnvCharacteristics array*/
82147 + } netEnvParams;
82148 + bool useHash; /**< use the KeyGen Hash functionality */
82149 + t_FmPcdKgKeyExtractAndHashParams keyExtractAndHashParams;
82150 + /**< used only if useHash = TRUE */
82151 + bool bypassFqidGeneration; /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
82152 + In such a case FQID after KeyGen will be the default FQID
82153 + defined for the relevant port, or the FQID defined by CC
82154 + in cases where CC was the previous engine. */
82155 + uint32_t baseFqid; /**< Base FQID; Relevant only if bypassFqidGeneration = FALSE;
82156 + If hash is used and an even distribution is expected
82157 + according to hashDistributionNumOfFqids, baseFqid must be aligned to
82158 + hashDistributionNumOfFqids. */
82159 + uint8_t numOfUsedExtractedOrs; /**< Number of FQID masks listed in extractedOrs array */
82160 + t_FmPcdKgExtractedOrParams extractedOrs[FM_PCD_KG_NUM_OF_GENERIC_REGS];
82161 + /**< FM_PCD_KG_NUM_OF_GENERIC_REGS
82162 + registers are shared between qidMasks
82163 + functionality and some of the extraction
82164 + actions; Normally only some will be used
82165 + for qidMask. Driver will return error if
82166 + resource is full at initialization time. */
82167 +
82168 +#if (DPAA_VERSION >= 11)
82169 + bool overrideStorageProfile; /**< TRUE if KeyGen override previously decided storage profile */
82170 + t_FmPcdKgStorageProfile storageProfile; /**< Used when overrideStorageProfile TRUE */
82171 +#endif /* (DPAA_VERSION >= 11) */
82172 +
82173 + e_FmPcdEngine nextEngine; /**< may be BMI, PLCR or CC */
82174 + union { /**< depends on nextEngine */
82175 + e_FmPcdDoneAction doneAction; /**< Used when next engine is BMI (done) */
82176 + t_FmPcdKgPlcrProfile plcrProfile; /**< Used when next engine is PLCR */
82177 + t_FmPcdKgCc cc; /**< Used when next engine is CC */
82178 + } kgNextEngineParams;
82179 + t_FmPcdKgSchemeCounter schemeCounter; /**< A structure of parameters for updating
82180 + the scheme counter */
82181 +} t_FmPcdKgSchemeParams;
82182 +
82183 +/**************************************************************************//**
82184 + @Collection Definitions for CC statistics
82185 +*//***************************************************************************/
82186 +#if (DPAA_VERSION >= 11)
82187 +#define FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
82188 +#define FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
82189 +#endif /* (DPAA_VERSION >= 11) */
82190 +#define FM_PCD_CC_STATS_COUNTER_SIZE 4 /* Size in bytes of a frame length range counter */
82191 +/* @} */
82192 +
82193 +/**************************************************************************//**
82194 + @Description Parameters for defining CC as the next engine after a CC node.
82195 +*//***************************************************************************/
82196 +typedef struct t_FmPcdCcNextCcParams {
82197 + t_Handle h_CcNode; /**< A handle of the next CC node */
82198 +} t_FmPcdCcNextCcParams;
82199 +
82200 +#if (DPAA_VERSION >= 11)
82201 +/**************************************************************************//**
82202 + @Description Parameters for defining Frame replicator as the next engine after a CC node.
82203 +*//***************************************************************************/
82204 +typedef struct t_FmPcdCcNextFrParams {
82205 + t_Handle h_FrmReplic; /**< A handle of the next frame replicator group */
82206 +} t_FmPcdCcNextFrParams;
82207 +#endif /* (DPAA_VERSION >= 11) */
82208 +
82209 +/**************************************************************************//**
82210 + @Description Parameters for defining Policer as the next engine after a CC node.
82211 +*//***************************************************************************/
82212 +typedef struct t_FmPcdCcNextPlcrParams {
82213 + bool overrideParams; /**< TRUE if CC override previously decided parameters*/
82214 + bool sharedProfile; /**< Relevant only if overrideParams=TRUE:
82215 + TRUE if this profile is shared between ports */
82216 + uint16_t newRelativeProfileId; /**< Relevant only if overrideParams=TRUE:
82217 + (otherwise profile id is taken from KeyGen);
82218 + This parameter should indicate the policer
82219 + profile offset within the port's
82220 + policer profiles or from SHARED window.*/
82221 + uint32_t newFqid; /**< Relevant only if overrideParams=TRUE:
82222 + FQID for enqueuing the frame;
82223 + In earlier chips if policer next engine is KEYGEN,
82224 + this parameter can be 0, because the KEYGEN
82225 + always decides the enqueue FQID.*/
82226 +#if (DPAA_VERSION >= 11)
82227 + uint8_t newRelativeStorageProfileId;
82228 + /**< Indicates the relative storage profile offset within
82229 + the port's storage profiles window;
82230 + Relevant only if the port was configured with VSP. */
82231 +#endif /* (DPAA_VERSION >= 11) */
82232 +} t_FmPcdCcNextPlcrParams;
82233 +
82234 +/**************************************************************************//**
82235 + @Description Parameters for defining enqueue as the next action after a CC node.
82236 +*//***************************************************************************/
82237 +typedef struct t_FmPcdCcNextEnqueueParams {
82238 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82239 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82240 + relevant if action = e_FM_PCD_ENQ_FRAME */
82241 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82242 + (otherwise FQID is taken from KeyGen),
82243 + relevant if action = e_FM_PCD_ENQ_FRAME */
82244 +#if (DPAA_VERSION >= 11)
82245 + uint8_t newRelativeStorageProfileId;
82246 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82247 + storage profile offset within the port's storage profiles
82248 + window; Relevant only if the port was configured with VSP. */
82249 +#endif /* (DPAA_VERSION >= 11) */
82250 +} t_FmPcdCcNextEnqueueParams;
82251 +
82252 +/**************************************************************************//**
82253 + @Description Parameters for defining KeyGen as the next engine after a CC node.
82254 +*//***************************************************************************/
82255 +typedef struct t_FmPcdCcNextKgParams {
82256 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82257 + Note - this parameters irrelevant for earlier chips */
82258 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82259 + (otherwise FQID is taken from KeyGen),
82260 + Note - this parameters irrelevant for earlier chips */
82261 +#if (DPAA_VERSION >= 11)
82262 + uint8_t newRelativeStorageProfileId;
82263 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82264 + storage profile offset within the port's storage profiles
82265 + window; Relevant only if the port was configured with VSP. */
82266 +#endif /* (DPAA_VERSION >= 11) */
82267 +
82268 + t_Handle h_DirectScheme; /**< Direct scheme handle to go to. */
82269 +} t_FmPcdCcNextKgParams;
82270 +
82271 +/**************************************************************************//**
82272 + @Description Parameters for defining the next engine after a CC node.
82273 +*//***************************************************************************/
82274 +typedef struct t_FmPcdCcNextEngineParams {
82275 + e_FmPcdEngine nextEngine; /**< User has to initialize parameters
82276 + according to nextEngine definition */
82277 + union {
82278 + t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */
82279 + t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */
82280 + t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */
82281 + t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */
82282 +#if (DPAA_VERSION >= 11)
82283 + t_FmPcdCcNextFrParams frParams; /**< Parameters in case next engine is FR */
82284 +#endif /* (DPAA_VERSION >= 11) */
82285 + } params; /**< union used for all the next-engine parameters options */
82286 +
82287 + t_Handle h_Manip; /**< Handle to Manipulation object.
82288 + Relevant if next engine is of type result
82289 + (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */
82290 +
82291 + bool statisticsEn; /**< If TRUE, statistics counters are incremented
82292 + for each frame passing through this
82293 + Coarse Classification entry. */
82294 +} t_FmPcdCcNextEngineParams;
82295 +
82296 +/**************************************************************************//**
82297 + @Description Parameters for defining a single CC key
82298 +*//***************************************************************************/
82299 +typedef struct t_FmPcdCcKeyParams {
82300 + uint8_t *p_Key; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82301 + pointer to the key of the size defined in keySize */
82302 + uint8_t *p_Mask; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82303 + pointer to the Mask per key of the size defined
82304 + in keySize. p_Key and p_Mask (if defined) has to be
82305 + of the same size defined in the keySize;
82306 + NOTE that if this value is equal for all entries whithin
82307 + this table, the driver will automatically use global-mask
82308 + (i.e. one common mask for all entries) instead of private
82309 + one; that is done in order to spare some memory and for
82310 + better performance. */
82311 + t_FmPcdCcNextEngineParams ccNextEngineParams;
82312 + /**< parameters for the next for the defined Key in
82313 + the p_Key */
82314 +} t_FmPcdCcKeyParams;
82315 +
82316 +/**************************************************************************//**
82317 + @Description Parameters for defining CC keys parameters
82318 + The driver supports two methods for CC node allocation: dynamic and static.
82319 + Static mode was created in order to prevent runtime alloc/free
82320 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
82321 + the driver automatically allocates the memory according to
82322 + 'maxNumOfKeys' parameter. The driver calculates the maximal memory
82323 + size that may be used for this CC-Node taking into consideration
82324 + 'maskSupport' and 'statisticsMode' parameters.
82325 + When 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
82326 + parameters of this node, 'maxNumOfKeys' must be equal to 'numOfKeys'.
82327 + In dynamic mode, 'maxNumOfKeys' must be zero. At initialization,
82328 + all required structures are allocated according to 'numOfKeys'
82329 + parameter. During runtime modification, these structures are
82330 + re-allocated according to the updated number of keys.
82331 +
82332 + Please note that 'action' and 'icIndxMask' mentioned in the
82333 + specific parameter explanations are passed in the extraction
82334 + parameters of the node (fields of extractCcParams.extractNonHdr).
82335 +*//***************************************************************************/
82336 +typedef struct t_KeysParams {
82337 + uint16_t maxNumOfKeys; /**< Maximum number of keys that will (ever) be used in this CC-Node;
82338 + A value of zero may be used for dynamic memory allocation. */
82339 + bool maskSupport; /**< This parameter is relevant only if a node is initialized with
82340 + 'action' = e_FM_PCD_ACTION_EXACT_MATCH and maxNumOfKeys > 0;
82341 + Should be TRUE to reserve table memory for key masks, even if
82342 + initial keys do not contain masks, or if the node was initialized
82343 + as 'empty' (without keys); this will allow user to add keys with
82344 + masks at runtime.
82345 + NOTE that if user want to use only global-masks (i.e. one common mask
82346 + for all the entries within this table, this parameter should set to 'FALSE'. */
82347 + e_FmPcdCcStatsMode statisticsMode; /**< Determines the supported statistics mode for all node's keys.
82348 + To enable statistics gathering, statistics should be enabled per
82349 + every key, using 'statisticsEn' in next engine parameters structure
82350 + of that key;
82351 + If 'maxNumOfKeys' is set, all required structures will be
82352 + preallocated for all keys. */
82353 +#if (DPAA_VERSION >= 11)
82354 + uint16_t frameLengthRanges[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82355 + /**< Relevant only for 'RMON' statistics mode
82356 + (this feature is supported only on B4860 device);
82357 + Holds a list of programmable thresholds - for each received frame,
82358 + its length in bytes is examined against these range thresholds and
82359 + the appropriate counter is incremented by 1 - for example, to belong
82360 + to range i, the following should hold:
82361 + range i-1 threshold < frame length <= range i threshold
82362 + Each range threshold must be larger then its preceding range
82363 + threshold, and last range threshold must be 0xFFFF. */
82364 +#endif /* (DPAA_VERSION >= 11) */
82365 + uint16_t numOfKeys; /**< Number of initial keys;
82366 + Note that in case of 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP,
82367 + this field should be power-of-2 of the number of bits that are
82368 + set in 'icIndxMask'. */
82369 + uint8_t keySize; /**< Size of key - for extraction of type FULL_FIELD, 'keySize' has
82370 + to be the standard size of the selected key; For other extraction
82371 + types, 'keySize' has to be as size of extraction; When 'action' =
82372 + e_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
82373 + t_FmPcdCcKeyParams keyParams[FM_PCD_MAX_NUM_OF_KEYS];
82374 + /**< An array with 'numOfKeys' entries, each entry specifies the
82375 + corresponding key parameters;
82376 + When 'action' = e_FM_PCD_ACTION_EXACT_MATCH, this value must not
82377 + exceed 255 (FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
82378 + for the 'miss' entry. */
82379 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss;
82380 + /**< Parameters for defining the next engine when a key is not matched;
82381 + Not relevant if action = e_FM_PCD_ACTION_INDEXED_LOOKUP. */
82382 +} t_KeysParams;
82383 +
82384 +
82385 +/**************************************************************************//**
82386 + @Description Parameters for defining a CC node
82387 +*//***************************************************************************/
82388 +typedef struct t_FmPcdCcNodeParams {
82389 + t_FmPcdExtractEntry extractCcParams; /**< Extraction parameters */
82390 + t_KeysParams keysParams; /**< Keys definition matching the selected extraction */
82391 +} t_FmPcdCcNodeParams;
82392 +
82393 +/**************************************************************************//**
82394 + @Description Parameters for defining a hash table
82395 +*//***************************************************************************/
82396 +typedef struct t_FmPcdHashTableParams {
82397 + uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
82398 + e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
82399 + requested statistics mode will be allocated according to maxNumOfKeys. */
82400 + uint8_t kgHashShift; /**< KG-Hash-shift as it was configured in the KG-scheme
82401 + that leads to this hash-table. */
82402 + uint16_t hashResMask; /**< Mask that will be used on the hash-result;
82403 + The number-of-sets for this hash will be calculated
82404 + as (2^(number of bits set in 'hashResMask'));
82405 + The 4 lower bits must be cleared. */
82406 + uint8_t hashShift; /**< Byte offset from the beginning of the KeyGen hash result to the
82407 + 2-bytes to be used as hash index. */
82408 + uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */
82409 +
82410 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */
82411 +
82412 +} t_FmPcdHashTableParams;
82413 +
82414 +/**************************************************************************//**
82415 + @Description Parameters for defining a CC tree group.
82416 +
82417 + This structure defines a CC group in terms of NetEnv units
82418 + and the action to be taken in each case. The unitIds list must
82419 + be given in order from low to high indices.
82420 +
82421 + t_FmPcdCcNextEngineParams is a list of 2^numOfDistinctionUnits
82422 + structures where each defines the next action to be taken for
82423 + each units combination. for example:
82424 + numOfDistinctionUnits = 2
82425 + unitIds = {1,3}
82426 + p_NextEnginePerEntriesInGrp[0] = t_FmPcdCcNextEngineParams for the case that
82427 + unit 1 - not found; unit 3 - not found;
82428 + p_NextEnginePerEntriesInGrp[1] = t_FmPcdCcNextEngineParams for the case that
82429 + unit 1 - not found; unit 3 - found;
82430 + p_NextEnginePerEntriesInGrp[2] = t_FmPcdCcNextEngineParams for the case that
82431 + unit 1 - found; unit 3 - not found;
82432 + p_NextEnginePerEntriesInGrp[3] = t_FmPcdCcNextEngineParams for the case that
82433 + unit 1 - found; unit 3 - found;
82434 +*//***************************************************************************/
82435 +typedef struct t_FmPcdCcGrpParams {
82436 + uint8_t numOfDistinctionUnits; /**< Up to 4 */
82437 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_CC_UNITS];
82438 + /**< Indices of the units as defined in
82439 + FM_PCD_NetEnvCharacteristicsSet() */
82440 + t_FmPcdCcNextEngineParams nextEnginePerEntriesInGrp[FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
82441 + /**< Maximum entries per group is 16 */
82442 +} t_FmPcdCcGrpParams;
82443 +
82444 +/**************************************************************************//**
82445 + @Description Parameters for defining CC tree groups
82446 +*//***************************************************************************/
82447 +typedef struct t_FmPcdCcTreeParams {
82448 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
82449 + by FM_PCD_NetEnvCharacteristicsSet() */
82450 + uint8_t numOfGrps; /**< Number of CC groups within the CC tree */
82451 + t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
82452 + /**< Parameters for each group. */
82453 +} t_FmPcdCcTreeParams;
82454 +
82455 +
82456 +/**************************************************************************//**
82457 + @Description CC key statistics structure
82458 +*//***************************************************************************/
82459 +typedef struct t_FmPcdCcKeyStatistics {
82460 + uint32_t byteCount; /**< This counter reflects byte count of frames that
82461 + were matched by this key. */
82462 + uint32_t frameCount; /**< This counter reflects count of frames that
82463 + were matched by this key. */
82464 +#if (DPAA_VERSION >= 11)
82465 + uint32_t frameLengthRangeCount[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82466 + /**< These counters reflect how many frames matched
82467 + this key in 'RMON' statistics mode:
82468 + Each counter holds the number of frames of a
82469 + specific frames length range, according to the
82470 + ranges provided at initialization. */
82471 +#endif /* (DPAA_VERSION >= 11) */
82472 +} t_FmPcdCcKeyStatistics;
82473 +
82474 +/**************************************************************************//**
82475 + @Description Parameters for defining policer byte rate
82476 +*//***************************************************************************/
82477 +typedef struct t_FmPcdPlcrByteRateModeParams {
82478 + e_FmPcdPlcrFrameLengthSelect frameLengthSelection; /**< Frame length selection */
82479 + e_FmPcdPlcrRollBackFrameSelect rollBackFrameSelection; /**< relevant option only e_FM_PCD_PLCR_L2_FRM_LEN,
82480 + e_FM_PCD_PLCR_FULL_FRM_LEN */
82481 +} t_FmPcdPlcrByteRateModeParams;
82482 +
82483 +/**************************************************************************//**
82484 + @Description Parameters for defining the policer profile (based on
82485 + RFC-2698 or RFC-4115 attributes).
82486 +*//***************************************************************************/
82487 +typedef struct t_FmPcdPlcrNonPassthroughAlgParams {
82488 + e_FmPcdPlcrRateMode rateMode; /**< Byte mode or Packet mode */
82489 + t_FmPcdPlcrByteRateModeParams byteModeParams; /**< Valid for Byte NULL for Packet */
82490 + uint32_t committedInfoRate; /**< KBits/Second or Packets/Second */
82491 + uint32_t committedBurstSize; /**< Bytes/Packets */
82492 + uint32_t peakOrExcessInfoRate; /**< KBits/Second or Packets/Second */
82493 + uint32_t peakOrExcessBurstSize; /**< Bytes/Packets */
82494 +} t_FmPcdPlcrNonPassthroughAlgParams;
82495 +
82496 +/**************************************************************************//**
82497 + @Description Parameters for defining the next engine after policer
82498 +*//***************************************************************************/
82499 +typedef union u_FmPcdPlcrNextEngineParams {
82500 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82501 + t_Handle h_Profile; /**< Policer profile handle - used when next engine
82502 + is Policer, must be a SHARED profile */
82503 + t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is KeyGen */
82504 +} u_FmPcdPlcrNextEngineParams;
82505 +
82506 +/**************************************************************************//**
82507 + @Description Parameters for defining the policer profile entry
82508 +*//***************************************************************************/
82509 +typedef struct t_FmPcdPlcrProfileParams {
82510 + bool modify; /**< TRUE to change an existing profile */
82511 + union {
82512 + struct {
82513 + e_FmPcdProfileTypeSelection profileType; /**< Type of policer profile */
82514 + t_Handle h_FmPort; /**< Relevant for per-port profiles only */
82515 + uint16_t relativeProfileId; /**< Profile id - relative to shared group or to port */
82516 + } newParams; /**< use it when modify = FALSE */
82517 + t_Handle h_Profile; /**< A handle to a profile - use it when modify=TRUE */
82518 + } id;
82519 + e_FmPcdPlcrAlgorithmSelection algSelection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
82520 + e_FmPcdPlcrColorMode colorMode; /**< COLOR_BLIND, COLOR_AWARE */
82521 +
82522 + union {
82523 + e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode; the policer will re-color
82524 + any incoming packet with the default value. */
82525 + e_FmPcdPlcrColor override; /**< For Color-Aware modes; the profile response to a
82526 + pre-color value of 2'b11. */
82527 + } color;
82528 +
82529 + t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 parameters */
82530 +
82531 + e_FmPcdEngine nextEngineOnGreen; /**< Next engine for green-colored frames */
82532 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Next engine parameters for green-colored frames */
82533 +
82534 + e_FmPcdEngine nextEngineOnYellow; /**< Next engine for yellow-colored frames */
82535 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Next engine parameters for yellow-colored frames */
82536 +
82537 + e_FmPcdEngine nextEngineOnRed; /**< Next engine for red-colored frames */
82538 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Next engine parameters for red-colored frames */
82539 +
82540 + bool trapProfileOnFlowA; /**< Obsolete - do not use */
82541 + bool trapProfileOnFlowB; /**< Obsolete - do not use */
82542 + bool trapProfileOnFlowC; /**< Obsolete - do not use */
82543 +} t_FmPcdPlcrProfileParams;
82544 +
82545 +/**************************************************************************//**
82546 + @Description Parameters for selecting a location for requested manipulation
82547 +*//***************************************************************************/
82548 +typedef struct t_FmManipHdrInfo {
82549 + e_NetHeaderType hdr; /**< Header selection */
82550 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
82551 + bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/
82552 + t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */
82553 +} t_FmManipHdrInfo;
82554 +
82555 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82556 +/**************************************************************************//**
82557 + @Description Parameters for defining an insertion manipulation
82558 + of type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE
82559 +*//***************************************************************************/
82560 +typedef struct t_FmPcdManipHdrInsrtByTemplateParams {
82561 + uint8_t size; /**< Size of insert template to the start of the frame. */
82562 + uint8_t hdrTemplate[FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE];
82563 + /**< Array of the insertion template. */
82564 +
82565 + bool modifyOuterIp; /**< TRUE if user want to modify some fields in outer IP. */
82566 + struct {
82567 + uint16_t ipOuterOffset; /**< Offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/
82568 + uint16_t dscpEcn; /**< value of dscpEcn in IP outer, relevant if modifyOuterIp = TRUE.
82569 + in IPV4 dscpEcn only byte - it has to be adjusted to the right*/
82570 + bool udpPresent; /**< TRUE if UDP is present in the insert template, relevant if modifyOuterIp = TRUE.*/
82571 + uint8_t udpOffset; /**< Offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/
82572 + uint8_t ipIdentGenId; /**< Used by FMan-CTRL to calculate IP-identification field,relevant if modifyOuterIp = TRUE.*/
82573 + 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.*/
82574 + struct {
82575 + uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP Total Length field.*/
82576 + uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length*/
82577 + uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length.*/
82578 + } recalculateLengthParams; /**< Recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */
82579 + } modifyOuterIpParams; /**< Outer IP modification parameters - ignored if modifyOuterIp is FALSE */
82580 +
82581 + bool modifyOuterVlan; /**< TRUE if user wants to modify VPri field in the outer VLAN header*/
82582 + struct {
82583 + uint8_t vpri; /**< Value of VPri, relevant if modifyOuterVlan = TRUE
82584 + VPri only 3 bits, it has to be adjusted to the right*/
82585 + } modifyOuterVlanParams;
82586 +} t_FmPcdManipHdrInsrtByTemplateParams;
82587 +
82588 +/**************************************************************************//**
82589 + @Description Parameters for defining CAPWAP fragmentation
82590 +*//***************************************************************************/
82591 +typedef struct t_CapwapFragmentationParams {
82592 + uint16_t sizeForFragmentation; /**< if length of the frame is greater than this value, CAPWAP fragmentation will be executed.*/
82593 + bool headerOptionsCompr; /**< TRUE - first fragment include the CAPWAP header options field,
82594 + and all other fragments exclude the CAPWAP options field,
82595 + FALSE - all fragments include CAPWAP header options field. */
82596 +} t_CapwapFragmentationParams;
82597 +
82598 +/**************************************************************************//**
82599 + @Description Parameters for defining CAPWAP reassembly
82600 +*//***************************************************************************/
82601 +typedef struct t_CapwapReassemblyParams {
82602 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be reassembled concurrently; must be power of 2.
82603 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82604 + maxNumFramesInProcess has to be in the range of 4 - 512,
82605 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82606 + maxNumFramesInProcess has to be in the range of 8 - 2048 */
82607 + bool haltOnDuplicationFrag; /**< If TRUE, reassembly process will be halted due to duplicated fragment,
82608 + and all processed fragments will be enqueued with error indication;
82609 + If FALSE, only duplicated fragments will be enqueued with error indication. */
82610 +
82611 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by the reassembly process */
82612 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process */
82613 + uint32_t timeoutRoutineRequestTime;
82614 + /**< Represents the time interval in microseconds between consecutive
82615 + timeout routine requests It has to be power of 2. */
82616 + uint32_t timeoutThresholdForReassmProcess;
82617 + /**< Time interval (microseconds) for marking frames in process as too old;
82618 + Frames in process are those for which at least one fragment was received
82619 + but not all fragments. */
82620 +
82621 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry (needed for the reassembly process) */
82622 +} t_CapwapReassemblyParams;
82623 +
82624 +/**************************************************************************//**
82625 + @Description Parameters for defining fragmentation/reassembly manipulation
82626 +*//***************************************************************************/
82627 +typedef struct t_FmPcdManipFragOrReasmParams {
82628 + bool frag; /**< TRUE if using the structure for fragmentation,
82629 + otherwise this structure is used for reassembly */
82630 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82631 + Same LIODN number is used for these buffers as for
82632 + the received frames buffers, so buffers of this pool
82633 + need to be allocated in the same memory area as the
82634 + received buffers. If the received buffers arrive
82635 + from different sources, the Scatter/Gather BP id
82636 + should be mutual to all these sources. */
82637 + e_NetHeaderType hdr; /**< Header selection */
82638 + union {
82639 + t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation,
82640 + relevant if 'frag' = TRUE, 'hdr' = HEADER_TYPE_CAPWAP */
82641 + t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly,
82642 + relevant if 'frag' = FALSE, 'hdr' = HEADER_TYPE_CAPWAP */
82643 + } u;
82644 +} t_FmPcdManipFragOrReasmParams;
82645 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
82646 +
82647 +
82648 +/**************************************************************************//**
82649 + @Description Parameters for defining header removal by header type
82650 +*//***************************************************************************/
82651 +typedef struct t_FmPcdManipHdrRmvByHdrParams {
82652 + e_FmPcdManipHdrRmvByHdrType type; /**< Selection of header removal location */
82653 + union {
82654 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82655 + struct {
82656 + bool include; /**< If FALSE, remove until the specified header (not including the header);
82657 + If TRUE, remove also the specified header. */
82658 + t_FmManipHdrInfo hdrInfo;
82659 + } fromStartByHdr; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
82660 +#endif /* (DPAA_VERSION >= 11) || ... */
82661 +#if (DPAA_VERSION >= 11)
82662 + t_FmManipHdrInfo hdrInfo; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
82663 +#endif /* (DPAA_VERSION >= 11) */
82664 + e_FmPcdManipHdrRmvSpecificL2 specificL2; /**< Relevant when type = e_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
82665 + Defines which L2 headers to remove. */
82666 + } u;
82667 +} t_FmPcdManipHdrRmvByHdrParams;
82668 +
82669 +/**************************************************************************//**
82670 + @Description Parameters for configuring IP fragmentation manipulation
82671 +
82672 + Restrictions:
82673 + - IP Fragmentation output fragments must not be forwarded to application directly.
82674 + - Maximum number of fragments per frame is 16.
82675 + - Fragmentation of IP fragments is not supported.
82676 + - IPv4 packets containing header Option fields are fragmented by copying all option
82677 + fields to each fragment, regardless of the copy bit value.
82678 + - Transmit confirmation is not supported.
82679 + - Fragmentation after SEC can't handle S/G frames.
82680 + - Fragmentation nodes must be set as the last PCD action (i.e. the
82681 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
82682 + - Only BMan buffers shall be used for frames to be fragmented.
82683 + - IPF does not support VSP. Therefore, on the same port where we have IPF
82684 + we cannot support VSP.
82685 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
82686 + does not support VSP. Therefore, on the same port where we have IPF we
82687 + cannot support VSP.
82688 +*//***************************************************************************/
82689 +typedef struct t_FmPcdManipFragIpParams {
82690 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
82691 + IP fragmentation will be executed.*/
82692 +#if (DPAA_VERSION == 10)
82693 + uint8_t scratchBpid; /**< Absolute buffer pool id according to BM configuration.*/
82694 +#endif /* (DPAA_VERSION == 10) */
82695 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
82696 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
82697 + received frame's buffer. */
82698 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82699 + This parameters is relevant when 'sgBpidEn=TRUE';
82700 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
82701 + of this pool need to be allocated in the same memory area as the received buffers.
82702 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
82703 + mutual to all these sources. */
82704 + e_FmPcdManipDontFragAction dontFragAction; /**< Don't Fragment Action - If an IP packet is larger
82705 + than MTU and its DF bit is set, then this field will
82706 + determine the action to be taken.*/
82707 +} t_FmPcdManipFragIpParams;
82708 +
82709 +/**************************************************************************//**
82710 + @Description Parameters for configuring IP reassembly manipulation.
82711 +
82712 + This is a common structure for both IPv4 and IPv6 reassembly
82713 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
82714 + set the 'hdr' field in t_FmPcdManipReassemParams to HEADER_TYPE_IPv6.
82715 +
82716 + Restrictions:
82717 + - Application must define at least one scheme to catch the reassembled frames.
82718 + - Maximum number of fragments per frame is 16.
82719 + - Reassembly of IPv4 fragments containing Option fields is supported.
82720 +
82721 +*//***************************************************************************/
82722 +typedef struct t_FmPcdManipReassemIpParams {
82723 + uint8_t relativeSchemeId[2]; /**< Partition relative scheme id:
82724 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
82725 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
82726 + NOTE: The following comment is relevant only for FMAN v2 devices:
82727 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
82728 + the user schemes id to ensure that the reassembly schemes will be first match;
82729 + Rest schemes, if defined, should have higher relative scheme ID. */
82730 +#if (DPAA_VERSION >= 11)
82731 + uint32_t nonConsistentSpFqid; /**< In case that other fragments of the frame corresponds to different storage
82732 + profile than the opening fragment (Non-Consistent-SP state)
82733 + then one of two possible scenarios occurs:
82734 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
82735 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
82736 +#else
82737 + uint8_t sgBpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
82738 +#endif /* (DPAA_VERSION >= 11) */
82739 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
82740 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
82741 + uint16_t minFragSize[2]; /**< Minimum fragment size:
82742 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
82743 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
82744 + /**< Number of frames per hash entry needed for reassembly process:
82745 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
82746 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_FM_PCD_MANIP_SIX_WAYS_HASH). */
82747 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time;
82748 + Must be power of 2;
82749 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82750 + maxNumFramesInProcess has to be in the range of 4 - 512;
82751 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82752 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
82753 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
82754 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
82755 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
82756 + uint32_t timeoutThresholdForReassmProcess;
82757 + /**< Represents the time interval in microseconds which defines
82758 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
82759 +} t_FmPcdManipReassemIpParams;
82760 +
82761 +/**************************************************************************//**
82762 + @Description structure for defining IPSEC manipulation
82763 +*//***************************************************************************/
82764 +typedef struct t_FmPcdManipSpecialOffloadIPSecParams {
82765 + bool decryption; /**< TRUE if being used in decryption direction;
82766 + FALSE if being used in encryption direction. */
82767 + bool ecnCopy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
82768 + (direction depends on the 'decryption' field). */
82769 + bool dscpCopy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
82770 + (direction depends on the 'decryption' field). */
82771 + bool variableIpHdrLen; /**< TRUE for supporting variable IP header length in decryption. */
82772 + bool variableIpVersion; /**< TRUE for supporting both IP version on the same SA in encryption */
82773 + uint8_t outerIPHdrLen; /**< if 'variableIpVersion == TRUE' then this field must be set to non-zero value;
82774 + It is specifies the length of the outer IP header that was configured in the
82775 + corresponding SA. */
82776 + uint16_t arwSize; /**< if <> '0' then will perform ARW check for this SA;
82777 + The value must be a multiplication of 16 */
82778 + uintptr_t arwAddr; /**< if arwSize <> '0' then this field must be set to non-zero value;
82779 + MUST be allocated from FMAN's MURAM that the post-sec op-port belongs to;
82780 + Must be 4B aligned. Required MURAM size is 'NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
82781 +} t_FmPcdManipSpecialOffloadIPSecParams;
82782 +
82783 +#if (DPAA_VERSION >= 11)
82784 +/**************************************************************************//**
82785 + @Description Parameters for configuring CAPWAP fragmentation manipulation
82786 +
82787 + Restrictions:
82788 + - Maximum number of fragments per frame is 16.
82789 + - Transmit confirmation is not supported.
82790 + - Fragmentation nodes must be set as the last PCD action (i.e. the
82791 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
82792 + - Only BMan buffers shall be used for frames to be fragmented.
82793 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
82794 + does not support VSP. Therefore, on the same port where we have IPF we
82795 + cannot support VSP.
82796 +*//***************************************************************************/
82797 +typedef struct t_FmPcdManipFragCapwapParams {
82798 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
82799 + CAPWAP fragmentation will be executed.*/
82800 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
82801 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
82802 + received frame's buffer. */
82803 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82804 + This parameters is relevant when 'sgBpidEn=TRUE';
82805 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
82806 + of this pool need to be allocated in the same memory area as the received buffers.
82807 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
82808 + mutual to all these sources. */
82809 + bool compressModeEn; /**< CAPWAP Header Options Compress Enable mode;
82810 + When this mode is enabled then only the first fragment include the CAPWAP header options
82811 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
82812 + options field (CAPWAP header is updated accordingly).*/
82813 +} t_FmPcdManipFragCapwapParams;
82814 +
82815 +/**************************************************************************//**
82816 + @Description Parameters for configuring CAPWAP reassembly manipulation.
82817 +
82818 + Restrictions:
82819 + - Application must define one scheme to catch the reassembled frames.
82820 + - Maximum number of fragments per frame is 16.
82821 +
82822 +*//***************************************************************************/
82823 +typedef struct t_FmPcdManipReassemCapwapParams {
82824 + uint8_t relativeSchemeId; /**< Partition relative scheme id;
82825 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
82826 + Rest schemes, if defined, should have higher relative scheme ID. */
82827 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
82828 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
82829 + uint16_t maxReassembledFrameLength;/**< The maximum CAPWAP reassembled frame length in bytes;
82830 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
82831 + considered as a valid length;
82832 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
82833 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
82834 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
82835 + /**< Number of frames per hash entry needed for reassembly process */
82836 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by reassembly in the same time;
82837 + Must be power of 2;
82838 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82839 + maxNumFramesInProcess has to be in the range of 4 - 512;
82840 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82841 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
82842 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
82843 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
82844 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
82845 + uint32_t timeoutThresholdForReassmProcess;
82846 + /**< Represents the time interval in microseconds which defines
82847 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
82848 +} t_FmPcdManipReassemCapwapParams;
82849 +
82850 +/**************************************************************************//**
82851 + @Description structure for defining CAPWAP manipulation
82852 +*//***************************************************************************/
82853 +typedef struct t_FmPcdManipSpecialOffloadCapwapParams {
82854 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
82855 + e_FmPcdManipHdrQosSrc qosSrc; /**< TODO */
82856 +} t_FmPcdManipSpecialOffloadCapwapParams;
82857 +
82858 +#endif /* (DPAA_VERSION >= 11) */
82859 +
82860 +
82861 +/**************************************************************************//**
82862 + @Description Parameters for defining special offload manipulation
82863 +*//***************************************************************************/
82864 +typedef struct t_FmPcdManipSpecialOffloadParams {
82865 + e_FmPcdManipSpecialOffloadType type; /**< Type of special offload manipulation */
82866 + union
82867 + {
82868 + t_FmPcdManipSpecialOffloadIPSecParams ipsec; /**< Parameters for IPSec; Relevant when
82869 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
82870 +#if (DPAA_VERSION >= 11)
82871 + t_FmPcdManipSpecialOffloadCapwapParams capwap; /**< Parameters for CAPWAP; Relevant when
82872 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
82873 +#endif /* (DPAA_VERSION >= 11) */
82874 + } u;
82875 +} t_FmPcdManipSpecialOffloadParams;
82876 +
82877 +/**************************************************************************//**
82878 + @Description Parameters for defining insertion manipulation
82879 +*//***************************************************************************/
82880 +typedef struct t_FmPcdManipHdrInsrt {
82881 + uint8_t size; /**< size of inserted section */
82882 + uint8_t *p_Data; /**< data to be inserted */
82883 +} t_FmPcdManipHdrInsrt;
82884 +
82885 +
82886 +/**************************************************************************//**
82887 + @Description Parameters for defining generic removal manipulation
82888 +*//***************************************************************************/
82889 +typedef struct t_FmPcdManipHdrRmvGenericParams {
82890 + uint8_t offset; /**< Offset from beginning of header to the start
82891 + location of the removal */
82892 + uint8_t size; /**< Size of removed section */
82893 +} t_FmPcdManipHdrRmvGenericParams;
82894 +
82895 +/**************************************************************************//**
82896 + @Description Parameters for defining generic insertion manipulation
82897 +*//***************************************************************************/
82898 +typedef struct t_FmPcdManipHdrInsrtGenericParams {
82899 + uint8_t offset; /**< Offset from beginning of header to the start
82900 + location of the insertion */
82901 + uint8_t size; /**< Size of inserted section */
82902 + bool replace; /**< TRUE to override (replace) existing data at
82903 + 'offset', FALSE to insert */
82904 + uint8_t *p_Data; /**< Pointer to data to be inserted */
82905 +} t_FmPcdManipHdrInsrtGenericParams;
82906 +
82907 +/**************************************************************************//**
82908 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
82909 +*//***************************************************************************/
82910 +typedef struct t_FmPcdManipHdrFieldUpdateVlanDscpToVpri {
82911 + uint8_t dscpToVpriTable[FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
82912 + /**< A table of VPri values for each DSCP value;
82913 + The index is the DSCP value (0-0x3F) and the
82914 + value is the corresponding VPRI (0-15). */
82915 + uint8_t vpriDefVal; /**< 0-7, Relevant only if if updateType =
82916 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
82917 + this field is the Q Tag default value if the
82918 + IP header is not found. */
82919 +} t_FmPcdManipHdrFieldUpdateVlanDscpToVpri;
82920 +
82921 +/**************************************************************************//**
82922 + @Description Parameters for defining header manipulation VLAN fields updates
82923 +*//***************************************************************************/
82924 +typedef struct t_FmPcdManipHdrFieldUpdateVlan {
82925 + e_FmPcdManipHdrFieldUpdateVlan updateType; /**< Selects VLAN update type */
82926 + union {
82927 + uint8_t vpri; /**< 0-7, Relevant only if If updateType =
82928 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
82929 + is the new VLAN pri. */
82930 + t_FmPcdManipHdrFieldUpdateVlanDscpToVpri dscpToVpri; /**< Parameters structure, Relevant only if updateType
82931 + = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
82932 + } u;
82933 +} t_FmPcdManipHdrFieldUpdateVlan;
82934 +
82935 +/**************************************************************************//**
82936 + @Description Parameters for defining header manipulation IPV4 fields updates
82937 +*//***************************************************************************/
82938 +typedef struct t_FmPcdManipHdrFieldUpdateIpv4 {
82939 + ipv4HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
82940 + uint8_t tos; /**< 8 bit New TOS; Relevant if validUpdates contains
82941 + HDR_MANIP_IPV4_TOS */
82942 + uint16_t id; /**< 16 bit New IP ID; Relevant only if validUpdates
82943 + contains HDR_MANIP_IPV4_ID */
82944 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if validUpdates
82945 + contains HDR_MANIP_IPV4_SRC */
82946 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if validUpdates
82947 + contains HDR_MANIP_IPV4_DST */
82948 +} t_FmPcdManipHdrFieldUpdateIpv4;
82949 +
82950 +/**************************************************************************//**
82951 + @Description Parameters for defining header manipulation IPV6 fields updates
82952 +*//***************************************************************************/
82953 +typedef struct t_FmPcdManipHdrFieldUpdateIpv6 {
82954 + ipv6HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
82955 + uint8_t trafficClass; /**< 8 bit New Traffic Class; Relevant if validUpdates contains
82956 + HDR_MANIP_IPV6_TC */
82957 + uint8_t src[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
82958 + /**< 16 byte new IP SRC; Relevant only if validUpdates
82959 + contains HDR_MANIP_IPV6_SRC */
82960 + uint8_t dst[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
82961 + /**< 16 byte new IP DST; Relevant only if validUpdates
82962 + contains HDR_MANIP_IPV6_DST */
82963 +} t_FmPcdManipHdrFieldUpdateIpv6;
82964 +
82965 +/**************************************************************************//**
82966 + @Description Parameters for defining header manipulation TCP/UDP fields updates
82967 +*//***************************************************************************/
82968 +typedef struct t_FmPcdManipHdrFieldUpdateTcpUdp {
82969 + tcpUdpHdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
82970 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if validUpdates
82971 + contains HDR_MANIP_TCP_UDP_SRC */
82972 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if validUpdates
82973 + contains HDR_MANIP_TCP_UDP_DST */
82974 +} t_FmPcdManipHdrFieldUpdateTcpUdp;
82975 +
82976 +/**************************************************************************//**
82977 + @Description Parameters for defining header manipulation fields updates
82978 +*//***************************************************************************/
82979 +typedef struct t_FmPcdManipHdrFieldUpdateParams {
82980 + e_FmPcdManipHdrFieldUpdateType type; /**< Type of header field update manipulation */
82981 + union {
82982 + t_FmPcdManipHdrFieldUpdateVlan vlan; /**< Parameters for VLAN update. Relevant when
82983 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
82984 + t_FmPcdManipHdrFieldUpdateIpv4 ipv4; /**< Parameters for IPv4 update. Relevant when
82985 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
82986 + t_FmPcdManipHdrFieldUpdateIpv6 ipv6; /**< Parameters for IPv6 update. Relevant when
82987 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
82988 + t_FmPcdManipHdrFieldUpdateTcpUdp tcpUdp; /**< Parameters for TCP/UDP update. Relevant when
82989 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
82990 + } u;
82991 +} t_FmPcdManipHdrFieldUpdateParams;
82992 +
82993 +
82994 +
82995 +/**************************************************************************//**
82996 + @Description Parameters for defining custom header manipulation for generic field replacement
82997 +*//***************************************************************************/
82998 +typedef struct t_FmPcdManipHdrCustomGenFieldReplace {
82999 + uint8_t srcOffset; /**< Location of new data - Offset from
83000 + Parse Result (>= 16, srcOffset+size <= 32, ) */
83001 + uint8_t dstOffset; /**< Location of data to be overwritten - Offset from
83002 + start of frame (dstOffset + size <= 256). */
83003 + uint8_t size; /**< The number of bytes (<=16) to be replaced */
83004 + uint8_t mask; /**< Optional 1 byte mask. Set to select bits for
83005 + replacement (1 - bit will be replaced);
83006 + Clear to use field as is. */
83007 + uint8_t maskOffset; /**< Relevant if mask != 0;
83008 + Mask offset within the replaces "size" */
83009 +} t_FmPcdManipHdrCustomGenFieldReplace;
83010 +
83011 +/**************************************************************************//**
83012 + @Description Parameters for defining custom header manipulation for IP replacement
83013 +*//***************************************************************************/
83014 +typedef struct t_FmPcdManipHdrCustomIpHdrReplace {
83015 + e_FmPcdManipHdrCustomIpReplace replaceType; /**< Selects replace update type */
83016 + bool decTtlHl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
83017 + bool updateIpv4Id; /**< Relevant when replaceType =
83018 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
83019 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
83020 + updateIpv4Id = TRUE */
83021 + uint8_t hdrSize; /**< The size of the new IP header */
83022 + uint8_t hdr[FM_PCD_MANIP_MAX_HDR_SIZE];
83023 + /**< The new IP header */
83024 +} t_FmPcdManipHdrCustomIpHdrReplace;
83025 +
83026 +/**************************************************************************//**
83027 + @Description Parameters for defining custom header manipulation
83028 +*//***************************************************************************/
83029 +typedef struct t_FmPcdManipHdrCustomParams {
83030 + e_FmPcdManipHdrCustomType type; /**< Type of header field update manipulation */
83031 + union {
83032 + t_FmPcdManipHdrCustomIpHdrReplace ipHdrReplace; /**< Parameters IP header replacement */
83033 + t_FmPcdManipHdrCustomGenFieldReplace genFieldReplace; /**< Parameters IP header replacement */
83034 + } u;
83035 +} t_FmPcdManipHdrCustomParams;
83036 +
83037 +/**************************************************************************//**
83038 + @Description Parameters for defining specific L2 insertion manipulation
83039 +*//***************************************************************************/
83040 +typedef struct t_FmPcdManipHdrInsrtSpecificL2Params {
83041 + e_FmPcdManipHdrInsrtSpecificL2 specificL2; /**< Selects which L2 headers to insert */
83042 + bool update; /**< TRUE to update MPLS header */
83043 + uint8_t size; /**< size of inserted section */
83044 + uint8_t *p_Data; /**< data to be inserted */
83045 +} t_FmPcdManipHdrInsrtSpecificL2Params;
83046 +
83047 +#if (DPAA_VERSION >= 11)
83048 +/**************************************************************************//**
83049 + @Description Parameters for defining IP insertion manipulation
83050 +*//***************************************************************************/
83051 +typedef struct t_FmPcdManipHdrInsrtIpParams {
83052 + bool calcL4Checksum; /**< Calculate L4 checksum. */
83053 + e_FmPcdManipHdrQosMappingMode mappingMode; /**< TODO */
83054 + uint8_t lastPidOffset; /**< the offset of the last Protocol within
83055 + the inserted header */
83056 + uint16_t id; /**< 16 bit New IP ID */
83057 + bool dontFragOverwrite;
83058 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
83059 + * This byte is configured to be overwritten when RPD is set. */
83060 + uint8_t lastDstOffset;
83061 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
83062 + * in order to calculate UDP checksum pseudo header;
83063 + * Otherwise set it to '0'. */
83064 + t_FmPcdManipHdrInsrt insrt; /**< size and data to be inserted. */
83065 +} t_FmPcdManipHdrInsrtIpParams;
83066 +#endif /* (DPAA_VERSION >= 11) */
83067 +
83068 +/**************************************************************************//**
83069 + @Description Parameters for defining header insertion manipulation by header type
83070 +*//***************************************************************************/
83071 +typedef struct t_FmPcdManipHdrInsrtByHdrParams {
83072 + e_FmPcdManipHdrInsrtByHdrType type; /**< Selects manipulation type */
83073 + union {
83074 +
83075 + t_FmPcdManipHdrInsrtSpecificL2Params specificL2Params;
83076 + /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
83077 + Selects which L2 headers to insert */
83078 +#if (DPAA_VERSION >= 11)
83079 + t_FmPcdManipHdrInsrtIpParams ipParams; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
83080 + t_FmPcdManipHdrInsrt insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
83081 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
83082 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
83083 +#endif /* (DPAA_VERSION >= 11) */
83084 + } u;
83085 +} t_FmPcdManipHdrInsrtByHdrParams;
83086 +
83087 +/**************************************************************************//**
83088 + @Description Parameters for defining header insertion manipulation
83089 +*//***************************************************************************/
83090 +typedef struct t_FmPcdManipHdrInsrtParams {
83091 + e_FmPcdManipHdrInsrtType type; /**< Type of insertion manipulation */
83092 + union {
83093 + t_FmPcdManipHdrInsrtByHdrParams byHdr; /**< Parameters for defining header insertion manipulation by header type,
83094 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_HDR */
83095 + t_FmPcdManipHdrInsrtGenericParams generic; /**< Parameters for defining generic header insertion manipulation,
83096 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_GENERIC */
83097 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83098 + t_FmPcdManipHdrInsrtByTemplateParams byTemplate; /**< Parameters for defining header insertion manipulation by template,
83099 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
83100 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83101 + } u;
83102 +} t_FmPcdManipHdrInsrtParams;
83103 +
83104 +/**************************************************************************//**
83105 + @Description Parameters for defining header removal manipulation
83106 +*//***************************************************************************/
83107 +typedef struct t_FmPcdManipHdrRmvParams {
83108 + e_FmPcdManipHdrRmvType type; /**< Type of header removal manipulation */
83109 + union {
83110 + t_FmPcdManipHdrRmvByHdrParams byHdr; /**< Parameters for defining header removal manipulation by header type,
83111 + relevant if type = e_FM_PCD_MANIP_RMV_BY_HDR */
83112 + t_FmPcdManipHdrRmvGenericParams generic; /**< Parameters for defining generic header removal manipulation,
83113 + relevant if type = e_FM_PCD_MANIP_RMV_GENERIC */
83114 + } u;
83115 +} t_FmPcdManipHdrRmvParams;
83116 +
83117 +/**************************************************************************//**
83118 + @Description Parameters for defining header manipulation node
83119 +*//***************************************************************************/
83120 +typedef struct t_FmPcdManipHdrParams {
83121 + bool rmv; /**< TRUE, to define removal manipulation */
83122 + t_FmPcdManipHdrRmvParams rmvParams; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
83123 +
83124 + bool insrt; /**< TRUE, to define insertion manipulation */
83125 + t_FmPcdManipHdrInsrtParams insrtParams; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
83126 +
83127 + bool fieldUpdate; /**< TRUE, to define field update manipulation */
83128 + t_FmPcdManipHdrFieldUpdateParams fieldUpdateParams; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
83129 +
83130 + bool custom; /**< TRUE, to define custom manipulation */
83131 + t_FmPcdManipHdrCustomParams customParams; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
83132 +
83133 + bool dontParseAfterManip;/**< TRUE to de-activate the parser after the manipulation defined in this node.
83134 + Restrictions:
83135 + 1. MUST be set if the next engine after the CC is not another CC node
83136 + (but rather Policer or Keygen), and this is the last (no h_NextManip) in a chain
83137 + of manipulation nodes. This includes single nodes (i.e. no h_NextManip and
83138 + also never pointed as h_NextManip of other manipulation nodes)
83139 + 2. MUST be set if the next engine after the CC is another CC node, and
83140 + this is NOT the last manipulation node (i.e. it has h_NextManip).*/
83141 +} t_FmPcdManipHdrParams;
83142 +
83143 +/**************************************************************************//**
83144 + @Description Parameters for defining fragmentation manipulation
83145 +*//***************************************************************************/
83146 +typedef struct t_FmPcdManipFragParams {
83147 + e_NetHeaderType hdr; /**< Header selection */
83148 + union {
83149 +#if (DPAA_VERSION >= 11)
83150 + t_FmPcdManipFragCapwapParams capwapFrag; /**< Parameters for defining CAPWAP fragmentation,
83151 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
83152 +#endif /* (DPAA_VERSION >= 11) */
83153 + t_FmPcdManipFragIpParams ipFrag; /**< Parameters for defining IP fragmentation,
83154 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83155 + } u;
83156 +} t_FmPcdManipFragParams;
83157 +
83158 +/**************************************************************************//**
83159 + @Description Parameters for defining reassembly manipulation
83160 +*//***************************************************************************/
83161 +typedef struct t_FmPcdManipReassemParams {
83162 + e_NetHeaderType hdr; /**< Header selection */
83163 + union {
83164 +#if (DPAA_VERSION >= 11)
83165 + t_FmPcdManipReassemCapwapParams capwapReassem; /**< Parameters for defining CAPWAP reassembly,
83166 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
83167 +#endif /* (DPAA_VERSION >= 11) */
83168 +
83169 + t_FmPcdManipReassemIpParams ipReassem; /**< Parameters for defining IP reassembly,
83170 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83171 + } u;
83172 +} t_FmPcdManipReassemParams;
83173 +
83174 +/**************************************************************************//**
83175 + @Description Parameters for defining a manipulation node
83176 +*//***************************************************************************/
83177 +typedef struct t_FmPcdManipParams {
83178 + e_FmPcdManipType type; /**< Selects type of manipulation node */
83179 + union{
83180 + t_FmPcdManipHdrParams hdr; /**< Parameters for defining header manipulation node */
83181 + t_FmPcdManipReassemParams reassem; /**< Parameters for defining reassembly manipulation node */
83182 + t_FmPcdManipFragParams frag; /**< Parameters for defining fragmentation manipulation node */
83183 + t_FmPcdManipSpecialOffloadParams specialOffload; /**< Parameters for defining special offload manipulation node */
83184 + } u;
83185 +
83186 + t_Handle h_NextManip; /**< Supported for Header Manipulation only;
83187 + Handle to another (previously defined) manipulation node;
83188 + Allows concatenation of manipulation actions;
83189 + This parameter is optional and may be NULL. */
83190 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83191 + bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */
83192 + t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation,
83193 + relevant if fragOrReasm = TRUE */
83194 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83195 +} t_FmPcdManipParams;
83196 +
83197 +/**************************************************************************//**
83198 + @Description Structure for retrieving IP reassembly statistics
83199 +*//***************************************************************************/
83200 +typedef struct t_FmPcdManipReassemIpStats {
83201 + /* common counters for both IPv4 and IPv6 */
83202 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83203 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83204 + a Reassembly Frame Descriptor */
83205 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83206 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83207 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83208 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83209 +#if (DPAA_VERSION >= 11)
83210 + uint32_t nonConsistentSp; /**< Counts the number of Non Consistent Storage Profile events for
83211 + successfully reassembled frames */
83212 +#endif /* (DPAA_VERSION >= 11) */
83213 + struct {
83214 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83215 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83216 + have been processed for all frames */
83217 + uint32_t processedFragments; /**< Counts the number of processed fragments
83218 + (valid and error fragments) for all frames */
83219 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83220 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83221 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83222 + to access an IP-Reassembly Automatic Learning Hash set */
83223 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83224 + exceeds 16 */
83225 + } specificHdrStatistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
83226 +} t_FmPcdManipReassemIpStats;
83227 +
83228 +/**************************************************************************//**
83229 + @Description Structure for retrieving IP fragmentation statistics
83230 +*//***************************************************************************/
83231 +typedef struct t_FmPcdManipFragIpStats {
83232 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83233 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83234 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83235 +} t_FmPcdManipFragIpStats;
83236 +
83237 +#if (DPAA_VERSION >= 11)
83238 +/**************************************************************************//**
83239 + @Description Structure for retrieving CAPWAP reassembly statistics
83240 +*//***************************************************************************/
83241 +typedef struct t_FmPcdManipReassemCapwapStats {
83242 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83243 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83244 + a Reassembly Frame Descriptor */
83245 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83246 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83247 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83248 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83249 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83250 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83251 + have been processed for all frames */
83252 + uint32_t processedFragments; /**< Counts the number of processed fragments
83253 + (valid and error fragments) for all frames */
83254 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83255 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83256 + to access an Reassembly Automatic Learning Hash set */
83257 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83258 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83259 + exceeds 16 */
83260 + uint32_t exceedMaxReassemblyFrameLen;/**< ounts the number of times that a successful reassembled frame
83261 + length exceeds MaxReassembledFrameLength value */
83262 +} t_FmPcdManipReassemCapwapStats;
83263 +
83264 +/**************************************************************************//**
83265 + @Description Structure for retrieving CAPWAP fragmentation statistics
83266 +*//***************************************************************************/
83267 +typedef struct t_FmPcdManipFragCapwapStats {
83268 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83269 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83270 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83271 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
83272 + uint8_t sgAllocationFailure; /**< Number of allocation failure of s/g buffers */
83273 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
83274 +} t_FmPcdManipFragCapwapStats;
83275 +#endif /* (DPAA_VERSION >= 11) */
83276 +
83277 +/**************************************************************************//**
83278 + @Description Structure for retrieving reassembly statistics
83279 +*//***************************************************************************/
83280 +typedef struct t_FmPcdManipReassemStats {
83281 + union {
83282 + t_FmPcdManipReassemIpStats ipReassem; /**< Structure for IP reassembly statistics */
83283 +#if (DPAA_VERSION >= 11)
83284 + t_FmPcdManipReassemCapwapStats capwapReassem; /**< Structure for CAPWAP reassembly statistics */
83285 +#endif /* (DPAA_VERSION >= 11) */
83286 + } u;
83287 +} t_FmPcdManipReassemStats;
83288 +
83289 +/**************************************************************************//**
83290 + @Description Structure for retrieving fragmentation statistics
83291 +*//***************************************************************************/
83292 +typedef struct t_FmPcdManipFragStats {
83293 + union {
83294 + t_FmPcdManipFragIpStats ipFrag; /**< Structure for IP fragmentation statistics */
83295 +#if (DPAA_VERSION >= 11)
83296 + t_FmPcdManipFragCapwapStats capwapFrag; /**< Structure for CAPWAP fragmentation statistics */
83297 +#endif /* (DPAA_VERSION >= 11) */
83298 + } u;
83299 +} t_FmPcdManipFragStats;
83300 +
83301 +/**************************************************************************//**
83302 + @Description Structure for selecting manipulation statistics
83303 +*//***************************************************************************/
83304 +typedef struct t_FmPcdManipStats {
83305 + union {
83306 + t_FmPcdManipReassemStats reassem; /**< Structure for reassembly statistics */
83307 + t_FmPcdManipFragStats frag; /**< Structure for fragmentation statistics */
83308 + } u;
83309 +} t_FmPcdManipStats;
83310 +
83311 +#if (DPAA_VERSION >= 11)
83312 +/**************************************************************************//**
83313 + @Description Parameters for defining frame replicator group and its members
83314 +*//***************************************************************************/
83315 +typedef struct t_FmPcdFrmReplicGroupParams {
83316 + uint8_t maxNumOfEntries; /**< Maximal number of members in the group;
83317 + Must be at least 2. */
83318 + uint8_t numOfEntries; /**< Number of members in the group;
83319 + Must be at least 1. */
83320 + t_FmPcdCcNextEngineParams nextEngineParams[FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
83321 + /**< Array of members' parameters */
83322 +} t_FmPcdFrmReplicGroupParams;
83323 +#endif /* (DPAA_VERSION >= 11) */
83324 +
83325 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83326 +/**************************************************************************//**
83327 + @Description structure for defining statistics node
83328 +*//***************************************************************************/
83329 +typedef struct t_FmPcdStatsParams {
83330 + e_FmPcdStatsType type; /**< type of statistics node */
83331 +} t_FmPcdStatsParams;
83332 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83333 +
83334 +/**************************************************************************//**
83335 + @Function FM_PCD_NetEnvCharacteristicsSet
83336 +
83337 + @Description Define a set of Network Environment Characteristics.
83338 +
83339 + When setting an environment it is important to understand its
83340 + application. It is not meant to describe the flows that will run
83341 + on the ports using this environment, but what the user means TO DO
83342 + with the PCD mechanisms in order to parse-classify-distribute those
83343 + frames.
83344 + By specifying a distinction unit, the user means it would use that option
83345 + for distinction between frames at either a KeyGen scheme or a coarse
83346 + classification action descriptor. Using interchangeable headers to define a
83347 + unit means that the user is indifferent to which of the interchangeable
83348 + headers is present in the frame, and wants the distinction to be based
83349 + on the presence of either one of them.
83350 +
83351 + Depending on context, there are limitations to the use of environments. A
83352 + port using the PCD functionality is bound to an environment. Some or even
83353 + all ports may share an environment but also an environment per port is
83354 + possible. When initializing a scheme, a classification plan group (see below),
83355 + or a coarse classification tree, one of the initialized environments must be
83356 + stated and related to. When a port is bound to a scheme, a classification
83357 + plan group, or a coarse classification tree, it MUST be bound to the same
83358 + environment.
83359 +
83360 + The different PCD modules, may relate (for flows definition) ONLY on
83361 + distinction units as defined by their environment. When initializing a
83362 + scheme for example, it may not choose to select IPV4 as a match for
83363 + recognizing flows unless it was defined in the relating environment. In
83364 + fact, to guide the user through the configuration of the PCD, each module's
83365 + characterization in terms of flows is not done using protocol names, but using
83366 + environment indexes.
83367 +
83368 + In terms of HW implementation, the list of distinction units sets the LCV vectors
83369 + and later used for match vector, classification plan vectors and coarse classification
83370 + indexing.
83371 +
83372 + @Param[in] h_FmPcd FM PCD module descriptor.
83373 + @Param[in] p_NetEnvParams A structure of parameters for the initialization of
83374 + the network environment.
83375 +
83376 + @Return A handle to the initialized object on success; NULL code otherwise.
83377 +
83378 + @Cautions Allowed only following FM_PCD_Init().
83379 +*//***************************************************************************/
83380 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams);
83381 +
83382 +/**************************************************************************//**
83383 + @Function FM_PCD_NetEnvCharacteristicsDelete
83384 +
83385 + @Description Deletes a set of Network Environment Characteristics.
83386 +
83387 + @Param[in] h_NetEnv A handle to the Network environment.
83388 +
83389 + @Return E_OK on success; Error code otherwise.
83390 +*//***************************************************************************/
83391 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv);
83392 +
83393 +/**************************************************************************//**
83394 + @Function FM_PCD_KgSchemeSet
83395 +
83396 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
83397 + This routine should be called for adding or modifying a scheme.
83398 + When a scheme needs modifying, the API requires that it will be
83399 + rewritten. In such a case 'modify' should be TRUE. If the
83400 + routine is called for a valid scheme and 'modify' is FALSE,
83401 + it will return error.
83402 +
83403 + @Param[in] h_FmPcd If this is a new scheme - A handle to an FM PCD Module.
83404 + Otherwise NULL (ignored by driver).
83405 + @Param[in,out] p_SchemeParams A structure of parameters for defining the scheme
83406 +
83407 + @Return A handle to the initialized scheme on success; NULL code otherwise.
83408 + When used as "modify" (rather than for setting a new scheme),
83409 + p_SchemeParams->id.h_Scheme will return NULL if action fails due to scheme
83410 + BUSY state.
83411 +
83412 + @Cautions Allowed only following FM_PCD_Init().
83413 +*//***************************************************************************/
83414 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd,
83415 + t_FmPcdKgSchemeParams *p_SchemeParams);
83416 +
83417 +/**************************************************************************//**
83418 + @Function FM_PCD_KgSchemeDelete
83419 +
83420 + @Description Deleting an initialized scheme.
83421 +
83422 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet()
83423 +
83424 + @Return E_OK on success; Error code otherwise.
83425 +
83426 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83427 +*//***************************************************************************/
83428 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme);
83429 +
83430 +/**************************************************************************//**
83431 + @Function FM_PCD_KgSchemeGetCounter
83432 +
83433 + @Description Reads scheme packet counter.
83434 +
83435 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83436 +
83437 + @Return Counter's current value.
83438 +
83439 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83440 +*//***************************************************************************/
83441 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme);
83442 +
83443 +/**************************************************************************//**
83444 + @Function FM_PCD_KgSchemeSetCounter
83445 +
83446 + @Description Writes scheme packet counter.
83447 +
83448 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83449 + @Param[in] value New scheme counter value - typically '0' for
83450 + resetting the counter.
83451 +
83452 + @Return E_OK on success; Error code otherwise.
83453 +
83454 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83455 +*//***************************************************************************/
83456 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value);
83457 +
83458 +/**************************************************************************//**
83459 + @Function FM_PCD_PlcrProfileSet
83460 +
83461 + @Description Sets a profile entry in the policer profile table.
83462 + The routine overrides any existing value.
83463 +
83464 + @Param[in] h_FmPcd A handle to an FM PCD Module.
83465 + @Param[in] p_Profile A structure of parameters for defining a
83466 + policer profile entry.
83467 +
83468 + @Return A handle to the initialized object on success; NULL code otherwise.
83469 + When used as "modify" (rather than for setting a new profile),
83470 + p_Profile->id.h_Profile will return NULL if action fails due to profile
83471 + BUSY state.
83472 + @Cautions Allowed only following FM_PCD_Init().
83473 +*//***************************************************************************/
83474 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
83475 + t_FmPcdPlcrProfileParams *p_Profile);
83476 +
83477 +/**************************************************************************//**
83478 + @Function FM_PCD_PlcrProfileDelete
83479 +
83480 + @Description Delete a profile entry in the policer profile table.
83481 + The routine set entry to invalid.
83482 +
83483 + @Param[in] h_Profile A handle to the profile.
83484 +
83485 + @Return E_OK on success; Error code otherwise.
83486 +
83487 + @Cautions Allowed only following FM_PCD_Init().
83488 +*//***************************************************************************/
83489 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile);
83490 +
83491 +/**************************************************************************//**
83492 + @Function FM_PCD_PlcrProfileGetCounter
83493 +
83494 + @Description Sets an entry in the classification plan.
83495 + The routine overrides any existing value.
83496 +
83497 + @Param[in] h_Profile A handle to the profile.
83498 + @Param[in] counter Counter selector.
83499 +
83500 + @Return specific counter value.
83501 +
83502 + @Cautions Allowed only following FM_PCD_Init().
83503 +*//***************************************************************************/
83504 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile,
83505 + e_FmPcdPlcrProfileCounters counter);
83506 +
83507 +/**************************************************************************//**
83508 + @Function FM_PCD_PlcrProfileSetCounter
83509 +
83510 + @Description Sets an entry in the classification plan.
83511 + The routine overrides any existing value.
83512 +
83513 + @Param[in] h_Profile A handle to the profile.
83514 + @Param[in] counter Counter selector.
83515 + @Param[in] value value to set counter with.
83516 +
83517 + @Return E_OK on success; Error code otherwise.
83518 +
83519 + @Cautions Allowed only following FM_PCD_Init().
83520 +*//***************************************************************************/
83521 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile,
83522 + e_FmPcdPlcrProfileCounters counter,
83523 + uint32_t value);
83524 +
83525 +/**************************************************************************//**
83526 + @Function FM_PCD_CcRootBuild
83527 +
83528 + @Description This routine must be called to define a complete coarse
83529 + classification tree. This is the way to define coarse
83530 + classification to a certain flow - the KeyGen schemes
83531 + may point only to trees defined in this way.
83532 +
83533 + @Param[in] h_FmPcd FM PCD module descriptor.
83534 + @Param[in] p_Params A structure of parameters to define the tree.
83535 +
83536 + @Return A handle to the initialized object on success; NULL code otherwise.
83537 +
83538 + @Cautions Allowed only following FM_PCD_Init().
83539 +*//***************************************************************************/
83540 +t_Handle FM_PCD_CcRootBuild (t_Handle h_FmPcd,
83541 + t_FmPcdCcTreeParams *p_Params);
83542 +
83543 +/**************************************************************************//**
83544 + @Function FM_PCD_CcRootDelete
83545 +
83546 + @Description Deleting an built tree.
83547 +
83548 + @Param[in] h_CcTree A handle to a CC tree.
83549 +
83550 + @Return E_OK on success; Error code otherwise.
83551 +
83552 + @Cautions Allowed only following FM_PCD_Init().
83553 +*//***************************************************************************/
83554 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree);
83555 +
83556 +/**************************************************************************//**
83557 + @Function FM_PCD_CcRootModifyNextEngine
83558 +
83559 + @Description Modify the Next Engine Parameters in the entry of the tree.
83560 +
83561 + @Param[in] h_CcTree A handle to the tree
83562 + @Param[in] grpId A Group index in the tree
83563 + @Param[in] index Entry index in the group defined by grpId
83564 + @Param[in] p_FmPcdCcNextEngineParams Pointer to new next engine parameters
83565 +
83566 + @Return E_OK on success; Error code otherwise.
83567 +
83568 + @Cautions Allowed only following FM_PCD_CcBuildTree().
83569 +*//***************************************************************************/
83570 +t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree,
83571 + uint8_t grpId,
83572 + uint8_t index,
83573 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83574 +
83575 +/**************************************************************************//**
83576 + @Function FM_PCD_MatchTableSet
83577 +
83578 + @Description This routine should be called for each CC (coarse classification)
83579 + node. The whole CC tree should be built bottom up so that each
83580 + node points to already defined nodes.
83581 +
83582 + @Param[in] h_FmPcd FM PCD module descriptor.
83583 + @Param[in] p_Param A structure of parameters defining the CC node
83584 +
83585 + @Return A handle to the initialized object on success; NULL code otherwise.
83586 +
83587 + @Cautions Allowed only following FM_PCD_Init().
83588 +*//***************************************************************************/
83589 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_Param);
83590 +
83591 +/**************************************************************************//**
83592 + @Function FM_PCD_MatchTableDelete
83593 +
83594 + @Description Deleting an built node.
83595 +
83596 + @Param[in] h_CcNode A handle to a CC node.
83597 +
83598 + @Return E_OK on success; Error code otherwise.
83599 +
83600 + @Cautions Allowed only following FM_PCD_Init().
83601 +*//***************************************************************************/
83602 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode);
83603 +
83604 +/**************************************************************************//**
83605 + @Function FM_PCD_MatchTableModifyMissNextEngine
83606 +
83607 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
83608 +
83609 + @Param[in] h_CcNode A handle to the node
83610 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83611 +
83612 + @Return E_OK on success; Error code otherwise.
83613 +
83614 + @Cautions Allowed only following FM_PCD_MatchTableSet();
83615 + Not relevant in the case the node is of type 'INDEXED_LOOKUP'.
83616 + When configuring nextEngine = e_FM_PCD_CC, note that
83617 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83618 + from the currently changed table.
83619 +
83620 +*//***************************************************************************/
83621 +t_Error FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode,
83622 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83623 +
83624 +/**************************************************************************//**
83625 + @Function FM_PCD_MatchTableRemoveKey
83626 +
83627 + @Description Remove the key (including next engine parameters of this key)
83628 + defined by the index of the relevant node.
83629 +
83630 + @Param[in] h_CcNode A handle to the node
83631 + @Param[in] keyIndex Key index for removing
83632 +
83633 + @Return E_OK on success; Error code otherwise.
83634 +
83635 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83636 + node and the nodes that lead to it.
83637 +*//***************************************************************************/
83638 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex);
83639 +
83640 +/**************************************************************************//**
83641 + @Function FM_PCD_MatchTableAddKey
83642 +
83643 + @Description Add the key (including next engine parameters of this key in the
83644 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
83645 + may be used by user that don't care about the position of the
83646 + key in the table - in that case, the key will be automatically
83647 + added by the driver in the last available entry.
83648 +
83649 + @Param[in] h_CcNode A handle to the node
83650 + @Param[in] keyIndex Key index for adding.
83651 + @Param[in] keySize Key size of added key
83652 + @Param[in] p_KeyParams A pointer to the parameters includes
83653 + new key with Next Engine Parameters
83654 +
83655 + @Return E_OK on success; Error code otherwise.
83656 +
83657 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83658 + node and the nodes that lead to it.
83659 +*//***************************************************************************/
83660 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode,
83661 + uint16_t keyIndex,
83662 + uint8_t keySize,
83663 + t_FmPcdCcKeyParams *p_KeyParams);
83664 +
83665 +/**************************************************************************//**
83666 + @Function FM_PCD_MatchTableModifyNextEngine
83667 +
83668 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
83669 +
83670 + @Param[in] h_CcNode A handle to the node
83671 + @Param[in] keyIndex Key index for Next Engine modifications
83672 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83673 +
83674 + @Return E_OK on success; Error code otherwise.
83675 +
83676 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83677 + When configuring nextEngine = e_FM_PCD_CC, note that
83678 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83679 + from the currently changed table.
83680 +
83681 +*//***************************************************************************/
83682 +t_Error FM_PCD_MatchTableModifyNextEngine(t_Handle h_CcNode,
83683 + uint16_t keyIndex,
83684 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83685 +
83686 +/**************************************************************************//**
83687 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
83688 +
83689 + @Description Modify the key and Next Engine Parameters of this key in the
83690 + index defined by the keyIndex.
83691 +
83692 + @Param[in] h_CcNode A handle to the node
83693 + @Param[in] keyIndex Key index for adding
83694 + @Param[in] keySize Key size of added key
83695 + @Param[in] p_KeyParams A pointer to the parameters includes
83696 + modified key and modified Next Engine Parameters
83697 +
83698 + @Return E_OK on success; Error code otherwise.
83699 +
83700 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83701 + node and the nodes that lead to it.
83702 + When configuring nextEngine = e_FM_PCD_CC, note that
83703 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83704 + from the currently changed table.
83705 +*//***************************************************************************/
83706 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
83707 + uint16_t keyIndex,
83708 + uint8_t keySize,
83709 + t_FmPcdCcKeyParams *p_KeyParams);
83710 +
83711 +/**************************************************************************//**
83712 + @Function FM_PCD_MatchTableModifyKey
83713 +
83714 + @Description Modify the key in the index defined by the keyIndex.
83715 +
83716 + @Param[in] h_CcNode A handle to the node
83717 + @Param[in] keyIndex Key index for adding
83718 + @Param[in] keySize Key size of added key
83719 + @Param[in] p_Key A pointer to the new key
83720 + @Param[in] p_Mask A pointer to the new mask if relevant,
83721 + otherwise pointer to NULL
83722 +
83723 + @Return E_OK on success; Error code otherwise.
83724 +
83725 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83726 + node and the nodes that lead to it.
83727 +*//***************************************************************************/
83728 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode,
83729 + uint16_t keyIndex,
83730 + uint8_t keySize,
83731 + uint8_t *p_Key,
83732 + uint8_t *p_Mask);
83733 +
83734 +/**************************************************************************//**
83735 + @Function FM_PCD_MatchTableFindNRemoveKey
83736 +
83737 + @Description Remove the key (including next engine parameters of this key)
83738 + defined by the key and mask. Note that this routine will search
83739 + the node to locate the index of the required key (& mask) to remove.
83740 +
83741 + @Param[in] h_CcNode A handle to the node
83742 + @Param[in] keySize Key size of the one to remove.
83743 + @Param[in] p_Key A pointer to the requested key to remove.
83744 + @Param[in] p_Mask A pointer to the mask if relevant,
83745 + otherwise pointer to NULL
83746 +
83747 + @Return E_OK on success; Error code otherwise.
83748 +
83749 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83750 + node and the nodes that lead to it.
83751 +*//***************************************************************************/
83752 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode,
83753 + uint8_t keySize,
83754 + uint8_t *p_Key,
83755 + uint8_t *p_Mask);
83756 +
83757 +/**************************************************************************//**
83758 + @Function FM_PCD_MatchTableFindNModifyNextEngine
83759 +
83760 + @Description Modify the Next Engine Parameters in the relevant key entry of
83761 + the node. Note that this routine will search the node to locate
83762 + the index of the required key (& mask) to modify.
83763 +
83764 + @Param[in] h_CcNode A handle to the node
83765 + @Param[in] keySize Key size of the one to modify.
83766 + @Param[in] p_Key A pointer to the requested key to modify.
83767 + @Param[in] p_Mask A pointer to the mask if relevant,
83768 + otherwise pointer to NULL
83769 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83770 +
83771 + @Return E_OK on success; Error code otherwise.
83772 +
83773 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83774 + When configuring nextEngine = e_FM_PCD_CC, note that
83775 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83776 + from the currently changed table.
83777 +*//***************************************************************************/
83778 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(t_Handle h_CcNode,
83779 + uint8_t keySize,
83780 + uint8_t *p_Key,
83781 + uint8_t *p_Mask,
83782 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83783 +
83784 +/**************************************************************************//**
83785 + @Function FM_PCD_MatchTableFindNModifyKeyAndNextEngine
83786 +
83787 + @Description Modify the key and Next Engine Parameters of this key in the
83788 + index defined by the keyIndex. Note that this routine will search
83789 + the node to locate the index of the required key (& mask) to modify.
83790 +
83791 + @Param[in] h_CcNode A handle to the node
83792 + @Param[in] keySize Key size of the one to modify.
83793 + @Param[in] p_Key A pointer to the requested key to modify.
83794 + @Param[in] p_Mask A pointer to the mask if relevant,
83795 + otherwise pointer to NULL
83796 + @Param[in] p_KeyParams A pointer to the parameters includes
83797 + modified key and modified Next Engine Parameters
83798 +
83799 + @Return E_OK on success; Error code otherwise.
83800 +
83801 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83802 + node and the nodes that lead to it.
83803 + When configuring nextEngine = e_FM_PCD_CC, note that
83804 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83805 + from the currently changed table.
83806 +*//***************************************************************************/
83807 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(t_Handle h_CcNode,
83808 + uint8_t keySize,
83809 + uint8_t *p_Key,
83810 + uint8_t *p_Mask,
83811 + t_FmPcdCcKeyParams *p_KeyParams);
83812 +
83813 +/**************************************************************************//**
83814 + @Function FM_PCD_MatchTableFindNModifyKey
83815 +
83816 + @Description Modify the key in the index defined by the keyIndex. Note that
83817 + this routine will search the node to locate the index of the
83818 + required key (& mask) to modify.
83819 +
83820 + @Param[in] h_CcNode A handle to the node
83821 + @Param[in] keySize Key size of the one to modify.
83822 + @Param[in] p_Key A pointer to the requested key to modify.
83823 + @Param[in] p_Mask A pointer to the mask if relevant,
83824 + otherwise pointer to NULL
83825 + @Param[in] p_NewKey A pointer to the new key
83826 + @Param[in] p_NewMask A pointer to the new mask if relevant,
83827 + otherwise pointer to NULL
83828 +
83829 + @Return E_OK on success; Error code otherwise.
83830 +
83831 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83832 + node and the nodes that lead to it.
83833 +*//***************************************************************************/
83834 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode,
83835 + uint8_t keySize,
83836 + uint8_t *p_Key,
83837 + uint8_t *p_Mask,
83838 + uint8_t *p_NewKey,
83839 + uint8_t *p_NewMask);
83840 +
83841 +/**************************************************************************//**
83842 + @Function FM_PCD_MatchTableGetKeyCounter
83843 +
83844 + @Description This routine may be used to get a counter of specific key in a CC
83845 + Node; This counter reflects how many frames passed that were matched
83846 + this key.
83847 +
83848 + @Param[in] h_CcNode A handle to the node
83849 + @Param[in] keyIndex Key index for adding
83850 +
83851 + @Return The specific key counter.
83852 +
83853 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83854 +*//***************************************************************************/
83855 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex);
83856 +
83857 +/**************************************************************************//**
83858 + @Function FM_PCD_MatchTableGetKeyStatistics
83859 +
83860 + @Description This routine may be used to get statistics counters of specific key
83861 + in a CC Node.
83862 +
83863 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
83864 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
83865 + these counters reflect how many frames passed that were matched
83866 + this key; The total frames count will be returned in the counter
83867 + of the first range (as only one frame length range was defined).
83868 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
83869 + frame count will be separated to frame length counters, based on
83870 + provided frame length ranges.
83871 +
83872 + @Param[in] h_CcNode A handle to the node
83873 + @Param[in] keyIndex Key index for adding
83874 + @Param[out] p_KeyStatistics Key statistics counters
83875 +
83876 + @Return The specific key statistics.
83877 +
83878 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83879 +*//***************************************************************************/
83880 +t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode,
83881 + uint16_t keyIndex,
83882 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
83883 +
83884 +/**************************************************************************//**
83885 + @Function FM_PCD_MatchTableGetMissStatistics
83886 +
83887 + @Description This routine may be used to get statistics counters of miss entry
83888 + in a CC Node.
83889 +
83890 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
83891 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
83892 + these counters reflect how many frames were not matched to any
83893 + existing key and therefore passed through the miss entry; The
83894 + total frames count will be returned in the counter of the
83895 + first range (as only one frame length range was defined).
83896 +
83897 + @Param[in] h_CcNode A handle to the node
83898 + @Param[out] p_MissStatistics Statistics counters for 'miss'
83899 +
83900 + @Return The statistics for 'miss'.
83901 +
83902 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83903 +*//***************************************************************************/
83904 +t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode,
83905 + t_FmPcdCcKeyStatistics *p_MissStatistics);
83906 +
83907 +/**************************************************************************//**
83908 + @Function FM_PCD_MatchTableFindNGetKeyStatistics
83909 +
83910 + @Description This routine may be used to get statistics counters of specific key
83911 + in a CC Node.
83912 +
83913 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
83914 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
83915 + these counters reflect how many frames passed that were matched
83916 + this key; The total frames count will be returned in the counter
83917 + of the first range (as only one frame length range was defined).
83918 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
83919 + frame count will be separated to frame length counters, based on
83920 + provided frame length ranges.
83921 + Note that this routine will search the node to locate the index
83922 + of the required key based on received key parameters.
83923 +
83924 + @Param[in] h_CcNode A handle to the node
83925 + @Param[in] keySize Size of the requested key
83926 + @Param[in] p_Key A pointer to the requested key
83927 + @Param[in] p_Mask A pointer to the mask if relevant,
83928 + otherwise pointer to NULL
83929 + @Param[out] p_KeyStatistics Key statistics counters
83930 +
83931 + @Return The specific key statistics.
83932 +
83933 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83934 +*//***************************************************************************/
83935 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode,
83936 + uint8_t keySize,
83937 + uint8_t *p_Key,
83938 + uint8_t *p_Mask,
83939 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
83940 +
83941 +/**************************************************************************//*
83942 + @Function FM_PCD_MatchTableGetNextEngine
83943 +
83944 + @Description Gets NextEngine of the relevant keyIndex.
83945 +
83946 + @Param[in] h_CcNode A handle to the node.
83947 + @Param[in] keyIndex keyIndex in the relevant node.
83948 + @Param[out] p_FmPcdCcNextEngineParams here updated nextEngine parameters for
83949 + the relevant keyIndex of the CC Node
83950 + received as parameter to this function
83951 +
83952 + @Return E_OK on success; Error code otherwise.
83953 +
83954 + @Cautions Allowed only following FM_PCD_Init().
83955 +*//***************************************************************************/
83956 +t_Error FM_PCD_MatchTableGetNextEngine(t_Handle h_CcNode,
83957 + uint16_t keyIndex,
83958 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83959 +
83960 +/**************************************************************************//*
83961 + @Function FM_PCD_MatchTableGetIndexedHashBucket
83962 +
83963 + @Description This routine simulates KeyGen operation on the provided key and
83964 + calculates to which hash bucket it will be mapped.
83965 +
83966 + @Param[in] h_CcNode A handle to the node.
83967 + @Param[in] kgKeySize Key size as it was configured in the KG
83968 + scheme that leads to this hash.
83969 + @Param[in] p_KgKey Pointer to the key; must be like the key
83970 + that the KG is generated, i.e. the same
83971 + extraction and with mask if exist.
83972 + @Param[in] kgHashShift Hash-shift as it was configured in the KG
83973 + scheme that leads to this hash.
83974 + @Param[out] p_CcNodeBucketHandle Pointer to the bucket of the provided key.
83975 + @Param[out] p_BucketIndex Index to the bucket of the provided key
83976 + @Param[out] p_LastIndex Pointer to last index in the bucket of the
83977 + provided key.
83978 +
83979 + @Return E_OK on success; Error code otherwise.
83980 +
83981 + @Cautions Allowed only following FM_PCD_HashTableSet()
83982 +*//***************************************************************************/
83983 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
83984 + uint8_t kgKeySize,
83985 + uint8_t *p_KgKey,
83986 + uint8_t kgHashShift,
83987 + t_Handle *p_CcNodeBucketHandle,
83988 + uint8_t *p_BucketIndex,
83989 + uint16_t *p_LastIndex);
83990 +
83991 +/**************************************************************************//**
83992 + @Function FM_PCD_HashTableSet
83993 +
83994 + @Description This routine initializes a hash table structure.
83995 + KeyGen hash result determines the hash bucket.
83996 + Next, KeyGen key is compared against all keys of this
83997 + bucket (exact match).
83998 + Number of sets (number of buckets) of the hash equals to the
83999 + number of 1-s in 'hashResMask' in the provided parameters.
84000 + Number of hash table ways is then calculated by dividing
84001 + 'maxNumOfKeys' equally between the hash sets. This is the maximal
84002 + number of keys that a hash bucket may hold.
84003 + The hash table is initialized empty and keys may be
84004 + added to it following the initialization. Keys masks are not
84005 + supported in current hash table implementation.
84006 + The initialized hash table can be integrated as a node in a
84007 + CC tree.
84008 +
84009 + @Param[in] h_FmPcd FM PCD module descriptor.
84010 + @Param[in] p_Param A structure of parameters defining the hash table
84011 +
84012 + @Return A handle to the initialized object on success; NULL code otherwise.
84013 +
84014 + @Cautions Allowed only following FM_PCD_Init().
84015 +*//***************************************************************************/
84016 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param);
84017 +
84018 +/**************************************************************************//**
84019 + @Function FM_PCD_HashTableDelete
84020 +
84021 + @Description This routine deletes the provided hash table and released all
84022 + its allocated resources.
84023 +
84024 + @Param[in] h_HashTbl A handle to a hash table
84025 +
84026 + @Return E_OK on success; Error code otherwise.
84027 +
84028 + @Cautions Allowed only following FM_PCD_HashTableSet().
84029 +*//***************************************************************************/
84030 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl);
84031 +
84032 +/**************************************************************************//**
84033 + @Function FM_PCD_HashTableAddKey
84034 +
84035 + @Description This routine adds the provided key (including next engine
84036 + parameters of this key) to the hash table.
84037 + The key is added as the last key of the bucket that it is
84038 + mapped to.
84039 +
84040 + @Param[in] h_HashTbl A handle to a hash table
84041 + @Param[in] keySize Key size of added key
84042 + @Param[in] p_KeyParams A pointer to the parameters includes
84043 + new key with next engine parameters; The pointer
84044 + to the key mask must be NULL, as masks are not
84045 + supported in hash table implementation.
84046 +
84047 + @Return E_OK on success; Error code otherwise.
84048 +
84049 + @Cautions Allowed only following FM_PCD_HashTableSet().
84050 +*//***************************************************************************/
84051 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl,
84052 + uint8_t keySize,
84053 + t_FmPcdCcKeyParams *p_KeyParams);
84054 +
84055 +/**************************************************************************//**
84056 + @Function FM_PCD_HashTableRemoveKey
84057 +
84058 + @Description This routine removes the requested key (including next engine
84059 + parameters of this key) from the hash table.
84060 +
84061 + @Param[in] h_HashTbl A handle to a hash table
84062 + @Param[in] keySize Key size of the one to remove.
84063 + @Param[in] p_Key A pointer to the requested key to remove.
84064 +
84065 + @Return E_OK on success; Error code otherwise.
84066 +
84067 + @Cautions Allowed only following FM_PCD_HashTableSet().
84068 +*//***************************************************************************/
84069 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl,
84070 + uint8_t keySize,
84071 + uint8_t *p_Key);
84072 +
84073 +/**************************************************************************//**
84074 + @Function FM_PCD_HashTableModifyNextEngine
84075 +
84076 + @Description This routine modifies the next engine for the provided key. The
84077 + key should be previously added to the hash table.
84078 +
84079 + @Param[in] h_HashTbl A handle to a hash table
84080 + @Param[in] keySize Key size of the key to modify.
84081 + @Param[in] p_Key A pointer to the requested key to modify.
84082 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
84083 + parameters.
84084 +
84085 + @Return E_OK on success; Error code otherwise.
84086 +
84087 + @Cautions Allowed only following FM_PCD_HashTableSet().
84088 + When configuring nextEngine = e_FM_PCD_CC, note that
84089 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84090 + from the currently changed table.
84091 +*//***************************************************************************/
84092 +t_Error FM_PCD_HashTableModifyNextEngine(t_Handle h_HashTbl,
84093 + uint8_t keySize,
84094 + uint8_t *p_Key,
84095 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84096 +
84097 +/**************************************************************************//**
84098 + @Function FM_PCD_HashTableModifyMissNextEngine
84099 +
84100 + @Description This routine modifies the next engine on key match miss.
84101 +
84102 + @Param[in] h_HashTbl A handle to a hash table
84103 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
84104 + parameters.
84105 +
84106 + @Return E_OK on success; Error code otherwise.
84107 +
84108 + @Cautions Allowed only following FM_PCD_HashTableSet().
84109 + When configuring nextEngine = e_FM_PCD_CC, note that
84110 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84111 + from the currently changed table.
84112 +*//***************************************************************************/
84113 +t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl,
84114 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84115 +
84116 +/**************************************************************************//*
84117 + @Function FM_PCD_HashTableGetMissNextEngine
84118 +
84119 + @Description Gets NextEngine in case of key match miss.
84120 +
84121 + @Param[in] h_HashTbl A handle to a hash table
84122 + @Param[out] p_FmPcdCcNextEngineParams Next engine parameters for the specified
84123 + hash table.
84124 +
84125 + @Return E_OK on success; Error code otherwise.
84126 +
84127 + @Cautions Allowed only following FM_PCD_HashTableSet().
84128 +*//***************************************************************************/
84129 +t_Error FM_PCD_HashTableGetMissNextEngine(t_Handle h_HashTbl,
84130 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84131 +
84132 +/**************************************************************************//**
84133 + @Function FM_PCD_HashTableFindNGetKeyStatistics
84134 +
84135 + @Description This routine may be used to get statistics counters of specific key
84136 + in a hash table.
84137 +
84138 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84139 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84140 + these counters reflect how many frames passed that were matched
84141 + this key; The total frames count will be returned in the counter
84142 + of the first range (as only one frame length range was defined).
84143 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
84144 + frame count will be separated to frame length counters, based on
84145 + provided frame length ranges.
84146 + Note that this routine will identify the bucket of this key in
84147 + the hash table and will search the bucket to locate the index
84148 + of the required key based on received key parameters.
84149 +
84150 + @Param[in] h_HashTbl A handle to a hash table
84151 + @Param[in] keySize Size of the requested key
84152 + @Param[in] p_Key A pointer to the requested key
84153 + @Param[out] p_KeyStatistics Key statistics counters
84154 +
84155 + @Return The specific key statistics.
84156 +
84157 + @Cautions Allowed only following FM_PCD_HashTableSet().
84158 +*//***************************************************************************/
84159 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl,
84160 + uint8_t keySize,
84161 + uint8_t *p_Key,
84162 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84163 +
84164 +/**************************************************************************//**
84165 + @Function FM_PCD_HashTableGetMissStatistics
84166 +
84167 + @Description This routine may be used to get statistics counters of 'miss'
84168 + entry of the a hash table.
84169 +
84170 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84171 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84172 + these counters reflect how many frames were not matched to any
84173 + existing key and therefore passed through the miss entry;
84174 +
84175 + @Param[in] h_HashTbl A handle to a hash table
84176 + @Param[out] p_MissStatistics Statistics counters for 'miss'
84177 +
84178 + @Return The statistics for 'miss'.
84179 +
84180 + @Cautions Allowed only following FM_PCD_HashTableSet().
84181 +*//***************************************************************************/
84182 +t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl,
84183 + t_FmPcdCcKeyStatistics *p_MissStatistics);
84184 +
84185 +/**************************************************************************//**
84186 + @Function FM_PCD_ManipNodeSet
84187 +
84188 + @Description This routine should be called for defining a manipulation
84189 + node. A manipulation node must be defined before the CC node
84190 + that precedes it.
84191 +
84192 + @Param[in] h_FmPcd FM PCD module descriptor.
84193 + @Param[in] p_FmPcdManipParams A structure of parameters defining the manipulation
84194 +
84195 + @Return A handle to the initialized object on success; NULL code otherwise.
84196 +
84197 + @Cautions Allowed only following FM_PCD_Init().
84198 +*//***************************************************************************/
84199 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams);
84200 +
84201 +/**************************************************************************//**
84202 + @Function FM_PCD_ManipNodeDelete
84203 +
84204 + @Description Delete an existing manipulation node.
84205 +
84206 + @Param[in] h_ManipNode A handle to a manipulation node.
84207 +
84208 + @Return E_OK on success; Error code otherwise.
84209 +
84210 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84211 +*//***************************************************************************/
84212 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode);
84213 +
84214 +/**************************************************************************//**
84215 + @Function FM_PCD_ManipGetStatistics
84216 +
84217 + @Description Retrieve the manipulation statistics.
84218 +
84219 + @Param[in] h_ManipNode A handle to a manipulation node.
84220 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
84221 +
84222 + @Return E_OK on success; Error code otherwise.
84223 +
84224 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84225 +*//***************************************************************************/
84226 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, t_FmPcdManipStats *p_FmPcdManipStats);
84227 +
84228 +/**************************************************************************//**
84229 + @Function FM_PCD_ManipNodeReplace
84230 +
84231 + @Description Change existing manipulation node to be according to new requirement.
84232 +
84233 + @Param[in] h_ManipNode A handle to a manipulation node.
84234 + @Param[out] p_ManipParams A structure of parameters defining the change requirement
84235 +
84236 + @Return E_OK on success; Error code otherwise.
84237 +
84238 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84239 +*//***************************************************************************/
84240 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_ManipNode, t_FmPcdManipParams *p_ManipParams);
84241 +
84242 +#if (DPAA_VERSION >= 11)
84243 +/**************************************************************************//**
84244 + @Function FM_PCD_FrmReplicSetGroup
84245 +
84246 + @Description Initialize a Frame Replicator group.
84247 +
84248 + @Param[in] h_FmPcd FM PCD module descriptor.
84249 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
84250 + the frame replicator group.
84251 +
84252 + @Return A handle to the initialized object on success; NULL code otherwise.
84253 +
84254 + @Cautions Allowed only following FM_PCD_Init().
84255 +*//***************************************************************************/
84256 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, t_FmPcdFrmReplicGroupParams *p_FrmReplicGroupParam);
84257 +
84258 +/**************************************************************************//**
84259 + @Function FM_PCD_FrmReplicDeleteGroup
84260 +
84261 + @Description Delete a Frame Replicator group.
84262 +
84263 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84264 +
84265 + @Return E_OK on success; Error code otherwise.
84266 +
84267 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
84268 +*//***************************************************************************/
84269 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_FrmReplicGroup);
84270 +
84271 +/**************************************************************************//**
84272 + @Function FM_PCD_FrmReplicAddMember
84273 +
84274 + @Description Add the member in the index defined by the memberIndex.
84275 +
84276 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84277 + @Param[in] memberIndex member index for adding.
84278 + @Param[in] p_MemberParams A pointer to the new member parameters.
84279 +
84280 + @Return E_OK on success; Error code otherwise.
84281 +
84282 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84283 +*//***************************************************************************/
84284 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_FrmReplicGroup,
84285 + uint16_t memberIndex,
84286 + t_FmPcdCcNextEngineParams *p_MemberParams);
84287 +
84288 +/**************************************************************************//**
84289 + @Function FM_PCD_FrmReplicRemoveMember
84290 +
84291 + @Description Remove the member defined by the index from the relevant group.
84292 +
84293 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84294 + @Param[in] memberIndex member index for removing.
84295 +
84296 + @Return E_OK on success; Error code otherwise.
84297 +
84298 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84299 +*//***************************************************************************/
84300 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_FrmReplicGroup,
84301 + uint16_t memberIndex);
84302 +#endif /* (DPAA_VERSION >= 11) */
84303 +
84304 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84305 +/**************************************************************************//**
84306 + @Function FM_PCD_StatisticsSetNode
84307 +
84308 + @Description This routine should be called for defining a statistics node.
84309 +
84310 + @Param[in] h_FmPcd FM PCD module descriptor.
84311 + @Param[in] p_FmPcdstatsParams A structure of parameters defining the statistics
84312 +
84313 + @Return A handle to the initialized object on success; NULL code otherwise.
84314 +
84315 + @Cautions Allowed only following FM_PCD_Init().
84316 +*//***************************************************************************/
84317 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_FmPcdstatsParams);
84318 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
84319 +
84320 +/** @} */ /* end of FM_PCD_Runtime_build_grp group */
84321 +/** @} */ /* end of FM_PCD_Runtime_grp group */
84322 +/** @} */ /* end of FM_PCD_grp group */
84323 +/** @} */ /* end of FM_grp group */
84324 +
84325 +
84326 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
84327 +#define FM_PCD_MAX_NUM_OF_INTERCHANGABLE_HDRS FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS
84328 +#define e_FM_PCD_MANIP_ONE_WAYS_HASH e_FM_PCD_MANIP_ONE_WAY_HASH
84329 +#define e_FM_PCD_MANIP_TOW_WAYS_HASH e_FM_PCD_MANIP_TWO_WAYS_HASH
84330 +
84331 +#define e_FM_PCD_MANIP_FRAGMENT_PACKECT e_FM_PCD_MANIP_FRAGMENT_PACKET /* Feb13 */
84332 +
84333 +#define FM_PCD_SetNetEnvCharacteristics(_pcd, _params) \
84334 + FM_PCD_NetEnvCharacteristicsSet(_pcd, _params)
84335 +#define FM_PCD_KgSetScheme(_pcd, _params) FM_PCD_KgSchemeSet(_pcd, _params)
84336 +#define FM_PCD_CcBuildTree(_pcd, _params) FM_PCD_CcRootBuild(_pcd, _params)
84337 +#define FM_PCD_CcSetNode(_pcd, _params) FM_PCD_MatchTableSet(_pcd, _params)
84338 +#define FM_PCD_PlcrSetProfile(_pcd, _params) FM_PCD_PlcrProfileSet(_pcd, _params)
84339 +#define FM_PCD_ManipSetNode(_pcd, _params) FM_PCD_ManipNodeSet(_pcd, _params)
84340 +
84341 +#define FM_PCD_DeleteNetEnvCharacteristics(_pcd, ...) \
84342 + FM_PCD_NetEnvCharacteristicsDelete(__VA_ARGS__)
84343 +#define FM_PCD_KgDeleteScheme(_pcd, ...) \
84344 + FM_PCD_KgSchemeDelete(__VA_ARGS__)
84345 +#define FM_PCD_KgGetSchemeCounter(_pcd, ...) \
84346 + FM_PCD_KgSchemeGetCounter(__VA_ARGS__)
84347 +#define FM_PCD_KgSetSchemeCounter(_pcd, ...) \
84348 + FM_PCD_KgSchemeSetCounter(__VA_ARGS__)
84349 +#define FM_PCD_PlcrDeleteProfile(_pcd, ...) \
84350 + FM_PCD_PlcrProfileDelete(__VA_ARGS__)
84351 +#define FM_PCD_PlcrGetProfileCounter(_pcd, ...) \
84352 + FM_PCD_PlcrProfileGetCounter(__VA_ARGS__)
84353 +#define FM_PCD_PlcrSetProfileCounter(_pcd, ...) \
84354 + FM_PCD_PlcrProfileSetCounter(__VA_ARGS__)
84355 +#define FM_PCD_CcDeleteTree(_pcd, ...) \
84356 + FM_PCD_CcRootDelete(__VA_ARGS__)
84357 +#define FM_PCD_CcTreeModifyNextEngine(_pcd, ...) \
84358 + FM_PCD_CcRootModifyNextEngine(__VA_ARGS__)
84359 +#define FM_PCD_CcDeleteNode(_pcd, ...) \
84360 + FM_PCD_MatchTableDelete(__VA_ARGS__)
84361 +#define FM_PCD_CcNodeModifyMissNextEngine(_pcd, ...) \
84362 + FM_PCD_MatchTableModifyMissNextEngine(__VA_ARGS__)
84363 +#define FM_PCD_CcNodeRemoveKey(_pcd, ...) \
84364 + FM_PCD_MatchTableRemoveKey(__VA_ARGS__)
84365 +#define FM_PCD_CcNodeAddKey(_pcd, ...) \
84366 + FM_PCD_MatchTableAddKey(__VA_ARGS__)
84367 +#define FM_PCD_CcNodeModifyNextEngine(_pcd, ...) \
84368 + FM_PCD_MatchTableModifyNextEngine(__VA_ARGS__)
84369 +#define FM_PCD_CcNodeModifyKeyAndNextEngine(_pcd, ...) \
84370 + FM_PCD_MatchTableModifyKeyAndNextEngine(__VA_ARGS__)
84371 +#define FM_PCD_CcNodeModifyKey(_pcd, ...) \
84372 + FM_PCD_MatchTableModifyKey(__VA_ARGS__)
84373 +#define FM_PCD_CcNodeFindNRemoveKey(_pcd, ...) \
84374 + FM_PCD_MatchTableFindNRemoveKey(__VA_ARGS__)
84375 +#define FM_PCD_CcNodeFindNModifyNextEngine(_pcd, ...) \
84376 + FM_PCD_MatchTableFindNModifyNextEngine(__VA_ARGS__)
84377 +#define FM_PCD_CcNodeFindNModifyKeyAndNextEngine(_pcd, ...) \
84378 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine(__VA_ARGS__)
84379 +#define FM_PCD_CcNodeFindNModifyKey(_pcd, ...) \
84380 + FM_PCD_MatchTableFindNModifyKey(__VA_ARGS__)
84381 +#define FM_PCD_CcIndexedHashNodeGetBucket(_pcd, ...) \
84382 + FM_PCD_MatchTableGetIndexedHashBucket(__VA_ARGS__)
84383 +#define FM_PCD_CcNodeGetNextEngine(_pcd, ...) \
84384 + FM_PCD_MatchTableGetNextEngine(__VA_ARGS__)
84385 +#define FM_PCD_CcNodeGetKeyCounter(_pcd, ...) \
84386 + FM_PCD_MatchTableGetKeyCounter(__VA_ARGS__)
84387 +#define FM_PCD_ManipDeleteNode(_pcd, ...) \
84388 + FM_PCD_ManipNodeDelete(__VA_ARGS__)
84389 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
84390 +
84391 +
84392 +#endif /* __FM_PCD_EXT */
84393 --- /dev/null
84394 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
84395 @@ -0,0 +1,2608 @@
84396 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
84397 + * All rights reserved.
84398 + *
84399 + * Redistribution and use in source and binary forms, with or without
84400 + * modification, are permitted provided that the following conditions are met:
84401 + * * Redistributions of source code must retain the above copyright
84402 + * notice, this list of conditions and the following disclaimer.
84403 + * * Redistributions in binary form must reproduce the above copyright
84404 + * notice, this list of conditions and the following disclaimer in the
84405 + * documentation and/or other materials provided with the distribution.
84406 + * * Neither the name of Freescale Semiconductor nor the
84407 + * names of its contributors may be used to endorse or promote products
84408 + * derived from this software without specific prior written permission.
84409 + *
84410 + *
84411 + * ALTERNATIVELY, this software may be distributed under the terms of the
84412 + * GNU General Public License ("GPL") as published by the Free Software
84413 + * Foundation, either version 2 of that License or (at your option) any
84414 + * later version.
84415 + *
84416 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
84417 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
84418 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
84419 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
84420 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
84421 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
84422 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
84423 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
84424 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
84425 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84426 + */
84427 +
84428 +
84429 +/**************************************************************************//**
84430 + @File fm_port_ext.h
84431 +
84432 + @Description FM-Port Application Programming Interface.
84433 +*//***************************************************************************/
84434 +#ifndef __FM_PORT_EXT
84435 +#define __FM_PORT_EXT
84436 +
84437 +#include "error_ext.h"
84438 +#include "std_ext.h"
84439 +#include "fm_pcd_ext.h"
84440 +#include "fm_ext.h"
84441 +#include "net_ext.h"
84442 +
84443 +
84444 +/**************************************************************************//**
84445 +
84446 + @Group FM_grp Frame Manager API
84447 +
84448 + @Description FM API functions, definitions and enums
84449 +
84450 + @{
84451 +*//***************************************************************************/
84452 +
84453 +/**************************************************************************//**
84454 + @Group FM_PORT_grp FM Port
84455 +
84456 + @Description FM Port API
84457 +
84458 + The FM uses a general module called "port" to represent a Tx port
84459 + (MAC), an Rx port (MAC) or Offline Parsing port.
84460 + The number of ports in an FM varies between SOCs.
84461 + The SW driver manages these ports as sub-modules of the FM, i.e.
84462 + after an FM is initialized, its ports may be initialized and
84463 + operated upon.
84464 +
84465 + The port is initialized aware of its type, but other functions on
84466 + a port may be indifferent to its type. When necessary, the driver
84467 + verifies coherence and returns error if applicable.
84468 +
84469 + On initialization, user specifies the port type and it's index
84470 + (relative to the port's type) - always starting at 0.
84471 +
84472 + @{
84473 +*//***************************************************************************/
84474 +
84475 +/**************************************************************************//**
84476 + @Description An enum for defining port PCD modes.
84477 + This enum defines the superset of PCD engines support - i.e. not
84478 + all engines have to be used, but all have to be enabled. The real
84479 + flow of a specific frame depends on the PCD configuration and the
84480 + frame headers and payload.
84481 + Note: the first engine and the first engine after the parser (if
84482 + exists) should be in order, the order is important as it will
84483 + define the flow of the port. However, as for the rest engines
84484 + (the ones that follows), the order is not important anymore as
84485 + it is defined by the PCD graph itself.
84486 +*//***************************************************************************/
84487 +typedef enum e_FmPortPcdSupport {
84488 + e_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
84489 + , e_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
84490 + , e_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
84491 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
84492 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
84493 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
84494 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
84495 + /**< Use all PCD engines */
84496 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
84497 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
84498 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
84499 + , e_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
84500 +#ifdef FM_CAPWAP_SUPPORT
84501 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
84502 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
84503 +#endif /* FM_CAPWAP_SUPPORT */
84504 +} e_FmPortPcdSupport;
84505 +
84506 +/**************************************************************************//**
84507 + @Description Port interrupts
84508 +*//***************************************************************************/
84509 +typedef enum e_FmPortExceptions {
84510 + e_FM_PORT_EXCEPTION_IM_BUSY /**< Independent-Mode Rx-BUSY */
84511 +} e_FmPortExceptions;
84512 +
84513 +
84514 +/**************************************************************************//**
84515 + @Collection General FM Port defines
84516 +*//***************************************************************************/
84517 +#define FM_PORT_PRS_RESULT_NUM_OF_WORDS 8 /**< Number of 4 bytes words in parser result */
84518 +/* @} */
84519 +
84520 +/**************************************************************************//**
84521 + @Collection FM Frame error
84522 +*//***************************************************************************/
84523 +typedef uint32_t fmPortFrameErrSelect_t; /**< typedef for defining Frame Descriptor errors */
84524 +
84525 +#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT FM_FD_ERR_UNSUPPORTED_FORMAT /**< Not for Rx-Port! Unsupported Format */
84526 +#define FM_PORT_FRM_ERR_LENGTH FM_FD_ERR_LENGTH /**< Not for Rx-Port! Length Error */
84527 +#define FM_PORT_FRM_ERR_DMA FM_FD_ERR_DMA /**< DMA Data error */
84528 +#define FM_PORT_FRM_ERR_NON_FM FM_FD_RX_STATUS_ERR_NON_FM /**< non Frame-Manager error; probably come from SEC that
84529 + was chained to FM */
84530 +
84531 +#define FM_PORT_FRM_ERR_IPRE (FM_FD_ERR_IPR & ~FM_FD_IPR) /**< IPR error */
84532 +#define FM_PORT_FRM_ERR_IPR_NCSP (FM_FD_ERR_IPR_NCSP & ~FM_FD_IPR) /**< IPR non-consistent-sp */
84533 +
84534 +#define FM_PORT_FRM_ERR_IPFE 0 /**< Obsolete; will be removed in the future */
84535 +
84536 +#ifdef FM_CAPWAP_SUPPORT
84537 +#define FM_PORT_FRM_ERR_CRE FM_FD_ERR_CRE
84538 +#define FM_PORT_FRM_ERR_CHE FM_FD_ERR_CHE
84539 +#endif /* FM_CAPWAP_SUPPORT */
84540 +
84541 +#define FM_PORT_FRM_ERR_PHYSICAL FM_FD_ERR_PHYSICAL /**< Rx FIFO overflow, FCS error, code error, running disparity
84542 + error (SGMII and TBI modes), FIFO parity error. PHY
84543 + Sequence error, PHY error control character detected. */
84544 +#define FM_PORT_FRM_ERR_SIZE FM_FD_ERR_SIZE /**< Frame too long OR Frame size exceeds max_length_frame */
84545 +#define FM_PORT_FRM_ERR_CLS_DISCARD FM_FD_ERR_CLS_DISCARD /**< indicates a classifier "drop" operation */
84546 +#define FM_PORT_FRM_ERR_EXTRACTION FM_FD_ERR_EXTRACTION /**< Extract Out of Frame */
84547 +#define FM_PORT_FRM_ERR_NO_SCHEME FM_FD_ERR_NO_SCHEME /**< No Scheme Selected */
84548 +#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW FM_FD_ERR_KEYSIZE_OVERFLOW /**< Keysize Overflow */
84549 +#define FM_PORT_FRM_ERR_COLOR_RED FM_FD_ERR_COLOR_RED /**< Frame color is red */
84550 +#define FM_PORT_FRM_ERR_COLOR_YELLOW FM_FD_ERR_COLOR_YELLOW /**< Frame color is yellow */
84551 +#define FM_PORT_FRM_ERR_ILL_PLCR FM_FD_ERR_ILL_PLCR /**< Illegal Policer Profile selected */
84552 +#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN FM_FD_ERR_PLCR_FRAME_LEN /**< Policer frame length error */
84553 +#define FM_PORT_FRM_ERR_PRS_TIMEOUT FM_FD_ERR_PRS_TIMEOUT /**< Parser Time out Exceed */
84554 +#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT FM_FD_ERR_PRS_ILL_INSTRUCT /**< Invalid Soft Parser instruction */
84555 +#define FM_PORT_FRM_ERR_PRS_HDR_ERR FM_FD_ERR_PRS_HDR_ERR /**< Header error was identified during parsing */
84556 +#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED FM_FD_ERR_BLOCK_LIMIT_EXCEEDED /**< Frame parsed beyind 256 first bytes */
84557 +#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */
84558 +/* @} */
84559 +
84560 +
84561 +
84562 +/**************************************************************************//**
84563 + @Group FM_PORT_init_grp FM Port Initialization Unit
84564 +
84565 + @Description FM Port Initialization Unit
84566 +
84567 + @{
84568 +*//***************************************************************************/
84569 +
84570 +/**************************************************************************//**
84571 + @Description Exceptions user callback routine, will be called upon an
84572 + exception passing the exception identification.
84573 +
84574 + @Param[in] h_App - User's application descriptor.
84575 + @Param[in] exception - The exception.
84576 + *//***************************************************************************/
84577 +typedef void (t_FmPortExceptionCallback) (t_Handle h_App, e_FmPortExceptions exception);
84578 +
84579 +/**************************************************************************//**
84580 + @Description User callback function called by driver with received data.
84581 +
84582 + User provides this function. Driver invokes it.
84583 +
84584 + @Param[in] h_App Application's handle originally specified to
84585 + the API Config function
84586 + @Param[in] p_Data A pointer to data received
84587 + @Param[in] length length of received data
84588 + @Param[in] status receive status and errors
84589 + @Param[in] position position of buffer in frame
84590 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84591 +
84592 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
84593 + operation for all ready data.
84594 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
84595 +*//***************************************************************************/
84596 +typedef e_RxStoreResponse (t_FmPortImRxStoreCallback) (t_Handle h_App,
84597 + uint8_t *p_Data,
84598 + uint16_t length,
84599 + uint16_t status,
84600 + uint8_t position,
84601 + t_Handle h_BufContext);
84602 +
84603 +/**************************************************************************//**
84604 + @Description User callback function called by driver when transmit completed.
84605 +
84606 + User provides this function. Driver invokes it.
84607 +
84608 + @Param[in] h_App Application's handle originally specified to
84609 + the API Config function
84610 + @Param[in] p_Data A pointer to data received
84611 + @Param[in] status transmit status and errors
84612 + @Param[in] lastBuffer is last buffer in frame
84613 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84614 + *//***************************************************************************/
84615 +typedef void (t_FmPortImTxConfCallback) (t_Handle h_App,
84616 + uint8_t *p_Data,
84617 + uint16_t status,
84618 + t_Handle h_BufContext);
84619 +
84620 +/**************************************************************************//**
84621 + @Description A structure for additional Rx port parameters
84622 +*//***************************************************************************/
84623 +typedef struct t_FmPortRxParams {
84624 + uint32_t errFqid; /**< Error Queue Id. */
84625 + uint32_t dfltFqid; /**< Default Queue Id. */
84626 + uint16_t liodnOffset; /**< Port's LIODN offset. */
84627 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
84628 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. */
84629 +} t_FmPortRxParams;
84630 +
84631 +/**************************************************************************//**
84632 + @Description A structure for additional non-Rx port parameters
84633 +*//***************************************************************************/
84634 +typedef struct t_FmPortNonRxParams {
84635 + uint32_t errFqid; /**< Error Queue Id. */
84636 + uint32_t dfltFqid; /**< For Tx - Default Confirmation queue,
84637 + 0 means no Tx confirmation for processed
84638 + frames. For OP port - default Rx queue. */
84639 + uint32_t qmChannel; /**< QM-channel dedicated to this port; will be used
84640 + by the FM for dequeue. */
84641 +} t_FmPortNonRxParams;
84642 +
84643 +/**************************************************************************//**
84644 + @Description A structure for additional Rx port parameters
84645 +*//***************************************************************************/
84646 +typedef struct t_FmPortImRxTxParams {
84647 + t_Handle h_FmMuram; /**< A handle of the FM-MURAM partition */
84648 + uint16_t liodnOffset; /**< For Rx ports only. Port's LIODN Offset. */
84649 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
84650 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
84651 + t_BufferPoolInfo rxPoolParams; /**< For Rx ports only. */
84652 + t_FmPortImRxStoreCallback *f_RxStore; /**< For Rx ports only. */
84653 + t_FmPortImTxConfCallback *f_TxConf; /**< For Tx ports only. */
84654 +} t_FmPortImRxTxParams;
84655 +
84656 +/**************************************************************************//**
84657 + @Description A union for additional parameters depending on port type
84658 +*//***************************************************************************/
84659 +typedef union u_FmPortSpecificParams {
84660 + t_FmPortImRxTxParams imRxTxParams; /**< Rx/Tx Independent-Mode port parameter structure */
84661 + t_FmPortRxParams rxParams; /**< Rx port parameters structure */
84662 + t_FmPortNonRxParams nonRxParams; /**< Non-Rx port parameters structure */
84663 +} u_FmPortSpecificParams;
84664 +
84665 +/**************************************************************************//**
84666 + @Description A structure representing FM initialization parameters
84667 +*//***************************************************************************/
84668 +typedef struct t_FmPortParams {
84669 + uintptr_t baseAddr; /**< Virtual Address of memory mapped FM Port registers.*/
84670 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
84671 + e_FmPortType portType; /**< Port type */
84672 + uint8_t portId; /**< Port Id - relative to type;
84673 + NOTE: When configuring Offline Parsing port for
84674 + FMANv3 devices (DPAA_VERSION 11 and higher),
84675 + it is highly recommended NOT to use portId=0 due to lack
84676 + of HW resources on portId=0. */
84677 + bool independentModeEnable;
84678 + /**< This port is Independent-Mode - Used for Rx/Tx ports only! */
84679 + uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be
84680 + used together with LIODN offset. */
84681 + u_FmPortSpecificParams specificParams; /**< Additional parameters depending on port
84682 + type. */
84683 +
84684 + t_FmPortExceptionCallback *f_Exception; /**< Relevant for IM only Callback routine to be called on BUSY exception */
84685 + t_Handle h_App; /**< A handle to an application layer object; This handle will
84686 + be passed by the driver upon calling the above callbacks */
84687 +} t_FmPortParams;
84688 +
84689 +
84690 +/**************************************************************************//**
84691 + @Function FM_PORT_Config
84692 +
84693 + @Description Creates a descriptor for the FM PORT module.
84694 +
84695 + The routine returns a handle (descriptor) to the FM PORT object.
84696 + This descriptor must be passed as first parameter to all other
84697 + FM PORT function calls.
84698 +
84699 + No actual initialization or configuration of FM hardware is
84700 + done by this routine.
84701 +
84702 + @Param[in] p_FmPortParams - Pointer to data structure of parameters
84703 +
84704 + @Retval Handle to FM object, or NULL for Failure.
84705 +*//***************************************************************************/
84706 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams);
84707 +
84708 +/**************************************************************************//**
84709 + @Function FM_PORT_Init
84710 +
84711 + @Description Initializes the FM PORT module by defining the software structure
84712 + and configuring the hardware registers.
84713 +
84714 + @Param[in] h_FmPort - FM PORT module descriptor
84715 +
84716 + @Return E_OK on success; Error code otherwise.
84717 +*//***************************************************************************/
84718 +t_Error FM_PORT_Init(t_Handle h_FmPort);
84719 +
84720 +/**************************************************************************//**
84721 + @Function FM_PORT_Free
84722 +
84723 + @Description Frees all resources that were assigned to FM PORT module.
84724 +
84725 + Calling this routine invalidates the descriptor.
84726 +
84727 + @Param[in] h_FmPort - FM PORT module descriptor
84728 +
84729 + @Return E_OK on success; Error code otherwise.
84730 +*//***************************************************************************/
84731 +t_Error FM_PORT_Free(t_Handle h_FmPort);
84732 +
84733 +
84734 +/**************************************************************************//**
84735 + @Group FM_PORT_advanced_init_grp FM Port Advanced Configuration Unit
84736 +
84737 + @Description Configuration functions used to change default values.
84738 +
84739 + @{
84740 +*//***************************************************************************/
84741 +
84742 +/**************************************************************************//**
84743 + @Description enum for defining QM frame dequeue
84744 +*//***************************************************************************/
84745 +typedef enum e_FmPortDeqType {
84746 + e_FM_PORT_DEQ_TYPE1, /**< Dequeue from the SP channel - with priority precedence,
84747 + and Intra-Class Scheduling respected. */
84748 + e_FM_PORT_DEQ_TYPE2, /**< Dequeue from the SP channel - with active FQ precedence,
84749 + and Intra-Class Scheduling respected. */
84750 + e_FM_PORT_DEQ_TYPE3 /**< Dequeue from the SP channel - with active FQ precedence,
84751 + and override Intra-Class Scheduling */
84752 +} e_FmPortDeqType;
84753 +
84754 +/**************************************************************************//**
84755 + @Description enum for defining QM frame dequeue
84756 +*//***************************************************************************/
84757 +typedef enum e_FmPortDeqPrefetchOption {
84758 + e_FM_PORT_DEQ_NO_PREFETCH, /**< QMI preforms a dequeue action for a single frame
84759 + only when a dedicated portID Tnum is waiting. */
84760 + e_FM_PORT_DEQ_PARTIAL_PREFETCH, /**< QMI preforms a dequeue action for 3 frames when
84761 + one dedicated portId tnum is waiting. */
84762 + e_FM_PORT_DEQ_FULL_PREFETCH /**< QMI preforms a dequeue action for 3 frames when
84763 + no dedicated portId tnums are waiting. */
84764 +
84765 +} e_FmPortDeqPrefetchOption;
84766 +
84767 +/**************************************************************************//**
84768 + @Description enum for defining port default color
84769 +*//***************************************************************************/
84770 +typedef enum e_FmPortColor {
84771 + e_FM_PORT_COLOR_GREEN, /**< Default port color is green */
84772 + e_FM_PORT_COLOR_YELLOW, /**< Default port color is yellow */
84773 + e_FM_PORT_COLOR_RED, /**< Default port color is red */
84774 + e_FM_PORT_COLOR_OVERRIDE /**< Ignore color */
84775 +} e_FmPortColor;
84776 +
84777 +/**************************************************************************//**
84778 + @Description A structure for defining Dual Tx rate limiting scale
84779 +*//***************************************************************************/
84780 +typedef enum e_FmPortDualRateLimiterScaleDown {
84781 + e_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
84782 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
84783 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
84784 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
84785 +} e_FmPortDualRateLimiterScaleDown;
84786 +
84787 +
84788 +/**************************************************************************//**
84789 + @Description A structure for defining FM port resources
84790 +*//***************************************************************************/
84791 +typedef struct t_FmPortRsrc {
84792 + uint32_t num; /**< Committed required resource */
84793 + uint32_t extra; /**< Extra (not committed) required resource */
84794 +} t_FmPortRsrc;
84795 +
84796 +/**************************************************************************//**
84797 + @Description A structure for defining observed pool depletion
84798 +*//***************************************************************************/
84799 +typedef struct t_FmPortObservedBufPoolDepletion {
84800 + t_FmBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */
84801 + t_FmExtPools poolsParams; /**< Which external buffer pools are observed
84802 + (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS),
84803 + and their sizes. */
84804 +} t_FmPortObservedBufPoolDepletion;
84805 +
84806 +/**************************************************************************//**
84807 + @Description A structure for defining Tx rate limiting
84808 +*//***************************************************************************/
84809 +typedef struct t_FmPortRateLimit {
84810 + uint16_t maxBurstSize; /**< in KBytes for Tx ports, in frames
84811 + for OP ports. (note that
84812 + for early chips burst size is
84813 + rounded up to a multiply of 1000 frames).*/
84814 + uint32_t rateLimit; /**< in Kb/sec for Tx ports, in frame/sec for
84815 + OP ports. Rate limit refers to
84816 + data rate (rather than line rate). */
84817 + e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For OP ports only. Not-valid
84818 + for some earlier chip revisions */
84819 +} t_FmPortRateLimit;
84820 +
84821 +/**************************************************************************//**
84822 + @Description A structure for defining the parameters of
84823 + the Rx port performance counters
84824 +*//***************************************************************************/
84825 +typedef struct t_FmPortPerformanceCnt {
84826 + uint8_t taskCompVal; /**< Task compare value */
84827 + uint8_t queueCompVal; /**< Rx queue/Tx confirm queue compare
84828 + value (unused for H/O) */
84829 + uint8_t dmaCompVal; /**< Dma compare value */
84830 + uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */
84831 +} t_FmPortPerformanceCnt;
84832 +
84833 +
84834 +/**************************************************************************//**
84835 + @Description A structure for defining the sizes of the Deep Sleep
84836 + the Auto Response tables
84837 +*//***************************************************************************/
84838 +typedef struct t_FmPortDsarTablesSizes
84839 +{
84840 + uint16_t maxNumOfArpEntries;
84841 + uint16_t maxNumOfEchoIpv4Entries;
84842 + uint16_t maxNumOfNdpEntries;
84843 + uint16_t maxNumOfEchoIpv6Entries;
84844 + uint16_t maxNumOfSnmpIPV4Entries;
84845 + uint16_t maxNumOfSnmpIPV6Entries;
84846 + uint16_t maxNumOfSnmpOidEntries;
84847 + uint16_t maxNumOfSnmpOidChar; /* total amount of character needed for the snmp table */
84848 +
84849 + uint16_t maxNumOfIpProtFiltering;
84850 + uint16_t maxNumOfTcpPortFiltering;
84851 + uint16_t maxNumOfUdpPortFiltering;
84852 +} t_FmPortDsarTablesSizes;
84853 +
84854 +
84855 +/**************************************************************************//**
84856 + @Function FM_PORT_ConfigDsarSupport
84857 +
84858 + @Description This function will allocate the amount of MURAM needed for
84859 + this max number of entries for Deep Sleep Auto Response.
84860 + it will calculate all needed MURAM for autoresponse including
84861 + necesary common stuff.
84862 +
84863 +
84864 + @Param[in] h_FmPort A handle to a FM Port module.
84865 + @Param[in] params A pointer to a structure containing the maximum
84866 + sizes of the auto response tables
84867 +
84868 + @Return E_OK on success; Error code otherwise.
84869 +
84870 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84871 +*//***************************************************************************/
84872 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params);
84873 +
84874 +/**************************************************************************//**
84875 + @Function FM_PORT_ConfigNumOfOpenDmas
84876 +
84877 + @Description Calling this routine changes the max number of open DMA's
84878 + available for this port. It changes this parameter in the
84879 + internal driver data base from its default configuration
84880 + [OP: 1]
84881 + [1G-RX, 1G-TX: 1 (+1)]
84882 + [10G-RX, 10G-TX: 8 (+8)]
84883 +
84884 + @Param[in] h_FmPort A handle to a FM Port module.
84885 + @Param[in] p_OpenDmas A pointer to a structure of parameters defining
84886 + the open DMA allocation.
84887 +
84888 + @Return E_OK on success; Error code otherwise.
84889 +
84890 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84891 +*//***************************************************************************/
84892 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas);
84893 +
84894 +/**************************************************************************//**
84895 + @Function FM_PORT_ConfigNumOfTasks
84896 +
84897 + @Description Calling this routine changes the max number of tasks
84898 + available for this port. It changes this parameter in the
84899 + internal driver data base from its default configuration
84900 + [OP: 1]
84901 + [1G-RX, 1G-TX: 3 (+2)]
84902 + [10G-RX, 10G-TX: 16 (+8)]
84903 +
84904 + @Param[in] h_FmPort A handle to a FM Port module.
84905 + @Param[in] p_NumOfTasks A pointer to a structure of parameters defining
84906 + the tasks allocation.
84907 +
84908 + @Return E_OK on success; Error code otherwise.
84909 +
84910 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84911 +*//***************************************************************************/
84912 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
84913 +
84914 +/**************************************************************************//**
84915 + @Function FM_PORT_ConfigSizeOfFifo
84916 +
84917 + @Description Calling this routine changes the max FIFO size configured for this port.
84918 +
84919 + This function changes the internal driver data base from its
84920 + default configuration. Please refer to the driver's User Guide for
84921 + information on default FIFO sizes in the various devices.
84922 + [OP: 2KB]
84923 + [1G-RX, 1G-TX: 11KB]
84924 + [10G-RX, 10G-TX: 12KB]
84925 +
84926 + @Param[in] h_FmPort A handle to a FM Port module.
84927 + @Param[in] p_SizeOfFifo A pointer to a structure of parameters defining
84928 + the FIFO allocation.
84929 +
84930 + @Return E_OK on success; Error code otherwise.
84931 +
84932 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84933 +*//***************************************************************************/
84934 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
84935 +
84936 +/**************************************************************************//**
84937 + @Function FM_PORT_ConfigDeqHighPriority
84938 +
84939 + @Description Calling this routine changes the dequeue priority in the
84940 + internal driver data base from its default configuration
84941 + 1G: [DEFAULT_PORT_deqHighPriority_1G]
84942 + 10G: [DEFAULT_PORT_deqHighPriority_10G]
84943 +
84944 + May be used for Non-Rx ports only
84945 +
84946 + @Param[in] h_FmPort A handle to a FM Port module.
84947 + @Param[in] highPri TRUE to select high priority, FALSE for normal operation.
84948 +
84949 + @Return E_OK on success; Error code otherwise.
84950 +
84951 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84952 +*//***************************************************************************/
84953 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri);
84954 +
84955 +/**************************************************************************//**
84956 + @Function FM_PORT_ConfigDeqType
84957 +
84958 + @Description Calling this routine changes the dequeue type parameter in the
84959 + internal driver data base from its default configuration
84960 + [DEFAULT_PORT_deqType].
84961 +
84962 + May be used for Non-Rx ports only
84963 +
84964 + @Param[in] h_FmPort A handle to a FM Port module.
84965 + @Param[in] deqType According to QM definition.
84966 +
84967 + @Return E_OK on success; Error code otherwise.
84968 +
84969 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84970 +*//***************************************************************************/
84971 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType);
84972 +
84973 +/**************************************************************************//**
84974 + @Function FM_PORT_ConfigDeqPrefetchOption
84975 +
84976 + @Description Calling this routine changes the dequeue prefetch option parameter in the
84977 + internal driver data base from its default configuration
84978 + [DEFAULT_PORT_deqPrefetchOption]
84979 + Note: Available for some chips only
84980 +
84981 + May be used for Non-Rx ports only
84982 +
84983 + @Param[in] h_FmPort A handle to a FM Port module.
84984 + @Param[in] deqPrefetchOption New option
84985 +
84986 + @Return E_OK on success; Error code otherwise.
84987 +
84988 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84989 +*//***************************************************************************/
84990 +t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption);
84991 +
84992 +/**************************************************************************//**
84993 + @Function FM_PORT_ConfigDeqByteCnt
84994 +
84995 + @Description Calling this routine changes the dequeue byte count parameter in
84996 + the internal driver data base from its default configuration
84997 + 1G:[DEFAULT_PORT_deqByteCnt_1G].
84998 + 10G:[DEFAULT_PORT_deqByteCnt_10G].
84999 +
85000 + May be used for Non-Rx ports only
85001 +
85002 + @Param[in] h_FmPort A handle to a FM Port module.
85003 + @Param[in] deqByteCnt New byte count
85004 +
85005 + @Return E_OK on success; Error code otherwise.
85006 +
85007 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85008 +*//***************************************************************************/
85009 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt);
85010 +
85011 +/**************************************************************************//**
85012 + @Function FM_PORT_ConfigBufferPrefixContent
85013 +
85014 + @Description Defines the structure, size and content of the application buffer.
85015 + The prefix will
85016 + In Tx ports, if 'passPrsResult', the application
85017 + should set a value to their offsets in the prefix of
85018 + the FM will save the first 'privDataSize', than,
85019 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
85020 + and timeStamp, and the packet itself (in this order), to the
85021 + application buffer, and to offset.
85022 + Calling this routine changes the buffer margins definitions
85023 + in the internal driver data base from its default
85024 + configuration: Data size: [DEFAULT_PORT_bufferPrefixContent_privDataSize]
85025 + Pass Parser result: [DEFAULT_PORT_bufferPrefixContent_passPrsResult].
85026 + Pass timestamp: [DEFAULT_PORT_bufferPrefixContent_passTimeStamp].
85027 +
85028 + May be used for all ports
85029 +
85030 + @Param[in] h_FmPort A handle to a FM Port module.
85031 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
85032 + structure of the buffer.
85033 + Out parameter: Start margin - offset
85034 + of data from start of external buffer.
85035 +
85036 + @Return E_OK on success; Error code otherwise.
85037 +
85038 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85039 +*//***************************************************************************/
85040 +t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort,
85041 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
85042 +
85043 +/**************************************************************************//**
85044 + @Function FM_PORT_ConfigCheksumLastBytesIgnore
85045 +
85046 + @Description Calling this routine changes the number of checksum bytes to ignore
85047 + parameter in the internal driver data base from its default configuration
85048 + [DEFAULT_PORT_cheksumLastBytesIgnore]
85049 +
85050 + May be used by Tx & Rx ports only
85051 +
85052 + @Param[in] h_FmPort A handle to a FM Port module.
85053 + @Param[in] cheksumLastBytesIgnore New value
85054 +
85055 + @Return E_OK on success; Error code otherwise.
85056 +
85057 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85058 +*//***************************************************************************/
85059 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore);
85060 +
85061 +/**************************************************************************//**
85062 + @Function FM_PORT_ConfigCutBytesFromEnd
85063 +
85064 + @Description Calling this routine changes the number of bytes to cut from a
85065 + frame's end parameter in the internal driver data base
85066 + from its default configuration [DEFAULT_PORT_cutBytesFromEnd]
85067 + Note that if the result of (frame length before chop - cutBytesFromEnd) is
85068 + less than 14 bytes, the chop operation is not executed.
85069 +
85070 + May be used for Rx ports only
85071 +
85072 + @Param[in] h_FmPort A handle to a FM Port module.
85073 + @Param[in] cutBytesFromEnd New value
85074 +
85075 + @Return E_OK on success; Error code otherwise.
85076 +
85077 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85078 +*//***************************************************************************/
85079 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd);
85080 +
85081 +/**************************************************************************//**
85082 + @Function FM_PORT_ConfigPoolDepletion
85083 +
85084 + @Description Calling this routine enables pause frame generation depending on the
85085 + depletion status of BM pools. It also defines the conditions to activate
85086 + this functionality. By default, this functionality is disabled.
85087 +
85088 + May be used for Rx ports only
85089 +
85090 + @Param[in] h_FmPort A handle to a FM Port module.
85091 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
85092 +
85093 + @Return E_OK on success; Error code otherwise.
85094 +
85095 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85096 +*//***************************************************************************/
85097 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmBufPoolDepletion *p_BufPoolDepletion);
85098 +
85099 +/**************************************************************************//**
85100 + @Function FM_PORT_ConfigObservedPoolDepletion
85101 +
85102 + @Description Calling this routine enables a mechanism to stop port enqueue
85103 + depending on the depletion status of selected BM pools.
85104 + It also defines the conditions to activate
85105 + this functionality. By default, this functionality is disabled.
85106 +
85107 + Note: Available for some chips only
85108 +
85109 + May be used for OP ports only
85110 +
85111 + @Param[in] h_FmPort A handle to a FM Port module.
85112 + @Param[in] p_FmPortObservedBufPoolDepletion A structure of parameters for pool depletion.
85113 +
85114 + @Return E_OK on success; Error code otherwise.
85115 +
85116 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85117 +*//***************************************************************************/
85118 +t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort,
85119 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion);
85120 +
85121 +/**************************************************************************//**
85122 + @Function FM_PORT_ConfigExtBufPools
85123 +
85124 + @Description This routine should be called for OP ports
85125 + that internally use BM buffer pools. In such cases, e.g. for fragmentation and
85126 + re-assembly, the FM needs new BM buffers. By calling this routine the user
85127 + specifies the BM buffer pools that should be used.
85128 +
85129 + Note: Available for some chips only
85130 +
85131 + May be used for OP ports only
85132 +
85133 + @Param[in] h_FmPort A handle to a FM Port module.
85134 + @Param[in] p_FmExtPools A structure of parameters for the external pools.
85135 +
85136 + @Return E_OK on success; Error code otherwise.
85137 +
85138 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85139 +*//***************************************************************************/
85140 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools);
85141 +
85142 +/**************************************************************************//**
85143 + @Function FM_PORT_ConfigBackupPools
85144 +
85145 + @Description Calling this routine allows the configuration of some of the BM pools
85146 + defined for this port as backup pools.
85147 + A pool configured to be a backup pool will be used only if all other
85148 + enabled non-backup pools are depleted.
85149 +
85150 + May be used for Rx ports only
85151 +
85152 + @Param[in] h_FmPort A handle to a FM Port module.
85153 + @Param[in] p_FmPortBackupBmPools An array of pool id's. All pools specified here will
85154 + be defined as backup pools.
85155 +
85156 + @Return E_OK on success; Error code otherwise.
85157 +
85158 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85159 +*//***************************************************************************/
85160 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmBackupBmPools *p_FmPortBackupBmPools);
85161 +
85162 +/**************************************************************************//**
85163 + @Function FM_PORT_ConfigFrmDiscardOverride
85164 +
85165 + @Description Calling this routine changes the error frames destination parameter
85166 + in the internal driver data base from its default configuration:
85167 + override = [DEFAULT_PORT_frmDiscardOverride]
85168 +
85169 + May be used for Rx and OP ports only
85170 +
85171 + @Param[in] h_FmPort A handle to a FM Port module.
85172 + @Param[in] override TRUE to override discarding of error frames and
85173 + enqueueing them to error queue.
85174 +
85175 + @Return E_OK on success; Error code otherwise.
85176 +
85177 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85178 +*//***************************************************************************/
85179 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override);
85180 +
85181 +/**************************************************************************//**
85182 + @Function FM_PORT_ConfigErrorsToDiscard
85183 +
85184 + @Description Calling this routine changes the behaviour on error parameter
85185 + in the internal driver data base from its default configuration:
85186 + [DEFAULT_PORT_errorsToDiscard].
85187 + If a requested error was previously defined as "ErrorsToEnqueue" it's
85188 + definition will change and the frame will be discarded.
85189 + Errors that were not defined either as "ErrorsToEnqueue" nor as
85190 + "ErrorsToDiscard", will be forwarded to CPU.
85191 +
85192 + May be used for Rx and OP ports only
85193 +
85194 + @Param[in] h_FmPort A handle to a FM Port module.
85195 + @Param[in] errs A list of errors to discard
85196 +
85197 + @Return E_OK on success; Error code otherwise.
85198 +
85199 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85200 +*//***************************************************************************/
85201 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
85202 +
85203 +/**************************************************************************//**
85204 + @Function FM_PORT_ConfigDmaSwapData
85205 +
85206 + @Description Calling this routine changes the DMA swap data aparameter
85207 + in the internal driver data base from its default
85208 + configuration [DEFAULT_PORT_dmaSwapData]
85209 +
85210 + May be used for all port types
85211 +
85212 + @Param[in] h_FmPort A handle to a FM Port module.
85213 + @Param[in] swapData New selection
85214 +
85215 + @Return E_OK on success; Error code otherwise.
85216 +
85217 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85218 +*//***************************************************************************/
85219 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData);
85220 +
85221 +/**************************************************************************//**
85222 + @Function FM_PORT_ConfigDmaIcCacheAttr
85223 +
85224 + @Description Calling this routine changes the internal context cache
85225 + attribute parameter in the internal driver data base
85226 + from its default configuration [DEFAULT_PORT_dmaIntContextCacheAttr]
85227 +
85228 + May be used for all port types
85229 +
85230 + @Param[in] h_FmPort A handle to a FM Port module.
85231 + @Param[in] intContextCacheAttr New selection
85232 +
85233 + @Return E_OK on success; Error code otherwise.
85234 +
85235 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85236 +*//***************************************************************************/
85237 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmDmaCacheOption intContextCacheAttr);
85238 +
85239 +/**************************************************************************//**
85240 + @Function FM_PORT_ConfigDmaHdrAttr
85241 +
85242 + @Description Calling this routine changes the header cache
85243 + attribute parameter in the internal driver data base
85244 + from its default configuration [DEFAULT_PORT_dmaHeaderCacheAttr]
85245 +
85246 + May be used for all port types
85247 +
85248 + @Param[in] h_FmPort A handle to a FM Port module.
85249 + @Param[in] headerCacheAttr New selection
85250 +
85251 + @Return E_OK on success; Error code otherwise.
85252 +
85253 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85254 +*//***************************************************************************/
85255 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmDmaCacheOption headerCacheAttr);
85256 +
85257 +/**************************************************************************//**
85258 + @Function FM_PORT_ConfigDmaScatterGatherAttr
85259 +
85260 + @Description Calling this routine changes the scatter gather cache
85261 + attribute parameter in the internal driver data base
85262 + from its default configuration [DEFAULT_PORT_dmaScatterGatherCacheAttr]
85263 +
85264 + May be used for all port types
85265 +
85266 + @Param[in] h_FmPort A handle to a FM Port module.
85267 + @Param[in] scatterGatherCacheAttr New selection
85268 +
85269 + @Return E_OK on success; Error code otherwise.
85270 +
85271 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85272 +*//***************************************************************************/
85273 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr);
85274 +
85275 +/**************************************************************************//**
85276 + @Function FM_PORT_ConfigDmaWriteOptimize
85277 +
85278 + @Description Calling this routine changes the write optimization
85279 + parameter in the internal driver data base
85280 + from its default configuration: By default optimize = [DEFAULT_PORT_dmaWriteOptimize].
85281 + Note:
85282 +
85283 + 1. For head optimization, data alignment must be >= 16 (supported by default).
85284 +
85285 + 3. For tail optimization, note that the optimization is performed by extending the write transaction
85286 + of the frame payload at the tail as needed to achieve optimal bus transfers, so that the last write
85287 + is extended to be on 16/64 bytes aligned block (chip dependent).
85288 +
85289 + Relevant for non-Tx port types
85290 +
85291 + @Param[in] h_FmPort A handle to a FM Port module.
85292 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
85293 +
85294 + @Return E_OK on success; Error code otherwise.
85295 +
85296 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85297 +*//***************************************************************************/
85298 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize);
85299 +
85300 +/**************************************************************************//**
85301 + @Function FM_PORT_ConfigNoScatherGather
85302 +
85303 + @Description Calling this routine changes the noScatherGather parameter in internal driver data base
85304 + from its default configuration.
85305 +
85306 + @Param[in] h_FmPort A handle to a FM Port module.
85307 + @Param[in] noScatherGather (TRUE - frame is discarded if can not be stored in single buffer,
85308 + FALSE - frame can be stored in scatter gather (S/G) format).
85309 +
85310 + @Return E_OK on success; Error code otherwise.
85311 +
85312 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85313 +*//***************************************************************************/
85314 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather);
85315 +
85316 +/**************************************************************************//**
85317 + @Function FM_PORT_ConfigDfltColor
85318 +
85319 + @Description Calling this routine changes the internal default color parameter
85320 + in the internal driver data base
85321 + from its default configuration [DEFAULT_PORT_color]
85322 +
85323 + May be used for all port types
85324 +
85325 + @Param[in] h_FmPort A handle to a FM Port module.
85326 + @Param[in] color New selection
85327 +
85328 + @Return E_OK on success; Error code otherwise.
85329 +
85330 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85331 +*//***************************************************************************/
85332 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color);
85333 +
85334 +/**************************************************************************//**
85335 + @Function FM_PORT_ConfigSyncReq
85336 +
85337 + @Description Calling this routine changes the synchronization attribute parameter
85338 + in the internal driver data base from its default configuration:
85339 + syncReq = [DEFAULT_PORT_syncReq]
85340 +
85341 + May be used for all port types
85342 +
85343 + @Param[in] h_FmPort A handle to a FM Port module.
85344 + @Param[in] syncReq TRUE to request synchronization, FALSE otherwize.
85345 +
85346 + @Return E_OK on success; Error code otherwise.
85347 +
85348 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85349 +*//***************************************************************************/
85350 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq);
85351 +
85352 +/**************************************************************************//**
85353 + @Function FM_PORT_ConfigForwardReuseIntContext
85354 +
85355 + @Description This routine is relevant for Rx ports that are routed to OP port.
85356 + It changes the internal context reuse option in the internal
85357 + driver data base from its default configuration:
85358 + reuse = [DEFAULT_PORT_forwardIntContextReuse]
85359 +
85360 + May be used for Rx ports only
85361 +
85362 + @Param[in] h_FmPort A handle to a FM Port module.
85363 + @Param[in] reuse TRUE to reuse internal context on frames
85364 + forwarded to OP port.
85365 +
85366 + @Return E_OK on success; Error code otherwise.
85367 +
85368 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85369 +*//***************************************************************************/
85370 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool reuse);
85371 +
85372 +/**************************************************************************//**
85373 + @Function FM_PORT_ConfigDontReleaseTxBufToBM
85374 +
85375 + @Description This routine should be called if no Tx confirmation
85376 + is done, and yet buffers should not be released to the BM.
85377 + Normally, buffers are returned using the Tx confirmation
85378 + process. When Tx confirmation is not used (defFqid=0),
85379 + buffers are typically released to the BM. This routine
85380 + may be called to avoid this behavior and not release the
85381 + buffers.
85382 +
85383 + May be used for Tx ports only
85384 +
85385 + @Param[in] h_FmPort A handle to a FM Port module.
85386 +
85387 + @Return E_OK on success; Error code otherwise.
85388 +
85389 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85390 +*//***************************************************************************/
85391 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort);
85392 +
85393 +/**************************************************************************//**
85394 + @Function FM_PORT_ConfigIMMaxRxBufLength
85395 +
85396 + @Description Changes the maximum receive buffer length from its default
85397 + configuration: Closest rounded down power of 2 value of the
85398 + data buffer size.
85399 +
85400 + The maximum receive buffer length directly affects the structure
85401 + of received frames (single- or multi-buffered) and the performance
85402 + of both the FM and the driver.
85403 +
85404 + The selection between single- or multi-buffered frames should be
85405 + done according to the characteristics of the specific application.
85406 + The recommended mode is to use a single data buffer per packet,
85407 + as this mode provides the best performance. However, the user can
85408 + select to use multiple data buffers per packet.
85409 +
85410 + @Param[in] h_FmPort A handle to a FM Port module.
85411 + @Param[in] newVal Maximum receive buffer length (in bytes).
85412 +
85413 + @Return E_OK on success; Error code otherwise.
85414 +
85415 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85416 + This routine is to be used only if Independent-Mode is enabled.
85417 +*//***************************************************************************/
85418 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal);
85419 +
85420 +/**************************************************************************//**
85421 + @Function FM_PORT_ConfigIMRxBdRingLength
85422 +
85423 + @Description Changes the receive BD ring length from its default
85424 + configuration:[DEFAULT_PORT_rxBdRingLength]
85425 +
85426 + @Param[in] h_FmPort A handle to a FM Port module.
85427 + @Param[in] newVal The desired BD ring length.
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 + This routine is to be used only if Independent-Mode is enabled.
85433 +*//***************************************************************************/
85434 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85435 +
85436 +/**************************************************************************//**
85437 + @Function FM_PORT_ConfigIMTxBdRingLength
85438 +
85439 + @Description Changes the transmit BD ring length from its default
85440 + configuration:[DEFAULT_PORT_txBdRingLength]
85441 +
85442 + @Param[in] h_FmPort A handle to a FM Port module.
85443 + @Param[in] newVal The desired BD ring length.
85444 +
85445 + @Return E_OK on success; Error code otherwise.
85446 +
85447 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85448 + This routine is to be used only if Independent-Mode is enabled.
85449 +*//***************************************************************************/
85450 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85451 +
85452 +/**************************************************************************//**
85453 + @Function FM_PORT_ConfigIMFmanCtrlExternalStructsMemory
85454 +
85455 + @Description Configures memory partition and attributes for FMan-Controller
85456 + data structures (e.g. BD rings).
85457 + Calling this routine changes the internal driver data base
85458 + from its default configuration
85459 + [DEFAULT_PORT_ImfwExtStructsMemId, DEFAULT_PORT_ImfwExtStructsMemAttr].
85460 +
85461 + @Param[in] h_FmPort A handle to a FM Port module.
85462 + @Param[in] memId Memory partition ID.
85463 + @Param[in] memAttributes Memory attributes mask (a combination of MEMORY_ATTR_x flags).
85464 +
85465 + @Return E_OK on success; Error code otherwise.
85466 +*//***************************************************************************/
85467 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
85468 + uint8_t memId,
85469 + uint32_t memAttributes);
85470 +
85471 +/**************************************************************************//**
85472 + @Function FM_PORT_ConfigIMPolling
85473 +
85474 + @Description Changes the Rx flow from interrupt driven (default) to polling.
85475 +
85476 + @Param[in] h_FmPort A handle to a FM Port module.
85477 +
85478 + @Return E_OK on success; Error code otherwise.
85479 +
85480 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85481 + This routine is to be used only if Independent-Mode is enabled.
85482 +*//***************************************************************************/
85483 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort);
85484 +
85485 +/**************************************************************************//**
85486 + @Function FM_PORT_ConfigMaxFrameLength
85487 +
85488 + @Description Changes the definition of the max size of frame that should be
85489 + transmitted/received on this port from its default value [DEFAULT_PORT_maxFrameLength].
85490 + This parameter is used for confirmation of the minimum Fifo
85491 + size calculations and only for Tx ports or ports working in
85492 + independent mode. This should be larger than the maximum possible
85493 + MTU that will be used for this port (i.e. its MAC).
85494 +
85495 + @Param[in] h_FmPort A handle to a FM Port module.
85496 + @Param[in] length Max size of frame
85497 +
85498 + @Return E_OK on success; Error code otherwise.
85499 +
85500 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85501 + This routine is to be used only if Independent-Mode is enabled.
85502 +*//***************************************************************************/
85503 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length);
85504 +
85505 +/**************************************************************************//*
85506 + @Function FM_PORT_ConfigTxFifoMinFillLevel
85507 +
85508 + @Description Calling this routine changes the fifo minimum
85509 + fill level parameter in the internal driver data base
85510 + from its default configuration [DEFAULT_PORT_txFifoMinFillLevel]
85511 +
85512 + May be used for Tx ports only
85513 +
85514 + @Param[in] h_FmPort A handle to a FM Port module.
85515 + @Param[in] minFillLevel New value
85516 +
85517 + @Return E_OK on success; Error code otherwise.
85518 +
85519 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85520 +*//***************************************************************************/
85521 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel);
85522 +
85523 +/**************************************************************************//*
85524 + @Function FM_PORT_ConfigFifoDeqPipelineDepth
85525 +
85526 + @Description Calling this routine changes the fifo dequeue
85527 + pipeline depth parameter in the internal driver data base
85528 +
85529 + from its default configuration: 1G ports: [DEFAULT_PORT_fifoDeqPipelineDepth_1G],
85530 + 10G port: [DEFAULT_PORT_fifoDeqPipelineDepth_10G],
85531 + OP port: [DEFAULT_PORT_fifoDeqPipelineDepth_OH]
85532 +
85533 + May be used for Tx/OP ports only
85534 +
85535 + @Param[in] h_FmPort A handle to a FM Port module.
85536 + @Param[in] deqPipelineDepth New value
85537 +
85538 + @Return E_OK on success; Error code otherwise.
85539 +
85540 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85541 +*//***************************************************************************/
85542 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth);
85543 +
85544 +/**************************************************************************//*
85545 + @Function FM_PORT_ConfigTxFifoLowComfLevel
85546 +
85547 + @Description Calling this routine changes the fifo low comfort level
85548 + parameter in internal driver data base
85549 + from its default configuration [DEFAULT_PORT_txFifoLowComfLevel]
85550 +
85551 + May be used for Tx ports only
85552 +
85553 + @Param[in] h_FmPort A handle to a FM Port module.
85554 + @Param[in] fifoLowComfLevel New value
85555 +
85556 + @Return E_OK on success; Error code otherwise.
85557 +
85558 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85559 +*//***************************************************************************/
85560 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel);
85561 +
85562 +/**************************************************************************//*
85563 + @Function FM_PORT_ConfigRxFifoThreshold
85564 +
85565 + @Description Calling this routine changes the threshold of the FIFO
85566 + fill level parameter in the internal driver data base
85567 + from its default configuration [DEFAULT_PORT_rxFifoThreshold]
85568 +
85569 + If the total number of buffers which are
85570 + currently in use and associated with the
85571 + specific RX port exceed this threshold, the
85572 + BMI will signal the MAC to send a pause frame
85573 + over the link.
85574 +
85575 + May be used for Rx ports only
85576 +
85577 + @Param[in] h_FmPort A handle to a FM Port module.
85578 + @Param[in] fifoThreshold New value
85579 +
85580 + @Return E_OK on success; Error code otherwise.
85581 +
85582 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85583 +*//***************************************************************************/
85584 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold);
85585 +
85586 +/**************************************************************************//*
85587 + @Function FM_PORT_ConfigRxFifoPriElevationLevel
85588 +
85589 + @Description Calling this routine changes the priority elevation level
85590 + parameter in the internal driver data base from its default
85591 + configuration [DEFAULT_PORT_rxFifoPriElevationLevel]
85592 +
85593 + If the total number of buffers which are currently in use and
85594 + associated with the specific RX port exceed the amount specified
85595 + in priElevationLevel, BMI will signal the main FM's DMA to
85596 + elevate the FM priority on the system bus.
85597 +
85598 + May be used for Rx ports only
85599 +
85600 + @Param[in] h_FmPort A handle to a FM Port module.
85601 + @Param[in] priElevationLevel New value
85602 +
85603 + @Return E_OK on success; Error code otherwise.
85604 +
85605 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85606 +*//***************************************************************************/
85607 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel);
85608 +
85609 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
85610 +/**************************************************************************//*
85611 + @Function FM_PORT_ConfigBCBWorkaround
85612 +
85613 + @Description Configures BCB errata workaround.
85614 +
85615 + When BCB errata is applicable, the workaround is always
85616 + performed by FM Controller. Thus, this functions doesn't
85617 + actually enable errata workaround but rather allows driver
85618 + to perform adjustments required due to errata workaround
85619 + execution in FM controller.
85620 +
85621 + Applying BCB workaround also configures FM_PORT_FRM_ERR_PHYSICAL
85622 + errors to be discarded. Thus FM_PORT_FRM_ERR_PHYSICAL can't be
85623 + set by FM_PORT_SetErrorsRoute() function.
85624 +
85625 + @Param[in] h_FmPort A handle to a FM Port module.
85626 +
85627 + @Return E_OK on success; Error code otherwise.
85628 +
85629 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85630 +*//***************************************************************************/
85631 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort);
85632 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
85633 +
85634 +#if (DPAA_VERSION >= 11)
85635 +/**************************************************************************//*
85636 + @Function FM_PORT_ConfigInternalBuffOffset
85637 +
85638 + @Description Configures internal buffer offset.
85639 +
85640 + May be used for Rx and OP ports only
85641 +
85642 + @Param[in] h_FmPort A handle to a FM Port module.
85643 + @Param[in] val New value
85644 +
85645 + @Return E_OK on success; Error code otherwise.
85646 +
85647 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85648 +*//***************************************************************************/
85649 +t_Error FM_PORT_ConfigInternalBuffOffset(t_Handle h_FmPort, uint8_t val);
85650 +#endif /* (DPAA_VERSION >= 11) */
85651 +
85652 +/** @} */ /* end of FM_PORT_advanced_init_grp group */
85653 +/** @} */ /* end of FM_PORT_init_grp group */
85654 +
85655 +
85656 +/**************************************************************************//**
85657 + @Group FM_PORT_runtime_control_grp FM Port Runtime Control Unit
85658 +
85659 + @Description FM Port Runtime control unit API functions, definitions and enums.
85660 +
85661 + @{
85662 +*//***************************************************************************/
85663 +
85664 +/**************************************************************************//**
85665 + @Description enum for defining FM Port counters
85666 +*//***************************************************************************/
85667 +typedef enum e_FmPortCounters {
85668 + e_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
85669 + e_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
85670 + e_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
85671 + e_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
85672 + e_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
85673 + e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
85674 + e_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
85675 + e_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
85676 + e_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
85677 + e_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
85678 + e_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
85679 + e_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
85680 + e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
85681 + e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
85682 + e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
85683 + e_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
85684 + e_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
85685 + e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
85686 + e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
85687 + e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
85688 + e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
85689 + e_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
85690 +} e_FmPortCounters;
85691 +
85692 +typedef struct t_FmPortBmiStats {
85693 + uint32_t cntCycle;
85694 + uint32_t cntTaskUtil;
85695 + uint32_t cntQueueUtil;
85696 + uint32_t cntDmaUtil;
85697 + uint32_t cntFifoUtil;
85698 + uint32_t cntRxPauseActivation;
85699 + uint32_t cntFrame;
85700 + uint32_t cntDiscardFrame;
85701 + uint32_t cntDeallocBuf;
85702 + uint32_t cntRxBadFrame;
85703 + uint32_t cntRxLargeFrame;
85704 + uint32_t cntRxFilterFrame;
85705 + uint32_t cntRxListDmaErr;
85706 + uint32_t cntRxOutOfBuffersDiscard;
85707 + uint32_t cntWredDiscard;
85708 + uint32_t cntLengthErr;
85709 + uint32_t cntUnsupportedFormat;
85710 +} t_FmPortBmiStats;
85711 +
85712 +/**************************************************************************//**
85713 + @Description Structure for Port id parameters.
85714 + Fields commented 'IN' are passed by the port module to be used
85715 + by the FM module.
85716 + Fields commented 'OUT' will be filled by FM before returning to port.
85717 +*//***************************************************************************/
85718 +typedef struct t_FmPortCongestionGrps {
85719 + uint16_t numOfCongestionGrpsToConsider; /**< The number of required CGs
85720 + to define the size of the following array */
85721 + uint8_t congestionGrpsToConsider[FM_PORT_NUM_OF_CONGESTION_GRPS];
85722 + /**< An array of CG indexes;
85723 + Note that the size of the array should be
85724 + 'numOfCongestionGrpsToConsider'. */
85725 +#if (DPAA_VERSION >= 11)
85726 + bool pfcPrioritiesEn[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
85727 + /**< a matrix that represents the map between the CG ids
85728 + defined in 'congestionGrpsToConsider' to the priorties
85729 + mapping array. */
85730 +#endif /* (DPAA_VERSION >= 11) */
85731 +} t_FmPortCongestionGrps;
85732 +
85733 +/**************************************************************************//**
85734 + @Description Structure for Deep Sleep Auto Response ARP Entry
85735 +*//***************************************************************************/
85736 +typedef struct t_FmPortDsarArpEntry
85737 +{
85738 + uint32_t ipAddress;
85739 + uint8_t mac[6];
85740 + bool isVlan;
85741 + uint16_t vid;
85742 +} t_FmPortDsarArpEntry;
85743 +
85744 +/**************************************************************************//**
85745 + @Description Structure for Deep Sleep Auto Response ARP info
85746 +*//***************************************************************************/
85747 +typedef struct t_FmPortDsarArpInfo
85748 +{
85749 + uint8_t tableSize;
85750 + t_FmPortDsarArpEntry *p_AutoResTable;
85751 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
85752 +} t_FmPortDsarArpInfo;
85753 +
85754 +/**************************************************************************//**
85755 + @Description Structure for Deep Sleep Auto Response NDP Entry
85756 +*//***************************************************************************/
85757 +typedef struct t_FmPortDsarNdpEntry
85758 +{
85759 + uint32_t ipAddress[4];
85760 + uint8_t mac[6];
85761 + bool isVlan;
85762 + uint16_t vid;
85763 +} t_FmPortDsarNdpEntry;
85764 +
85765 +/**************************************************************************//**
85766 + @Description Structure for Deep Sleep Auto Response NDP info
85767 +*//***************************************************************************/
85768 +typedef struct t_FmPortDsarNdpInfo
85769 +{
85770 + uint32_t multicastGroup;
85771 +
85772 + uint8_t tableSizeAssigned;
85773 + t_FmPortDsarNdpEntry *p_AutoResTableAssigned; /* This list refer to solicitation IP addresses.
85774 + Note that all IP adresses must be from the same multicast group.
85775 + This will be checked and if not operation will fail. */
85776 + uint8_t tableSizeTmp;
85777 + t_FmPortDsarNdpEntry *p_AutoResTableTmp; /* This list refer to temp IP addresses.
85778 + Note that all temp IP adresses must be from the same multicast group.
85779 + This will be checked and if not operation will fail. */
85780 +
85781 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
85782 +
85783 +} t_FmPortDsarNdpInfo;
85784 +
85785 +/**************************************************************************//**
85786 + @Description Structure for Deep Sleep Auto Response ICMPV4 info
85787 +*//***************************************************************************/
85788 +typedef struct t_FmPortDsarEchoIpv4Info
85789 +{
85790 + uint8_t tableSize;
85791 + t_FmPortDsarArpEntry *p_AutoResTable;
85792 +} t_FmPortDsarEchoIpv4Info;
85793 +
85794 +/**************************************************************************//**
85795 + @Description Structure for Deep Sleep Auto Response ICMPV6 info
85796 +*//***************************************************************************/
85797 +typedef struct t_FmPortDsarEchoIpv6Info
85798 +{
85799 + uint8_t tableSize;
85800 + t_FmPortDsarNdpEntry *p_AutoResTable;
85801 +} t_FmPortDsarEchoIpv6Info;
85802 +
85803 +/**************************************************************************//**
85804 +@Description Deep Sleep Auto Response SNMP OIDs table entry
85805 +
85806 +*//***************************************************************************/
85807 +typedef struct {
85808 + uint16_t oidSize;
85809 + uint8_t *oidVal; /* only the oid string */
85810 + uint16_t resSize;
85811 + uint8_t *resVal; /* resVal will be the entire reply,
85812 + i.e. "Type|Length|Value" */
85813 +} t_FmPortDsarOidsEntry;
85814 +
85815 +/**************************************************************************//**
85816 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
85817 + Refer to the FMan Controller spec for more details.
85818 +*//***************************************************************************/
85819 +typedef struct
85820 +{
85821 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
85822 + bool isVlan;
85823 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
85824 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
85825 +} t_FmPortDsarSnmpIpv4AddrTblEntry;
85826 +
85827 +/**************************************************************************//**
85828 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
85829 + Refer to the FMan Controller spec for more details.
85830 +*//***************************************************************************/
85831 +typedef struct
85832 +{
85833 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
85834 + bool isVlan;
85835 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
85836 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
85837 +} t_FmPortDsarSnmpIpv6AddrTblEntry;
85838 +
85839 +/**************************************************************************//**
85840 + @Description Deep Sleep Auto Response SNMP Descriptor
85841 +
85842 +*//***************************************************************************/
85843 +typedef struct
85844 +{
85845 + uint16_t control; /**< Control bits [0-15]. */
85846 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
85847 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
85848 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
85849 + t_FmPortDsarSnmpIpv4AddrTblEntry *p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
85850 + t_FmPortDsarSnmpIpv6AddrTblEntry *p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
85851 + uint8_t *p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
85852 + uint8_t *p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
85853 + t_FmPortDsarOidsEntry *p_OidsTbl; /**< Pointer to OIDs table. */
85854 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
85855 +} t_FmPortDsarSnmpInfo;
85856 +
85857 +/**************************************************************************//**
85858 + @Description Structure for Deep Sleep Auto Response filtering Entry
85859 +*//***************************************************************************/
85860 +typedef struct t_FmPortDsarFilteringEntry
85861 +{
85862 + uint16_t srcPort;
85863 + uint16_t dstPort;
85864 + uint16_t srcPortMask;
85865 + uint16_t dstPortMask;
85866 +} t_FmPortDsarFilteringEntry;
85867 +
85868 +/**************************************************************************//**
85869 + @Description Structure for Deep Sleep Auto Response filtering info
85870 +*//***************************************************************************/
85871 +typedef struct t_FmPortDsarFilteringInfo
85872 +{
85873 + /* IP protocol filtering parameters */
85874 + uint8_t ipProtTableSize;
85875 + uint8_t *p_IpProtTablePtr;
85876 + bool ipProtPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
85877 + hit will pass the packet to UDP/TCP filters if needed and if not
85878 + to the classification tree. If the classification tree will pass
85879 + the packet to a queue it will cause a wake interupt.
85880 + When FALSE it the other way around. */
85881 + /* UDP port filtering parameters */
85882 + uint8_t udpPortsTableSize;
85883 + t_FmPortDsarFilteringEntry *p_UdpPortsTablePtr;
85884 + bool udpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
85885 + hit will pass the packet to classification tree.
85886 + If the classification tree will pass the packet to a queue it
85887 + will cause a wake interupt.
85888 + When FALSE it the other way around. */
85889 + /* TCP port filtering parameters */
85890 + uint16_t tcpFlagsMask;
85891 + uint8_t tcpPortsTableSize;
85892 + t_FmPortDsarFilteringEntry *p_TcpPortsTablePtr;
85893 + bool tcpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
85894 + hit will pass the packet to classification tree.
85895 + If the classification tree will pass the packet to a queue it
85896 + will cause a wake interupt.
85897 + When FALSE it the other way around. */
85898 +} t_FmPortDsarFilteringInfo;
85899 +
85900 +/**************************************************************************//**
85901 + @Description Structure for Deep Sleep Auto Response parameters
85902 +*//***************************************************************************/
85903 +typedef struct t_FmPortDsarParams
85904 +{
85905 + t_Handle h_FmPortTx;
85906 + t_FmPortDsarArpInfo *p_AutoResArpInfo;
85907 + t_FmPortDsarEchoIpv4Info *p_AutoResEchoIpv4Info;
85908 + t_FmPortDsarNdpInfo *p_AutoResNdpInfo;
85909 + t_FmPortDsarEchoIpv6Info *p_AutoResEchoIpv6Info;
85910 + t_FmPortDsarSnmpInfo *p_AutoResSnmpInfo;
85911 + t_FmPortDsarFilteringInfo *p_AutoResFilteringInfo;
85912 +} t_FmPortDsarParams;
85913 +
85914 +/**************************************************************************//**
85915 + @Function FM_PORT_EnterDsar
85916 +
85917 + @Description Enter Deep Sleep Auto Response mode.
85918 + This function write the apropriate values to in the relevant
85919 + tables in the MURAM.
85920 +
85921 + @Param[in] h_FmPortRx - FM PORT module descriptor
85922 + @Param[in] params - Auto Response parameters
85923 +
85924 + @Return E_OK on success; Error code otherwise.
85925 +
85926 + @Cautions Allowed only following FM_PORT_Init().
85927 +*//***************************************************************************/
85928 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params);
85929 +
85930 +/**************************************************************************//**
85931 + @Function FM_PORT_EnterDsarFinal
85932 +
85933 + @Description Enter Deep Sleep Auto Response mode.
85934 + This function sets the Tx port in independent mode as needed
85935 + and redirect the receive flow to go through the
85936 + Dsar Fman-ctrl code
85937 +
85938 + @Param[in] h_DsarRxPort - FM Rx PORT module descriptor
85939 + @Param[in] h_DsarTxPort - FM Tx PORT module descriptor
85940 +
85941 + @Return E_OK on success; Error code otherwise.
85942 +
85943 + @Cautions Allowed only following FM_PORT_Init().
85944 +*//***************************************************************************/
85945 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort);
85946 +
85947 +/**************************************************************************//**
85948 + @Function FM_PORT_ExitDsar
85949 +
85950 + @Description Exit Deep Sleep Auto Response mode.
85951 + This function reverse the AR mode and put the ports back into
85952 + their original wake mode
85953 +
85954 + @Param[in] h_FmPortRx - FM PORT Rx module descriptor
85955 + @Param[in] h_FmPortTx - FM PORT Tx module descriptor
85956 +
85957 + @Return E_OK on success; Error code otherwise.
85958 +
85959 + @Cautions Allowed only following FM_PORT_EnterDsar().
85960 +*//***************************************************************************/
85961 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx);
85962 +
85963 +/**************************************************************************//**
85964 + @Function FM_PORT_IsInDsar
85965 +
85966 + @Description This function returns TRUE if the port was set as Auto Response
85967 + and FALSE if not. Once Exit AR mode it will return FALSE as well
85968 + until re-enabled once more.
85969 +
85970 + @Param[in] h_FmPort - FM PORT module descriptor
85971 +
85972 + @Return E_OK on success; Error code otherwise.
85973 +*//***************************************************************************/
85974 +bool FM_PORT_IsInDsar(t_Handle h_FmPort);
85975 +
85976 +typedef struct t_FmPortDsarStats
85977 +{
85978 + uint32_t arpArCnt;
85979 + uint32_t echoIcmpv4ArCnt;
85980 + uint32_t ndpArCnt;
85981 + uint32_t echoIcmpv6ArCnt;
85982 + uint32_t snmpGetCnt;
85983 + uint32_t snmpGetNextCnt;
85984 +} t_FmPortDsarStats;
85985 +
85986 +/**************************************************************************//**
85987 + @Function FM_PORT_GetDsarStats
85988 +
85989 + @Description Return statistics for Deep Sleep Auto Response
85990 +
85991 + @Param[in] h_FmPortRx - FM PORT module descriptor
85992 + @Param[out] stats - structure containing the statistics counters
85993 +
85994 + @Return E_OK on success; Error code otherwise.
85995 +*//***************************************************************************/
85996 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats);
85997 +
85998 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
85999 +/**************************************************************************//**
86000 + @Function FM_PORT_DumpRegs
86001 +
86002 + @Description Dump all regs.
86003 +
86004 + Calling this routine invalidates the descriptor.
86005 +
86006 + @Param[in] h_FmPort - FM PORT module descriptor
86007 +
86008 + @Return E_OK on success; Error code otherwise.
86009 +
86010 + @Cautions Allowed only following FM_PORT_Init().
86011 +*//***************************************************************************/
86012 +t_Error FM_PORT_DumpRegs(t_Handle h_FmPort);
86013 +#endif /* (defined(DEBUG_ERRORS) && ... */
86014 +
86015 +/**************************************************************************//**
86016 + @Function FM_PORT_GetBufferDataOffset
86017 +
86018 + @Description Relevant for Rx ports.
86019 + Returns the data offset from the beginning of the data buffer
86020 +
86021 + @Param[in] h_FmPort - FM PORT module descriptor
86022 +
86023 + @Return data offset.
86024 +
86025 + @Cautions Allowed only following FM_PORT_Init().
86026 +*//***************************************************************************/
86027 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort);
86028 +
86029 +/**************************************************************************//**
86030 + @Function FM_PORT_GetBufferICInfo
86031 +
86032 + @Description Returns the Internal Context offset from the beginning of the data buffer
86033 +
86034 + @Param[in] h_FmPort - FM PORT module descriptor
86035 + @Param[in] p_Data - A pointer to the data buffer.
86036 +
86037 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
86038 + configured for this port.
86039 +
86040 + @Cautions Allowed only following FM_PORT_Init().
86041 +*//***************************************************************************/
86042 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data);
86043 +
86044 +/**************************************************************************//**
86045 + @Function FM_PORT_GetBufferPrsResult
86046 +
86047 + @Description Returns the pointer to the parse result in the data buffer.
86048 + In Rx ports this is relevant after reception, if parse
86049 + result is configured to be part of the data passed to the
86050 + application. For non Rx ports it may be used to get the pointer
86051 + of the area in the buffer where parse result should be
86052 + initialized - if so configured.
86053 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
86054 + configuration.
86055 +
86056 + @Param[in] h_FmPort - FM PORT module descriptor
86057 + @Param[in] p_Data - A pointer to the data buffer.
86058 +
86059 + @Return Parse result pointer on success, NULL if parse result was not
86060 + configured for this port.
86061 +
86062 + @Cautions Allowed only following FM_PORT_Init().
86063 +*//***************************************************************************/
86064 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data);
86065 +
86066 +/**************************************************************************//**
86067 + @Function FM_PORT_GetBufferTimeStamp
86068 +
86069 + @Description Returns the time stamp in the data buffer.
86070 + Relevant for Rx ports for getting the buffer time stamp.
86071 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
86072 + configuration.
86073 +
86074 + @Param[in] h_FmPort - FM PORT module descriptor
86075 + @Param[in] p_Data - A pointer to the data buffer.
86076 +
86077 + @Return A pointer to the hash result on success, NULL otherwise.
86078 +
86079 + @Cautions Allowed only following FM_PORT_Init().
86080 +*//***************************************************************************/
86081 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data);
86082 +
86083 +/**************************************************************************//**
86084 + @Function FM_PORT_GetBufferHashResult
86085 +
86086 + @Description Given a data buffer, on the condition that hash result was defined
86087 + as a part of the buffer content (see FM_PORT_ConfigBufferPrefixContent)
86088 + this routine will return the pointer to the hash result location in the
86089 + buffer prefix.
86090 +
86091 + @Param[in] h_FmPort - FM PORT module descriptor
86092 + @Param[in] p_Data - A pointer to the data buffer.
86093 +
86094 + @Return A pointer to the hash result on success, NULL otherwise.
86095 +
86096 + @Cautions Allowed only following FM_PORT_Init().
86097 +*//***************************************************************************/
86098 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data);
86099 +
86100 +/**************************************************************************//**
86101 + @Function FM_PORT_Disable
86102 +
86103 + @Description Gracefully disable an FM port. The port will not start new tasks after all
86104 + tasks associated with the port are terminated.
86105 +
86106 + @Param[in] h_FmPort A handle to a FM Port module.
86107 +
86108 + @Return E_OK on success; Error code otherwise.
86109 +
86110 + @Cautions Allowed only following FM_PORT_Init().
86111 + This is a blocking routine, it returns after port is
86112 + gracefully stopped, i.e. the port will not except new frames,
86113 + but it will finish all frames or tasks which were already began
86114 +*//***************************************************************************/
86115 +t_Error FM_PORT_Disable(t_Handle h_FmPort);
86116 +
86117 +/**************************************************************************//**
86118 + @Function FM_PORT_Enable
86119 +
86120 + @Description A runtime routine provided to allow disable/enable of port.
86121 +
86122 + @Param[in] h_FmPort A handle to a FM Port module.
86123 +
86124 + @Return E_OK on success; Error code otherwise.
86125 +
86126 + @Cautions Allowed only following FM_PORT_Init().
86127 +*//***************************************************************************/
86128 +t_Error FM_PORT_Enable(t_Handle h_FmPort);
86129 +
86130 +/**************************************************************************//**
86131 + @Function FM_PORT_SetRateLimit
86132 +
86133 + @Description Calling this routine enables rate limit algorithm.
86134 + By default, this functionality is disabled.
86135 + Note that rate-limit mechanism uses the FM time stamp.
86136 + The selected rate limit specified here would be
86137 + rounded DOWN to the nearest 16M.
86138 +
86139 + May be used for Tx and OP ports only
86140 +
86141 + @Param[in] h_FmPort A handle to a FM Port module.
86142 + @Param[in] p_RateLimit A structure of rate limit parameters
86143 +
86144 + @Return E_OK on success; Error code otherwise.
86145 +
86146 + @Cautions Allowed only following FM_PORT_Init().
86147 + If rate limit is set on a port that need to send PFC frames,
86148 + it might violate the stop transmit timing.
86149 +*//***************************************************************************/
86150 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit);
86151 +
86152 +/**************************************************************************//**
86153 + @Function FM_PORT_DeleteRateLimit
86154 +
86155 + @Description Calling this routine disables and clears rate limit
86156 + initialization.
86157 +
86158 + May be used for Tx and OP ports only
86159 +
86160 + @Param[in] h_FmPort A handle to a FM Port module.
86161 +
86162 + @Return E_OK on success; Error code otherwise.
86163 +
86164 + @Cautions Allowed only following FM_PORT_Init().
86165 +*//***************************************************************************/
86166 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort);
86167 +
86168 +/**************************************************************************//**
86169 + @Function FM_PORT_SetPfcPrioritiesMappingToQmanWQ
86170 +
86171 + @Description Calling this routine maps each PFC received priority to the transmit WQ.
86172 + This WQ will be blocked upon receiving a PFC frame with this priority.
86173 +
86174 + May be used for Tx ports only.
86175 +
86176 + @Param[in] h_FmPort A handle to a FM Port module.
86177 + @Param[in] prio PFC priority (0-7).
86178 + @Param[in] wq Work Queue (0-7).
86179 +
86180 + @Return E_OK on success; Error code otherwise.
86181 +
86182 + @Cautions Allowed only following FM_PORT_Init().
86183 +*//***************************************************************************/
86184 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, uint8_t wq);
86185 +
86186 +/**************************************************************************//**
86187 + @Function FM_PORT_SetStatisticsCounters
86188 +
86189 + @Description Calling this routine enables/disables port's statistics counters.
86190 + By default, counters are enabled.
86191 +
86192 + May be used for all port types
86193 +
86194 + @Param[in] h_FmPort A handle to a FM Port module.
86195 + @Param[in] enable TRUE to enable, FALSE to disable.
86196 +
86197 + @Return E_OK on success; Error code otherwise.
86198 +
86199 + @Cautions Allowed only following FM_PORT_Init().
86200 +*//***************************************************************************/
86201 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable);
86202 +
86203 +/**************************************************************************//**
86204 + @Function FM_PORT_SetFrameQueueCounters
86205 +
86206 + @Description Calling this routine enables/disables port's enqueue/dequeue counters.
86207 + By default, counters are enabled.
86208 +
86209 + May be used for all ports
86210 +
86211 + @Param[in] h_FmPort A handle to a FM Port module.
86212 + @Param[in] enable TRUE to enable, FALSE to disable.
86213 +
86214 + @Return E_OK on success; Error code otherwise.
86215 +
86216 + @Cautions Allowed only following FM_PORT_Init().
86217 +*//***************************************************************************/
86218 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable);
86219 +
86220 +/**************************************************************************//**
86221 + @Function FM_PORT_AnalyzePerformanceParams
86222 +
86223 + @Description User may call this routine to so the driver will analyze if the
86224 + basic performance parameters are correct and also the driver may
86225 + suggest of improvements; The basic parameters are FIFO sizes, number
86226 + of DMAs and number of TNUMs for the port.
86227 +
86228 + May be used for all port types
86229 +
86230 + @Param[in] h_FmPort A handle to a FM Port module.
86231 +
86232 + @Return E_OK on success; Error code otherwise.
86233 +
86234 + @Cautions Allowed only following FM_PORT_Init().
86235 +*//***************************************************************************/
86236 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort);
86237 +
86238 +
86239 +/**************************************************************************//**
86240 + @Function FM_PORT_SetAllocBufCounter
86241 +
86242 + @Description Calling this routine enables/disables BM pool allocate
86243 + buffer counters.
86244 + By default, counters are enabled.
86245 +
86246 + May be used for Rx ports only
86247 +
86248 + @Param[in] h_FmPort A handle to a FM Port module.
86249 + @Param[in] poolId BM pool id.
86250 + @Param[in] enable TRUE to enable, FALSE to disable.
86251 +
86252 + @Return E_OK on success; Error code otherwise.
86253 +
86254 + @Cautions Allowed only following FM_PORT_Init().
86255 +*//***************************************************************************/
86256 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable);
86257 +
86258 +/**************************************************************************//**
86259 + @Function FM_PORT_GetBmiCounters
86260 +
86261 + @Description Read port's BMI stat counters and place them into
86262 + a designated structure of counters.
86263 +
86264 + @Param[in] h_FmPort A handle to a FM Port module.
86265 + @Param[out] p_BmiStats counters structure
86266 +
86267 + @Return E_OK on success; Error code otherwise.
86268 +
86269 + @Cautions Allowed only following FM_PORT_Init().
86270 +*//***************************************************************************/
86271 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats);
86272 +
86273 +/**************************************************************************//**
86274 + @Function FM_PORT_GetCounter
86275 +
86276 + @Description Reads one of the FM PORT counters.
86277 +
86278 + @Param[in] h_FmPort A handle to a FM Port module.
86279 + @Param[in] fmPortCounter The requested counter.
86280 +
86281 + @Return Counter's current value.
86282 +
86283 + @Cautions Allowed only following FM_PORT_Init().
86284 + Note that it is user's responsibility to call this routine only
86285 + for enabled counters, and there will be no indication if a
86286 + disabled counter is accessed.
86287 +*//***************************************************************************/
86288 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter);
86289 +
86290 +/**************************************************************************//**
86291 + @Function FM_PORT_ModifyCounter
86292 +
86293 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86294 +
86295 + @Param[in] h_FmPort A handle to a FM Port module.
86296 + @Param[in] fmPortCounter The requested counter.
86297 + @Param[in] value The requested value to be written into the counter.
86298 +
86299 + @Return E_OK on success; Error code otherwise.
86300 +
86301 + @Cautions Allowed only following FM_PORT_Init().
86302 +*//***************************************************************************/
86303 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter, uint32_t value);
86304 +
86305 +/**************************************************************************//**
86306 + @Function FM_PORT_GetAllocBufCounter
86307 +
86308 + @Description Reads one of the FM PORT buffer counters.
86309 +
86310 + @Param[in] h_FmPort A handle to a FM Port module.
86311 + @Param[in] poolId The requested pool.
86312 +
86313 + @Return Counter's current value.
86314 +
86315 + @Cautions Allowed only following FM_PORT_Init().
86316 + Note that it is user's responsibility to call this routine only
86317 + for enabled counters, and there will be no indication if a
86318 + disabled counter is accessed.
86319 +*//***************************************************************************/
86320 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId);
86321 +
86322 +/**************************************************************************//**
86323 + @Function FM_PORT_ModifyAllocBufCounter
86324 +
86325 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86326 +
86327 + @Param[in] h_FmPort A handle to a FM Port module.
86328 + @Param[in] poolId The requested pool.
86329 + @Param[in] value The requested value to be written into the counter.
86330 +
86331 + @Return E_OK on success; Error code otherwise.
86332 +
86333 + @Cautions Allowed only following FM_PORT_Init().
86334 +*//***************************************************************************/
86335 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value);
86336 +
86337 +/**************************************************************************//**
86338 + @Function FM_PORT_AddCongestionGrps
86339 +
86340 + @Description This routine effects the corresponding Tx port.
86341 + It should be called in order to enable pause
86342 + frame transmission in case of congestion in one or more
86343 + of the congestion groups relevant to this port.
86344 + Each call to this routine may add one or more congestion
86345 + groups to be considered relevant to this port.
86346 +
86347 + May be used for Rx, or RX+OP ports only (depending on chip)
86348 +
86349 + @Param[in] h_FmPort A handle to a FM Port module.
86350 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86351 + id's to consider.
86352 +
86353 + @Return E_OK on success; Error code otherwise.
86354 +
86355 + @Cautions Allowed only following FM_PORT_Init().
86356 +*//***************************************************************************/
86357 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86358 +
86359 +/**************************************************************************//**
86360 + @Function FM_PORT_RemoveCongestionGrps
86361 +
86362 + @Description This routine effects the corresponding Tx port. It should be
86363 + called when congestion groups were
86364 + defined for this port and are no longer relevant, or pause
86365 + frames transmitting is not required on their behalf.
86366 + Each call to this routine may remove one or more congestion
86367 + groups to be considered relevant to this port.
86368 +
86369 + May be used for Rx, or RX+OP ports only (depending on chip)
86370 +
86371 + @Param[in] h_FmPort A handle to a FM Port module.
86372 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86373 + id's to consider.
86374 +
86375 + @Return E_OK on success; Error code otherwise.
86376 +
86377 + @Cautions Allowed only following FM_PORT_Init().
86378 +*//***************************************************************************/
86379 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86380 +
86381 +/**************************************************************************//**
86382 + @Function FM_PORT_IsStalled
86383 +
86384 + @Description A routine for checking whether the specified port is stalled.
86385 +
86386 + @Param[in] h_FmPort A handle to a FM Port module.
86387 +
86388 + @Return TRUE if port is stalled, FALSE otherwize
86389 +
86390 + @Cautions Allowed only following FM_PORT_Init().
86391 +*//***************************************************************************/
86392 +bool FM_PORT_IsStalled(t_Handle h_FmPort);
86393 +
86394 +/**************************************************************************//**
86395 + @Function FM_PORT_ReleaseStalled
86396 +
86397 + @Description This routine may be called in case the port was stalled and may
86398 + now be released.
86399 + Note that this routine is available only on older FMan revisions
86400 + (FMan v2, DPAA v1.0 only).
86401 +
86402 + @Param[in] h_FmPort A handle to a FM Port module.
86403 +
86404 + @Return E_OK on success; Error code otherwise.
86405 +
86406 + @Cautions Allowed only following FM_PORT_Init().
86407 +*//***************************************************************************/
86408 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort);
86409 +
86410 +/**************************************************************************//**
86411 + @Function FM_PORT_SetRxL4ChecksumVerify
86412 +
86413 + @Description This routine is relevant for Rx ports (1G and 10G). The routine
86414 + set/clear the L3/L4 checksum verification (on RX side).
86415 + Note that this takes affect only if hw-parser is enabled!
86416 +
86417 + @Param[in] h_FmPort A handle to a FM Port module.
86418 + @Param[in] l4Checksum boolean indicates whether to do L3/L4 checksum
86419 + on frames or not.
86420 +
86421 + @Return E_OK on success; Error code otherwise.
86422 +
86423 + @Cautions Allowed only following FM_PORT_Init().
86424 +*//***************************************************************************/
86425 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum);
86426 +
86427 +/**************************************************************************//**
86428 + @Function FM_PORT_SetErrorsRoute
86429 +
86430 + @Description Errors selected for this routine will cause a frame with that error
86431 + to be enqueued to error queue.
86432 + Errors not selected for this routine will cause a frame with that error
86433 + to be enqueued to the one of the other port queues.
86434 + By default all errors are defined to be enqueued to error queue.
86435 + Errors that were configured to be discarded (at initialization)
86436 + may not be selected here.
86437 +
86438 + May be used for Rx and OP ports only
86439 +
86440 + @Param[in] h_FmPort A handle to a FM Port module.
86441 + @Param[in] errs A list of errors to enqueue to error queue
86442 +
86443 + @Return E_OK on success; Error code otherwise.
86444 +
86445 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86446 +*//***************************************************************************/
86447 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
86448 +
86449 +/**************************************************************************//**
86450 + @Function FM_PORT_SetIMExceptions
86451 +
86452 + @Description Calling this routine enables/disables FM PORT interrupts.
86453 +
86454 + @Param[in] h_FmPort FM PORT module descriptor.
86455 + @Param[in] exception The exception to be selected.
86456 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
86457 +
86458 + @Return E_OK on success; Error code otherwise.
86459 +
86460 + @Cautions Allowed only following FM_PORT_Init().
86461 + This routine should NOT be called from guest-partition
86462 + (i.e. guestId != NCSW_MASTER_ID)
86463 +*//***************************************************************************/
86464 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable);
86465 +
86466 +/**************************************************************************//*
86467 + @Function FM_PORT_SetPerformanceCounters
86468 +
86469 + @Description Calling this routine enables/disables port's performance counters.
86470 + By default, counters are enabled.
86471 +
86472 + May be used for all port types
86473 +
86474 + @Param[in] h_FmPort A handle to a FM Port module.
86475 + @Param[in] enable TRUE to enable, FALSE to disable.
86476 +
86477 + @Return E_OK on success; Error code otherwise.
86478 +
86479 + @Cautions Allowed only following FM_PORT_Init().
86480 +*//***************************************************************************/
86481 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable);
86482 +
86483 +/**************************************************************************//*
86484 + @Function FM_PORT_SetPerformanceCountersParams
86485 +
86486 + @Description Calling this routine defines port's performance
86487 + counters parameters.
86488 +
86489 + May be used for all port types
86490 +
86491 + @Param[in] h_FmPort A handle to a FM Port module.
86492 + @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance
86493 + counters parameters.
86494 +
86495 + @Return E_OK on success; Error code otherwise.
86496 +
86497 + @Cautions Allowed only following FM_PORT_Init().
86498 +*//***************************************************************************/
86499 +t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt);
86500 +
86501 +/**************************************************************************//**
86502 + @Group FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
86503 +
86504 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
86505 +
86506 + @{
86507 +*//***************************************************************************/
86508 +
86509 +/**************************************************************************//**
86510 + @Description A structure defining the KG scheme after the parser.
86511 + This is relevant only to change scheme selection mode - from
86512 + direct to indirect and vice versa, or when the scheme is selected directly,
86513 + to select the scheme id.
86514 +
86515 +*//***************************************************************************/
86516 +typedef struct t_FmPcdKgSchemeSelect {
86517 + bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV. */
86518 + t_Handle h_DirectScheme; /**< Scheme handle, selects the scheme after parser;
86519 + Relevant only when 'direct' is TRUE. */
86520 +} t_FmPcdKgSchemeSelect;
86521 +
86522 +/**************************************************************************//**
86523 + @Description A structure of scheme parameters
86524 +*//***************************************************************************/
86525 +typedef struct t_FmPcdPortSchemesParams {
86526 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86527 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'numOfSchemes' schemes for the
86528 + port to be bound to */
86529 +} t_FmPcdPortSchemesParams;
86530 +
86531 +/**************************************************************************//**
86532 + @Description Union for defining port protocol parameters for parser
86533 +*//***************************************************************************/
86534 +typedef union u_FmPcdHdrPrsOpts {
86535 + /* MPLS */
86536 + struct {
86537 + bool labelInterpretationEnable; /**< When this bit is set, the last MPLS label will be
86538 + interpreted as described in HW spec table. When the bit
86539 + is cleared, the parser will advance to MPLS next parse */
86540 + e_NetHeaderType nextParse; /**< must be equal or higher than IPv4 */
86541 + } mplsPrsOptions;
86542 + /* VLAN */
86543 + struct {
86544 + uint16_t tagProtocolId1; /**< User defined Tag Protocol Identifier, to be recognized
86545 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86546 + uint16_t tagProtocolId2; /**< User defined Tag Protocol Identifier, to be recognized
86547 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86548 + } vlanPrsOptions;
86549 + /* PPP */
86550 + struct{
86551 + bool enableMTUCheck; /**< Check validity of MTU according to RFC2516 */
86552 + } pppoePrsOptions;
86553 +
86554 + /* IPV6 */
86555 + struct{
86556 + bool routingHdrEnable; /**< TRUE to enable routing header, otherwise ignore */
86557 + } ipv6PrsOptions;
86558 +
86559 + /* UDP */
86560 + struct{
86561 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86562 + } udpPrsOptions;
86563 +
86564 + /* TCP */
86565 + struct {
86566 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86567 + } tcpPrsOptions;
86568 +} u_FmPcdHdrPrsOpts;
86569 +
86570 +/**************************************************************************//**
86571 + @Description A structure for defining each header for the parser
86572 +*//***************************************************************************/
86573 +typedef struct t_FmPcdPrsAdditionalHdrParams {
86574 + e_NetHeaderType hdr; /**< Selected header; use HEADER_TYPE_NONE
86575 + to indicate that sw parser is to run first
86576 + (before HW parser, and independent of the
86577 + existence of any protocol), in this case,
86578 + swPrsEnable must be set, and all other
86579 + parameters are irrelevant. */
86580 + bool errDisable; /**< TRUE to disable error indication */
86581 + bool swPrsEnable; /**< Enable jump to SW parser when this
86582 + header is recognized by the HW parser. */
86583 + uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser
86584 + attachments exists for the same header,
86585 + (in the main sw parser code) use this
86586 + index to distinguish between them. */
86587 + bool usePrsOpts; /**< TRUE to use parser options. */
86588 + u_FmPcdHdrPrsOpts prsOpts; /**< A union according to header type,
86589 + defining the parser options selected.*/
86590 +} t_FmPcdPrsAdditionalHdrParams;
86591 +
86592 +/**************************************************************************//**
86593 + @Description struct for defining port PCD parameters
86594 +*//***************************************************************************/
86595 +typedef struct t_FmPortPcdPrsParams {
86596 + uint8_t prsResultPrivateInfo; /**< The private info provides a method of inserting
86597 + port information into the parser result. This information
86598 + may be extracted by Keygen and be used for frames
86599 + distribution when a per-port distinction is required,
86600 + it may also be used as a port logical id for analyzing
86601 + incoming frames. */
86602 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to start parsing */
86603 + e_NetHeaderType firstPrsHdr; /**< The type of the first header expected at 'parsingOffset' */
86604 + bool includeInPrsStatistics; /**< TRUE to include this port in the parser statistics;
86605 + NOTE: this field is not valid when the FM is in "guest" mode
86606 + and IPC is not available. */
86607 + uint8_t numOfHdrsWithAdditionalParams; /**< Normally 0, some headers may get
86608 + special parameters */
86609 + t_FmPcdPrsAdditionalHdrParams additionalParams[FM_PCD_PRS_NUM_OF_HDRS];
86610 + /**< 'numOfHdrsWithAdditionalParams' structures
86611 + of additional parameters
86612 + for each header that requires them */
86613 + bool setVlanTpid1; /**< TRUE to configure user selection of Ethertype to
86614 + indicate a VLAN tag (in addition to the TPID values
86615 + 0x8100 and 0x88A8). */
86616 + uint16_t vlanTpid1; /**< extra tag to use if setVlanTpid1=TRUE. */
86617 + bool setVlanTpid2; /**< TRUE to configure user selection of Ethertype to
86618 + indicate a VLAN tag (in addition to the TPID values
86619 + 0x8100 and 0x88A8). */
86620 + uint16_t vlanTpid2; /**< extra tag to use if setVlanTpid1=TRUE. */
86621 +} t_FmPortPcdPrsParams;
86622 +
86623 +/**************************************************************************//**
86624 + @Description struct for defining coarse alassification parameters
86625 +*//***************************************************************************/
86626 +typedef struct t_FmPortPcdCcParams {
86627 + t_Handle h_CcTree; /**< A handle to a CC tree */
86628 +} t_FmPortPcdCcParams;
86629 +
86630 +/**************************************************************************//**
86631 + @Description struct for defining keygen parameters
86632 +*//***************************************************************************/
86633 +typedef struct t_FmPortPcdKgParams {
86634 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86635 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
86636 + /**< Array of 'numOfSchemes' schemes handles for the
86637 + port to be bound to */
86638 + bool directScheme; /**< TRUE for going from parser to a specific scheme,
86639 + regardless of parser result */
86640 + t_Handle h_DirectScheme; /**< relevant only if direct == TRUE, Scheme handle,
86641 + as returned by FM_PCD_KgSetScheme */
86642 +} t_FmPortPcdKgParams;
86643 +
86644 +/**************************************************************************//**
86645 + @Description struct for defining policer parameters
86646 +*//***************************************************************************/
86647 +typedef struct t_FmPortPcdPlcrParams {
86648 + t_Handle h_Profile; /**< Selected profile handle */
86649 +} t_FmPortPcdPlcrParams;
86650 +
86651 +/**************************************************************************//**
86652 + @Description struct for defining port PCD parameters
86653 +*//***************************************************************************/
86654 +typedef struct t_FmPortPcdParams {
86655 + e_FmPortPcdSupport pcdSupport; /**< Relevant for Rx and offline ports only.
86656 + Describes the active PCD engines for this port. */
86657 + t_Handle h_NetEnv; /**< HL Unused in PLCR only mode */
86658 + t_FmPortPcdPrsParams *p_PrsParams; /**< Parser parameters for this port */
86659 + t_FmPortPcdCcParams *p_CcParams; /**< Coarse classification parameters for this port */
86660 + t_FmPortPcdKgParams *p_KgParams; /**< Keygen parameters for this port */
86661 + t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port; Relevant for one of
86662 + following cases:
86663 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
86664 + e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
86665 + or if any flow uses a KG scheme were policer
86666 + profile is not generated
86667 + ('bypassPlcrProfileGeneration selected'). */
86668 + t_Handle h_IpReassemblyManip; /**< IP Reassembly manipulation */
86669 +#if (DPAA_VERSION >= 11)
86670 + t_Handle h_CapwapReassemblyManip;/**< CAPWAP Reassembly manipulation */
86671 +#endif /* (DPAA_VERSION >= 11) */
86672 +} t_FmPortPcdParams;
86673 +
86674 +/**************************************************************************//**
86675 + @Description A structure for defining the Parser starting point
86676 +*//***************************************************************************/
86677 +typedef struct t_FmPcdPrsStart {
86678 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to
86679 + start parsing */
86680 + e_NetHeaderType firstPrsHdr; /**< The type of the first header axpected at
86681 + 'parsingOffset' */
86682 +} t_FmPcdPrsStart;
86683 +
86684 +#if (DPAA_VERSION >= 11)
86685 +/**************************************************************************//**
86686 + @Description struct for defining external buffer margins
86687 +*//***************************************************************************/
86688 +typedef struct t_FmPortVSPAllocParams {
86689 + uint8_t numOfProfiles; /**< Number of Virtual Storage Profiles; must be a power of 2 */
86690 + uint8_t dfltRelativeId; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
86691 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
86692 + if relevant function called for Rx port */
86693 + t_Handle h_FmTxPort; /**< Handle to coupled Tx Port; not relevant for OP port. */
86694 +} t_FmPortVSPAllocParams;
86695 +#endif /* (DPAA_VERSION >= 11) */
86696 +
86697 +
86698 +/**************************************************************************//**
86699 + @Function FM_PORT_SetPCD
86700 +
86701 + @Description Calling this routine defines the port's PCD configuration.
86702 + It changes it from its default configuration which is PCD
86703 + disabled (BMI to BMI) and configures it according to the passed
86704 + parameters.
86705 +
86706 + May be used for Rx and OP ports only
86707 +
86708 + @Param[in] h_FmPort A handle to a FM Port module.
86709 + @Param[in] p_FmPortPcd A Structure of parameters defining the port's PCD
86710 + configuration.
86711 +
86712 + @Return E_OK on success; Error code otherwise.
86713 +
86714 + @Cautions Allowed only following FM_PORT_Init().
86715 +*//***************************************************************************/
86716 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_FmPortPcd);
86717 +
86718 +/**************************************************************************//**
86719 + @Function FM_PORT_DeletePCD
86720 +
86721 + @Description Calling this routine releases the port's PCD configuration.
86722 + The port returns to its default configuration which is PCD
86723 + disabled (BMI to BMI) and all PCD configuration is removed.
86724 +
86725 + May be used for Rx and OP ports which are
86726 + in PCD mode only
86727 +
86728 + @Param[in] h_FmPort A handle to a FM Port module.
86729 +
86730 + @Return E_OK on success; Error code otherwise.
86731 +
86732 + @Cautions Allowed only following FM_PORT_Init().
86733 +*//***************************************************************************/
86734 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort);
86735 +
86736 +/**************************************************************************//**
86737 + @Function FM_PORT_AttachPCD
86738 +
86739 + @Description This routine may be called after FM_PORT_DetachPCD was called,
86740 + to return to the originally configured PCD support flow.
86741 + The couple of routines are used to allow PCD configuration changes
86742 + that demand that PCD will not be used while changes take place.
86743 +
86744 + May be used for Rx and OP ports which are
86745 + in PCD mode only
86746 +
86747 + @Param[in] h_FmPort A handle to a FM Port module.
86748 +
86749 + @Return E_OK on success; Error code otherwise.
86750 +
86751 + @Cautions Allowed only following FM_PORT_Init().
86752 +*//***************************************************************************/
86753 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort);
86754 +
86755 +/**************************************************************************//**
86756 + @Function FM_PORT_DetachPCD
86757 +
86758 + @Description Calling this routine detaches the port from its PCD functionality.
86759 + The port returns to its default flow which is BMI to BMI.
86760 +
86761 + May be used for Rx and OP ports which are
86762 + in PCD mode only
86763 +
86764 + @Param[in] h_FmPort A handle to a FM Port module.
86765 +
86766 + @Return E_OK on success; Error code otherwise.
86767 +
86768 + @Cautions Allowed only following FM_PORT_AttachPCD().
86769 +*//***************************************************************************/
86770 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort);
86771 +
86772 +/**************************************************************************//**
86773 + @Function FM_PORT_PcdPlcrAllocProfiles
86774 +
86775 + @Description This routine may be called only for ports that use the Policer in
86776 + order to allocate private policer profiles.
86777 +
86778 + @Param[in] h_FmPort A handle to a FM Port module.
86779 + @Param[in] numOfProfiles The number of required policer profiles
86780 +
86781 + @Return E_OK on success; Error code otherwise.
86782 +
86783 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
86784 + and before FM_PORT_SetPCD().
86785 +*//***************************************************************************/
86786 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles);
86787 +
86788 +/**************************************************************************//**
86789 + @Function FM_PORT_PcdPlcrFreeProfiles
86790 +
86791 + @Description This routine should be called for freeing private policer profiles.
86792 +
86793 + @Param[in] h_FmPort A handle to a FM Port module.
86794 +
86795 + @Return E_OK on success; Error code otherwise.
86796 +
86797 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
86798 + and before FM_PORT_SetPCD().
86799 +*//***************************************************************************/
86800 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort);
86801 +
86802 +#if (DPAA_VERSION >= 11)
86803 +/**************************************************************************//**
86804 + @Function FM_PORT_VSPAlloc
86805 +
86806 + @Description This routine allocated VSPs per port and forces the port to work
86807 + in VSP mode. Note that the port is initialized by default with the
86808 + physical-storage-profile only.
86809 +
86810 + @Param[in] h_FmPort A handle to a FM Port module.
86811 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
86812 +
86813 + @Return E_OK on success; Error code otherwise.
86814 +
86815 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
86816 + and also before FM_PORT_Enable(); i.e. the port should be disabled.
86817 +*//***************************************************************************/
86818 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_Params);
86819 +#endif /* (DPAA_VERSION >= 11) */
86820 +
86821 +/**************************************************************************//**
86822 + @Function FM_PORT_PcdKgModifyInitialScheme
86823 +
86824 + @Description This routine may be called only for ports that use the keygen in
86825 + order to change the initial scheme frame should be routed to.
86826 + The change may be of a scheme id (in case of direct mode),
86827 + from direct to indirect, or from indirect to direct - specifying the scheme id.
86828 +
86829 + @Param[in] h_FmPort A handle to a FM Port module.
86830 + @Param[in] p_FmPcdKgScheme A structure of parameters for defining whether
86831 + a scheme is direct/indirect, and if direct - scheme id.
86832 +
86833 + @Return E_OK on success; Error code otherwise.
86834 +
86835 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86836 +*//***************************************************************************/
86837 +t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme);
86838 +
86839 +/**************************************************************************//**
86840 + @Function FM_PORT_PcdPlcrModifyInitialProfile
86841 +
86842 + @Description This routine may be called for ports with flows
86843 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR
86844 + only, to change the initial Policer profile frame should be
86845 + routed to. The change may be of a profile and/or absolute/direct
86846 + mode selection.
86847 +
86848 + @Param[in] h_FmPort A handle to a FM Port module.
86849 + @Param[in] h_Profile Policer profile handle
86850 +
86851 + @Return E_OK on success; Error code otherwise.
86852 +
86853 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86854 +*//***************************************************************************/
86855 +t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile);
86856 +
86857 +/**************************************************************************//**
86858 + @Function FM_PORT_PcdCcModifyTree
86859 +
86860 + @Description This routine may be called for ports that use coarse classification tree
86861 + if the user wishes to replace the tree. The routine may not be called while port
86862 + receives packets using the PCD functionalities, therefor port must be first detached
86863 + from the PCD, only than the routine may be called, and than port be attached to PCD again.
86864 +
86865 + @Param[in] h_FmPort A handle to a FM Port module.
86866 + @Param[in] h_CcTree A CC tree that was already built. The tree id as returned from
86867 + the BuildTree routine.
86868 +
86869 + @Return E_OK on success; Error code otherwise.
86870 +
86871 + @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetachPCD()
86872 +*//***************************************************************************/
86873 +t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree);
86874 +
86875 +/**************************************************************************//**
86876 + @Function FM_PORT_PcdKgBindSchemes
86877 +
86878 + @Description These routines may be called for adding more schemes for the
86879 + port to be bound to. The selected schemes are not added,
86880 + just this specific port starts using them.
86881 +
86882 + @Param[in] h_FmPort A handle to a FM Port module.
86883 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
86884 +
86885 + @Return E_OK on success; Error code otherwise.
86886 +
86887 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86888 +*//***************************************************************************/
86889 +t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
86890 +
86891 +/**************************************************************************//**
86892 + @Function FM_PORT_PcdKgUnbindSchemes
86893 +
86894 + @Description These routines may be called for adding more schemes for the
86895 + port to be bound to. The selected schemes are not removed or invalidated,
86896 + just this specific port stops using them.
86897 +
86898 + @Param[in] h_FmPort A handle to a FM Port module.
86899 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
86900 +
86901 + @Return E_OK on success; Error code otherwise.
86902 +
86903 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86904 +*//***************************************************************************/
86905 +t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
86906 +
86907 +/**************************************************************************//**
86908 + @Function FM_PORT_GetIPv4OptionsCount
86909 +
86910 + @Description TODO
86911 +
86912 + @Param[in] h_FmPort A handle to a FM Port module.
86913 + @Param[out] p_Ipv4OptionsCount will hold the counter value
86914 +
86915 + @Return E_OK on success; Error code otherwise.
86916 +
86917 + @Cautions Allowed only following FM_PORT_Init()
86918 +*//***************************************************************************/
86919 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, uint32_t *p_Ipv4OptionsCount);
86920 +
86921 +/** @} */ /* end of FM_PORT_pcd_runtime_control_grp group */
86922 +/** @} */ /* end of FM_PORT_runtime_control_grp group */
86923 +
86924 +
86925 +/**************************************************************************//**
86926 + @Group FM_PORT_runtime_data_grp FM Port Runtime Data-path Unit
86927 +
86928 + @Description FM Port Runtime data unit API functions, definitions and enums.
86929 + This API is valid only if working in Independent-Mode.
86930 +
86931 + @{
86932 +*//***************************************************************************/
86933 +
86934 +/**************************************************************************//**
86935 + @Function FM_PORT_ImTx
86936 +
86937 + @Description Tx function, called to transmit a data buffer on the port.
86938 +
86939 + @Param[in] h_FmPort A handle to a FM Port module.
86940 + @Param[in] p_Data A pointer to an LCP data buffer.
86941 + @Param[in] length Size of data for transmission.
86942 + @Param[in] lastBuffer Buffer position - TRUE for the last buffer
86943 + of a frame, including a single buffer frame
86944 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
86945 +
86946 + @Return E_OK on success; Error code otherwise.
86947 +
86948 + @Cautions Allowed only following FM_PORT_Init().
86949 + NOTE - This routine can be used only when working in
86950 + Independent-Mode mode.
86951 +*//***************************************************************************/
86952 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
86953 + uint8_t *p_Data,
86954 + uint16_t length,
86955 + bool lastBuffer,
86956 + t_Handle h_BufContext);
86957 +
86958 +/**************************************************************************//**
86959 + @Function FM_PORT_ImTxConf
86960 +
86961 + @Description Tx port confirmation routine, optional, may be called to verify
86962 + transmission of all frames. The procedure performed by this
86963 + routine will be performed automatically on next buffer transmission,
86964 + but if desired, calling this routine will invoke this action on
86965 + demand.
86966 +
86967 + @Param[in] h_FmPort A handle to a FM Port module.
86968 +
86969 + @Cautions Allowed only following FM_PORT_Init().
86970 + NOTE - This routine can be used only when working in
86971 + Independent-Mode mode.
86972 +*//***************************************************************************/
86973 +void FM_PORT_ImTxConf(t_Handle h_FmPort);
86974 +
86975 +/**************************************************************************//**
86976 + @Function FM_PORT_ImRx
86977 +
86978 + @Description Rx function, may be called to poll for received buffers.
86979 + Normally, Rx process is invoked by the driver on Rx interrupt.
86980 + Alternatively, this routine may be called on demand.
86981 +
86982 + @Param[in] h_FmPort A handle to a FM Port module.
86983 +
86984 + @Return E_OK on success; Error code otherwise.
86985 +
86986 + @Cautions Allowed only following FM_PORT_Init().
86987 + NOTE - This routine can be used only when working in
86988 + Independent-Mode mode.
86989 +*//***************************************************************************/
86990 +t_Error FM_PORT_ImRx(t_Handle h_FmPort);
86991 +
86992 +/** @} */ /* end of FM_PORT_runtime_data_grp group */
86993 +/** @} */ /* end of FM_PORT_grp group */
86994 +/** @} */ /* end of FM_grp group */
86995 +
86996 +
86997 +
86998 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
86999 +#define FM_PORT_ConfigTxFifoDeqPipelineDepth FM_PORT_ConfigFifoDeqPipelineDepth
87000 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
87001 +
87002 +
87003 +#endif /* __FM_PORT_EXT */
87004 --- /dev/null
87005 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
87006 @@ -0,0 +1,619 @@
87007 +/*
87008 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87009 + *
87010 + * Redistribution and use in source and binary forms, with or without
87011 + * modification, are permitted provided that the following conditions are met:
87012 + * * Redistributions of source code must retain the above copyright
87013 + * notice, this list of conditions and the following disclaimer.
87014 + * * Redistributions in binary form must reproduce the above copyright
87015 + * notice, this list of conditions and the following disclaimer in the
87016 + * documentation and/or other materials provided with the distribution.
87017 + * * Neither the name of Freescale Semiconductor nor the
87018 + * names of its contributors may be used to endorse or promote products
87019 + * derived from this software without specific prior written permission.
87020 + *
87021 + *
87022 + * ALTERNATIVELY, this software may be distributed under the terms of the
87023 + * GNU General Public License ("GPL") as published by the Free Software
87024 + * Foundation, either version 2 of that License or (at your option) any
87025 + * later version.
87026 + *
87027 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87028 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87029 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87030 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87031 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87032 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87033 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87034 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87035 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87036 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87037 + */
87038 +
87039 +
87040 +/**************************************************************************//**
87041 + @File fm_rtc_ext.h
87042 +
87043 + @Description External definitions and API for FM RTC IEEE1588 Timer Module.
87044 +
87045 + @Cautions None.
87046 +*//***************************************************************************/
87047 +
87048 +#ifndef __FM_RTC_EXT_H__
87049 +#define __FM_RTC_EXT_H__
87050 +
87051 +
87052 +#include "error_ext.h"
87053 +#include "std_ext.h"
87054 +#include "fsl_fman_rtc.h"
87055 +
87056 +/**************************************************************************//**
87057 +
87058 + @Group FM_grp Frame Manager API
87059 +
87060 + @Description FM API functions, definitions and enums
87061 +
87062 + @{
87063 +*//***************************************************************************/
87064 +
87065 +/**************************************************************************//**
87066 + @Group fm_rtc_grp FM RTC
87067 +
87068 + @Description FM RTC functions, definitions and enums.
87069 +
87070 + @{
87071 +*//***************************************************************************/
87072 +
87073 +/**************************************************************************//**
87074 + @Group fm_rtc_init_grp FM RTC Initialization Unit
87075 +
87076 + @Description FM RTC initialization API.
87077 +
87078 + @{
87079 +*//***************************************************************************/
87080 +
87081 +/**************************************************************************//**
87082 + @Description FM RTC Alarm Polarity Options.
87083 +*//***************************************************************************/
87084 +typedef enum e_FmRtcAlarmPolarity
87085 +{
87086 + e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
87087 + e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
87088 +} e_FmRtcAlarmPolarity;
87089 +
87090 +/**************************************************************************//**
87091 + @Description FM RTC Trigger Polarity Options.
87092 +*//***************************************************************************/
87093 +typedef enum e_FmRtcTriggerPolarity
87094 +{
87095 + e_FM_RTC_TRIGGER_ON_RISING_EDGE = E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
87096 + e_FM_RTC_TRIGGER_ON_FALLING_EDGE = E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
87097 +} e_FmRtcTriggerPolarity;
87098 +
87099 +/**************************************************************************//**
87100 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
87101 +*//***************************************************************************/
87102 +typedef enum e_FmSrcClock
87103 +{
87104 + e_FM_RTC_SOURCE_CLOCK_EXTERNAL = E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */
87105 + e_FM_RTC_SOURCE_CLOCK_SYSTEM = E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
87106 + e_FM_RTC_SOURCE_CLOCK_OSCILATOR = E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
87107 +}e_FmSrcClk;
87108 +
87109 +/**************************************************************************//**
87110 + @Description FM RTC configuration parameters structure.
87111 +
87112 + This structure should be passed to FM_RTC_Config().
87113 +*//***************************************************************************/
87114 +typedef struct t_FmRtcParams
87115 +{
87116 + t_Handle h_Fm; /**< FM Handle*/
87117 + uintptr_t baseAddress; /**< Base address of FM RTC registers */
87118 + t_Handle h_App; /**< A handle to an application layer object; This handle will
87119 + be passed by the driver upon calling the above callbacks */
87120 +} t_FmRtcParams;
87121 +
87122 +
87123 +/**************************************************************************//**
87124 + @Function FM_RTC_Config
87125 +
87126 + @Description Configures the FM RTC module according to user's parameters.
87127 +
87128 + The driver assigns default values to some FM RTC parameters.
87129 + These parameters can be overwritten using the advanced
87130 + configuration routines.
87131 +
87132 + @Param[in] p_FmRtcParam - FM RTC configuration parameters.
87133 +
87134 + @Return Handle to the new FM RTC object; NULL pointer on failure.
87135 +
87136 + @Cautions None
87137 +*//***************************************************************************/
87138 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam);
87139 +
87140 +/**************************************************************************//**
87141 + @Function FM_RTC_Init
87142 +
87143 + @Description Initializes the FM RTC driver and hardware.
87144 +
87145 + @Param[in] h_FmRtc - Handle to FM RTC object.
87146 +
87147 + @Return E_OK on success; Error code otherwise.
87148 +
87149 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87150 +*//***************************************************************************/
87151 +t_Error FM_RTC_Init(t_Handle h_FmRtc);
87152 +
87153 +/**************************************************************************//**
87154 + @Function FM_RTC_Free
87155 +
87156 + @Description Frees the FM RTC object and all allocated resources.
87157 +
87158 + @Param[in] h_FmRtc - Handle to FM RTC object.
87159 +
87160 + @Return E_OK on success; Error code otherwise.
87161 +
87162 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87163 +*//***************************************************************************/
87164 +t_Error FM_RTC_Free(t_Handle h_FmRtc);
87165 +
87166 +
87167 +/**************************************************************************//**
87168 + @Group fm_rtc_adv_config_grp FM RTC Advanced Configuration Unit
87169 +
87170 + @Description FM RTC advanced configuration functions.
87171 +
87172 + @{
87173 +*//***************************************************************************/
87174 +
87175 +/**************************************************************************//**
87176 + @Function FM_RTC_ConfigPeriod
87177 +
87178 + @Description Configures the period of the timestamp if different than
87179 + default [DEFAULT_clockPeriod].
87180 +
87181 + @Param[in] h_FmRtc - Handle to FM RTC object.
87182 + @Param[in] period - Period in nano-seconds.
87183 +
87184 + @Return E_OK on success; Error code otherwise.
87185 +
87186 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87187 +*//***************************************************************************/
87188 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period);
87189 +
87190 +/**************************************************************************//**
87191 + @Function FM_RTC_ConfigSourceClock
87192 +
87193 + @Description Configures the source clock of the RTC.
87194 +
87195 + @Param[in] h_FmRtc - Handle to FM RTC object.
87196 + @Param[in] srcClk - Source clock selection.
87197 + @Param[in] freqInMhz - the source-clock frequency (in MHz).
87198 +
87199 + @Return E_OK on success; Error code otherwise.
87200 +
87201 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87202 +*//***************************************************************************/
87203 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
87204 + e_FmSrcClk srcClk,
87205 + uint32_t freqInMhz);
87206 +
87207 +/**************************************************************************//**
87208 + @Function FM_RTC_ConfigPulseRealignment
87209 +
87210 + @Description Configures the RTC to automatic FIPER pulse realignment in
87211 + response to timer adjustments [DEFAULT_pulseRealign]
87212 +
87213 + In this mode, the RTC clock is identical to the source clock.
87214 + This feature can be useful when the system contains an external
87215 + RTC with inherent frequency compensation.
87216 +
87217 + @Param[in] h_FmRtc - Handle to FM RTC object.
87218 + @Param[in] enable - TRUE to enable automatic realignment.
87219 +
87220 + @Return E_OK on success; Error code otherwise.
87221 +
87222 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87223 +*//***************************************************************************/
87224 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable);
87225 +
87226 +/**************************************************************************//**
87227 + @Function FM_RTC_ConfigFrequencyBypass
87228 +
87229 + @Description Configures the RTC to bypass the frequency compensation
87230 + mechanism. [DEFAULT_bypass]
87231 +
87232 + In this mode, the RTC clock is identical to the source clock.
87233 + This feature can be useful when the system contains an external
87234 + RTC with inherent frequency compensation.
87235 +
87236 + @Param[in] h_FmRtc - Handle to FM RTC object.
87237 + @Param[in] enabled - TRUE to bypass frequency compensation;
87238 + FALSE otherwise.
87239 +
87240 + @Return E_OK on success; Error code otherwise.
87241 +
87242 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87243 +*//***************************************************************************/
87244 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled);
87245 +
87246 +/**************************************************************************//**
87247 + @Function FM_RTC_ConfigInvertedInputClockPhase
87248 +
87249 + @Description Configures the RTC to invert the source clock phase on input.
87250 + [DEFAULT_invertInputClkPhase]
87251 +
87252 + @Param[in] h_FmRtc - Handle to FM RTC object.
87253 + @Param[in] inverted - TRUE to invert the source clock phase on input.
87254 + FALSE otherwise.
87255 +
87256 + @Return E_OK on success; Error code otherwise.
87257 +
87258 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87259 +*//***************************************************************************/
87260 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted);
87261 +
87262 +/**************************************************************************//**
87263 + @Function FM_RTC_ConfigInvertedOutputClockPhase
87264 +
87265 + @Description Configures the RTC to invert the output clock phase.
87266 + [DEFAULT_invertOutputClkPhase]
87267 +
87268 + @Param[in] h_FmRtc - Handle to FM RTC object.
87269 + @Param[in] inverted - TRUE to invert the output clock phase.
87270 + FALSE otherwise.
87271 +
87272 + @Return E_OK on success; Error code otherwise.
87273 +
87274 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87275 +*//***************************************************************************/
87276 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted);
87277 +
87278 +/**************************************************************************//**
87279 + @Function FM_RTC_ConfigOutputClockDivisor
87280 +
87281 + @Description Configures the divisor for generating the output clock from
87282 + the RTC clock. [DEFAULT_outputClockDivisor]
87283 +
87284 + @Param[in] h_FmRtc - Handle to FM RTC object.
87285 + @Param[in] divisor - Divisor for generation of the output clock.
87286 +
87287 + @Return E_OK on success; Error code otherwise.
87288 +
87289 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87290 +*//***************************************************************************/
87291 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor);
87292 +
87293 +/**************************************************************************//**
87294 + @Function FM_RTC_ConfigAlarmPolarity
87295 +
87296 + @Description Configures the polarity (active-high/active-low) of a specific
87297 + alarm signal. [DEFAULT_alarmPolarity]
87298 +
87299 + @Param[in] h_FmRtc - Handle to FM RTC object.
87300 + @Param[in] alarmId - Alarm ID.
87301 + @Param[in] alarmPolarity - Alarm polarity.
87302 +
87303 + @Return E_OK on success; Error code otherwise.
87304 +
87305 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87306 +*//***************************************************************************/
87307 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
87308 + uint8_t alarmId,
87309 + e_FmRtcAlarmPolarity alarmPolarity);
87310 +
87311 +/**************************************************************************//**
87312 + @Function FM_RTC_ConfigExternalTriggerPolarity
87313 +
87314 + @Description Configures the polarity (rising/falling edge) of a specific
87315 + external trigger signal. [DEFAULT_triggerPolarity]
87316 +
87317 + @Param[in] h_FmRtc - Handle to FM RTC object.
87318 + @Param[in] triggerId - Trigger ID.
87319 + @Param[in] triggerPolarity - Trigger polarity.
87320 +
87321 + @Return E_OK on success; Error code otherwise.
87322 +
87323 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87324 +*//***************************************************************************/
87325 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
87326 + uint8_t triggerId,
87327 + e_FmRtcTriggerPolarity triggerPolarity);
87328 +
87329 +/** @} */ /* end of fm_rtc_adv_config_grp */
87330 +/** @} */ /* end of fm_rtc_init_grp */
87331 +
87332 +
87333 +/**************************************************************************//**
87334 + @Group fm_rtc_control_grp FM RTC Control Unit
87335 +
87336 + @Description FM RTC runtime control API.
87337 +
87338 + @{
87339 +*//***************************************************************************/
87340 +
87341 +/**************************************************************************//**
87342 + @Function t_FmRtcExceptionsCallback
87343 +
87344 + @Description Exceptions user callback routine, used for RTC different mechanisms.
87345 +
87346 + @Param[in] h_App - User's application descriptor.
87347 + @Param[in] id - source id.
87348 +*//***************************************************************************/
87349 +typedef void (t_FmRtcExceptionsCallback) ( t_Handle h_App, uint8_t id);
87350 +
87351 +/**************************************************************************//**
87352 + @Description FM RTC alarm parameters.
87353 +*//***************************************************************************/
87354 +typedef struct t_FmRtcAlarmParams {
87355 + uint8_t alarmId; /**< 0 or 1 */
87356 + uint64_t alarmTime; /**< In nanoseconds, the time when the alarm
87357 + should go off - must be a multiple of
87358 + the RTC period */
87359 + t_FmRtcExceptionsCallback *f_AlarmCallback; /**< This routine will be called when RTC
87360 + reaches alarmTime */
87361 + bool clearOnExpiration; /**< TRUE to turn off the alarm once expired. */
87362 +} t_FmRtcAlarmParams;
87363 +
87364 +/**************************************************************************//**
87365 + @Description FM RTC Periodic Pulse parameters.
87366 +*//***************************************************************************/
87367 +typedef struct t_FmRtcPeriodicPulseParams {
87368 + uint8_t periodicPulseId; /**< 0 or 1 */
87369 + uint64_t periodicPulsePeriod; /**< In Nanoseconds. Must be
87370 + a multiple of the RTC period */
87371 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback; /**< This routine will be called every
87372 + periodicPulsePeriod. */
87373 +} t_FmRtcPeriodicPulseParams;
87374 +
87375 +/**************************************************************************//**
87376 + @Description FM RTC Periodic Pulse parameters.
87377 +*//***************************************************************************/
87378 +typedef struct t_FmRtcExternalTriggerParams {
87379 + uint8_t externalTriggerId; /**< 0 or 1 */
87380 + bool usePulseAsInput; /**< Use the pulse interrupt instead of
87381 + an external signal */
87382 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback; /**< This routine will be called every
87383 + periodicPulsePeriod. */
87384 +} t_FmRtcExternalTriggerParams;
87385 +
87386 +
87387 +/**************************************************************************//**
87388 + @Function FM_RTC_Enable
87389 +
87390 + @Description Enable the RTC (time count is started).
87391 +
87392 + The user can select to resume the time count from previous
87393 + point, or to restart the time count.
87394 +
87395 + @Param[in] h_FmRtc - Handle to FM RTC object.
87396 + @Param[in] resetClock - Restart the time count from zero.
87397 +
87398 + @Return E_OK on success; Error code otherwise.
87399 +
87400 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87401 +*//***************************************************************************/
87402 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock);
87403 +
87404 +/**************************************************************************//**
87405 + @Function FM_RTC_Disable
87406 +
87407 + @Description Disables the RTC (time count is stopped).
87408 +
87409 + @Param[in] h_FmRtc - Handle to FM RTC object.
87410 +
87411 + @Return E_OK on success; Error code otherwise.
87412 +
87413 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87414 +*//***************************************************************************/
87415 +t_Error FM_RTC_Disable(t_Handle h_FmRtc);
87416 +
87417 +/**************************************************************************//**
87418 + @Function FM_RTC_SetClockOffset
87419 +
87420 + @Description Sets the clock offset (usually relative to another clock).
87421 +
87422 + The user can pass a negative offset value.
87423 +
87424 + @Param[in] h_FmRtc - Handle to FM RTC object.
87425 + @Param[in] offset - New clock offset (in nanoseconds).
87426 +
87427 + @Return E_OK on success; Error code otherwise.
87428 +
87429 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87430 +*//***************************************************************************/
87431 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset);
87432 +
87433 +/**************************************************************************//**
87434 + @Function FM_RTC_SetAlarm
87435 +
87436 + @Description Schedules an alarm event to a given RTC time.
87437 +
87438 + @Param[in] h_FmRtc - Handle to FM RTC object.
87439 + @Param[in] p_FmRtcAlarmParams - Alarm parameters.
87440 +
87441 + @Return E_OK on success; Error code otherwise.
87442 +
87443 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87444 + Must be called only prior to FM_RTC_Enable().
87445 +*//***************************************************************************/
87446 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams);
87447 +
87448 +/**************************************************************************//**
87449 + @Function FM_RTC_SetPeriodicPulse
87450 +
87451 + @Description Sets a periodic pulse.
87452 +
87453 + @Param[in] h_FmRtc - Handle to FM RTC object.
87454 + @Param[in] p_FmRtcPeriodicPulseParams - Periodic pulse parameters.
87455 +
87456 + @Return E_OK on success; Error code otherwise.
87457 +
87458 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87459 + Must be called only prior to FM_RTC_Enable().
87460 +*//***************************************************************************/
87461 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams);
87462 +
87463 +/**************************************************************************//**
87464 + @Function FM_RTC_ClearPeriodicPulse
87465 +
87466 + @Description Clears a periodic pulse.
87467 +
87468 + @Param[in] h_FmRtc - Handle to FM RTC object.
87469 + @Param[in] periodicPulseId - Periodic pulse id.
87470 +
87471 + @Return E_OK on success; Error code otherwise.
87472 +
87473 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87474 +*//***************************************************************************/
87475 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId);
87476 +
87477 +/**************************************************************************//**
87478 + @Function FM_RTC_SetExternalTrigger
87479 +
87480 + @Description Sets an external trigger indication and define a callback
87481 + routine to be called on such event.
87482 +
87483 + @Param[in] h_FmRtc - Handle to FM RTC object.
87484 + @Param[in] p_FmRtcExternalTriggerParams - External Trigger parameters.
87485 +
87486 + @Return E_OK on success; Error code otherwise.
87487 +
87488 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87489 +*//***************************************************************************/
87490 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams);
87491 +
87492 +/**************************************************************************//**
87493 + @Function FM_RTC_ClearExternalTrigger
87494 +
87495 + @Description Clears external trigger indication.
87496 +
87497 + @Param[in] h_FmRtc - Handle to FM RTC object.
87498 + @Param[in] id - External Trigger id.
87499 +
87500 + @Return E_OK on success; Error code otherwise.
87501 +
87502 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87503 +*//***************************************************************************/
87504 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t id);
87505 +
87506 +/**************************************************************************//**
87507 + @Function FM_RTC_GetExternalTriggerTimeStamp
87508 +
87509 + @Description Reads the External Trigger TimeStamp.
87510 +
87511 + @Param[in] h_FmRtc - Handle to FM RTC object.
87512 + @Param[in] triggerId - External Trigger id.
87513 + @Param[out] p_TimeStamp - External Trigger timestamp (in nanoseconds).
87514 +
87515 + @Return E_OK on success; Error code otherwise.
87516 +
87517 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87518 +*//***************************************************************************/
87519 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
87520 + uint8_t triggerId,
87521 + uint64_t *p_TimeStamp);
87522 +
87523 +/**************************************************************************//**
87524 + @Function FM_RTC_GetCurrentTime
87525 +
87526 + @Description Returns the current RTC time.
87527 +
87528 + @Param[in] h_FmRtc - Handle to FM RTC object.
87529 + @Param[out] p_Ts - returned time stamp (in nanoseconds).
87530 +
87531 + @Return E_OK on success; Error code otherwise.
87532 +
87533 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87534 +*//***************************************************************************/
87535 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts);
87536 +
87537 +/**************************************************************************//**
87538 + @Function FM_RTC_SetCurrentTime
87539 +
87540 + @Description Sets the current RTC time.
87541 +
87542 + @Param[in] h_FmRtc - Handle to FM RTC object.
87543 + @Param[in] ts - The new time stamp (in nanoseconds).
87544 +
87545 + @Return E_OK on success; Error code otherwise.
87546 +
87547 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87548 +*//***************************************************************************/
87549 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts);
87550 +
87551 +/**************************************************************************//**
87552 + @Function FM_RTC_GetFreqCompensation
87553 +
87554 + @Description Retrieves the frequency compensation value
87555 +
87556 + @Param[in] h_FmRtc - Handle to FM RTC object.
87557 + @Param[out] p_Compensation - A pointer to the returned value of compensation.
87558 +
87559 + @Return E_OK on success; Error code otherwise.
87560 +
87561 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87562 +*//***************************************************************************/
87563 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation);
87564 +
87565 +/**************************************************************************//**
87566 + @Function FM_RTC_SetFreqCompensation
87567 +
87568 + @Description Sets a new frequency compensation value.
87569 +
87570 + @Param[in] h_FmRtc - Handle to FM RTC object.
87571 + @Param[in] freqCompensation - The new frequency compensation value to set.
87572 +
87573 + @Return E_OK on success; Error code otherwise.
87574 +
87575 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87576 +*//***************************************************************************/
87577 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation);
87578 +
87579 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
87580 +/**************************************************************************//**
87581 +*@Function FM_RTC_EnableInterrupt
87582 +*
87583 +*@Description Enable interrupt of FM RTC.
87584 +*
87585 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87586 +*@Param[in] events - Interrupt events.
87587 +*
87588 +*@Return E_OK on success; Error code otherwise.
87589 +*//***************************************************************************/
87590 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events);
87591 +
87592 +/**************************************************************************//**
87593 +*@Function FM_RTC_DisableInterrupt
87594 +*
87595 +*@Description Disable interrupt of FM RTC.
87596 +*
87597 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87598 +*@Param[in] events - Interrupt events.
87599 +*
87600 +*@Return E_OK on success; Error code otherwise.
87601 +*//***************************************************************************/
87602 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events);
87603 +#endif
87604 +
87605 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
87606 +/**************************************************************************//**
87607 + @Function FM_RTC_DumpRegs
87608 +
87609 + @Description Dumps all FM registers
87610 +
87611 + @Param[in] h_FmRtc A handle to an FM RTC Module.
87612 +
87613 + @Return E_OK on success;
87614 +
87615 + @Cautions Allowed only FM_Init().
87616 +*//***************************************************************************/
87617 +t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc);
87618 +#endif /* (defined(DEBUG_ERRORS) && ... */
87619 +
87620 +/** @} */ /* end of fm_rtc_control_grp */
87621 +/** @} */ /* end of fm_rtc_grp */
87622 +/** @} */ /* end of FM_grp group */
87623 +
87624 +
87625 +#endif /* __FM_RTC_EXT_H__ */
87626 --- /dev/null
87627 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
87628 @@ -0,0 +1,411 @@
87629 +/*
87630 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87631 + *
87632 + * Redistribution and use in source and binary forms, with or without
87633 + * modification, are permitted provided that the following conditions are met:
87634 + * * Redistributions of source code must retain the above copyright
87635 + * notice, this list of conditions and the following disclaimer.
87636 + * * Redistributions in binary form must reproduce the above copyright
87637 + * notice, this list of conditions and the following disclaimer in the
87638 + * documentation and/or other materials provided with the distribution.
87639 + * * Neither the name of Freescale Semiconductor nor the
87640 + * names of its contributors may be used to endorse or promote products
87641 + * derived from this software without specific prior written permission.
87642 + *
87643 + *
87644 + * ALTERNATIVELY, this software may be distributed under the terms of the
87645 + * GNU General Public License ("GPL") as published by the Free Software
87646 + * Foundation, either version 2 of that License or (at your option) any
87647 + * later version.
87648 + *
87649 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87650 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87651 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87652 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87653 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87654 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87655 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87656 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87657 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87658 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87659 + */
87660 +
87661 +
87662 +/**************************************************************************//**
87663 + @File fm_vsp_ext.h
87664 +
87665 + @Description FM Virtual Storage-Profile ...
87666 +*//***************************************************************************/
87667 +#ifndef __FM_VSP_EXT_H
87668 +#define __FM_VSP_EXT_H
87669 +
87670 +#include "std_ext.h"
87671 +#include "error_ext.h"
87672 +#include "string_ext.h"
87673 +#include "debug_ext.h"
87674 +
87675 +#include "fm_ext.h"
87676 +
87677 +
87678 +/**************************************************************************//**
87679 +
87680 + @Group FM_grp Frame Manager API
87681 +
87682 + @Description FM API functions, definitions and enums
87683 +
87684 + @{
87685 +*//***************************************************************************/
87686 +
87687 +/**************************************************************************//**
87688 + @Group FM_VSP_grp FM Virtual-Storage-Profile
87689 +
87690 + @Description FM Virtual-Storage-Profile API
87691 +
87692 + @{
87693 +*//***************************************************************************/
87694 +
87695 +/**************************************************************************//**
87696 + @Group FM_VSP_init_grp FM VSP Initialization Unit
87697 +
87698 + @Description FM VSP initialization API.
87699 +
87700 + @{
87701 +*//***************************************************************************/
87702 +
87703 +/**************************************************************************//**
87704 + @Description Virtual Storage Profile
87705 +*//***************************************************************************/
87706 +typedef struct t_FmVspParams {
87707 + t_Handle h_Fm; /**< A handle to the FM object this VSP related to */
87708 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
87709 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
87710 + parameter associated with Rx / OP port */
87711 + uint16_t liodnOffset; /**< VSP's LIODN offset */
87712 + struct {
87713 + e_FmPortType portType; /**< Port type */
87714 + uint8_t portId; /**< Port Id - relative to type */
87715 + } portParams;
87716 + uint8_t relativeProfileId; /**< VSP Id - relative to VSP's range
87717 + defined in relevant FM object */
87718 +} t_FmVspParams;
87719 +
87720 +
87721 +/**************************************************************************//**
87722 + @Function FM_VSP_Config
87723 +
87724 + @Description Creates descriptor for the FM VSP module.
87725 +
87726 + The routine returns a handle (descriptor) to the FM VSP object.
87727 + This descriptor must be passed as first parameter to all other
87728 + FM VSP function calls.
87729 +
87730 + No actual initialization or configuration of FM hardware is
87731 + done by this routine.
87732 +
87733 +@Param[in] p_FmVspParams Pointer to data structure of parameters
87734 +
87735 + @Retval Handle to FM VSP object, or NULL for Failure.
87736 +*//***************************************************************************/
87737 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams);
87738 +
87739 +/**************************************************************************//**
87740 + @Function FM_VSP_Init
87741 +
87742 + @Description Initializes the FM VSP module
87743 +
87744 + @Param[in] h_FmVsp - FM VSP module descriptor
87745 +
87746 + @Return E_OK on success; Error code otherwise.
87747 +*//***************************************************************************/
87748 +t_Error FM_VSP_Init(t_Handle h_FmVsp);
87749 +
87750 +/**************************************************************************//**
87751 + @Function FM_VSP_Free
87752 +
87753 + @Description Frees all resources that were assigned to FM VSP module.
87754 +
87755 + Calling this routine invalidates the descriptor.
87756 +
87757 + @Param[in] h_FmVsp - FM VSP module descriptor
87758 +
87759 + @Return E_OK on success; Error code otherwise.
87760 +*//***************************************************************************/
87761 +t_Error FM_VSP_Free(t_Handle h_FmVsp);
87762 +
87763 +
87764 +/**************************************************************************//**
87765 + @Group FM_VSP_adv_config_grp FM VSP Advanced Configuration Unit
87766 +
87767 + @Description FM VSP advanced configuration functions.
87768 +
87769 + @{
87770 +*//***************************************************************************/
87771 +
87772 +/**************************************************************************//**
87773 + @Function FM_VSP_ConfigBufferPrefixContent
87774 +
87775 + @Description Defines the structure, size and content of the application buffer.
87776 +
87777 + The prefix will
87778 + In VSPs defined for Tx ports, if 'passPrsResult', the application
87779 + should set a value to their offsets in the prefix of
87780 + the FM will save the first 'privDataSize', than,
87781 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
87782 + and timeStamp, and the packet itself (in this order), to the
87783 + application buffer, and to offset.
87784 +
87785 + Calling this routine changes the buffer margins definitions
87786 + in the internal driver data base from its default
87787 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
87788 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
87789 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
87790 +
87791 + @Param[in] h_FmVsp A handle to a FM VSP module.
87792 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
87793 + structure of the buffer.
87794 + Out parameter: Start margin - offset
87795 + of data from start of external buffer.
87796 +
87797 + @Return E_OK on success; Error code otherwise.
87798 +
87799 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87800 +*//***************************************************************************/
87801 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp,
87802 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
87803 +
87804 +/**************************************************************************//**
87805 + @Function FM_VSP_ConfigDmaSwapData
87806 +
87807 + @Description Calling this routine changes the DMA swap data parameter
87808 + in the internal driver data base from its default
87809 + configuration [DEFAULT_FM_SP_dmaSwapData]
87810 +
87811 + @Param[in] h_FmVsp A handle to a FM VSP module.
87812 + @Param[in] swapData New selection
87813 +
87814 + @Return E_OK on success; Error code otherwise.
87815 +
87816 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87817 +*//***************************************************************************/
87818 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData);
87819 +
87820 +/**************************************************************************//**
87821 + @Function FM_VSP_ConfigDmaIcCacheAttr
87822 +
87823 + @Description Calling this routine changes the internal context cache
87824 + attribute parameter in the internal driver data base
87825 + from its default configuration [DEFAULT_FM_SP_dmaIntContextCacheAttr]
87826 +
87827 + @Param[in] h_FmVsp A handle to a FM VSP module.
87828 + @Param[in] intContextCacheAttr New selection
87829 +
87830 + @Return E_OK on success; Error code otherwise.
87831 +
87832 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87833 +*//***************************************************************************/
87834 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp,
87835 + e_FmDmaCacheOption intContextCacheAttr);
87836 +
87837 +/**************************************************************************//**
87838 + @Function FM_VSP_ConfigDmaHdrAttr
87839 +
87840 + @Description Calling this routine changes the header cache
87841 + attribute parameter in the internal driver data base
87842 + from its default configuration [DEFAULT_FM_SP_dmaHeaderCacheAttr]
87843 +
87844 + @Param[in] h_FmVsp A handle to a FM VSP module.
87845 + @Param[in] headerCacheAttr New selection
87846 +
87847 + @Return E_OK on success; Error code otherwise.
87848 +
87849 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87850 +*//***************************************************************************/
87851 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr);
87852 +
87853 +/**************************************************************************//**
87854 + @Function FM_VSP_ConfigDmaScatterGatherAttr
87855 +
87856 + @Description Calling this routine changes the scatter gather cache
87857 + attribute parameter in the internal driver data base
87858 + from its default configuration [DEFAULT_FM_SP_dmaScatterGatherCacheAttr]
87859 +
87860 + @Param[in] h_FmVsp A handle to a FM VSP module.
87861 + @Param[in] scatterGatherCacheAttr New selection
87862 +
87863 + @Return E_OK on success; Error code otherwise.
87864 +
87865 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87866 +*//***************************************************************************/
87867 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp,
87868 + e_FmDmaCacheOption scatterGatherCacheAttr);
87869 +
87870 +/**************************************************************************//**
87871 + @Function FM_VSP_ConfigDmaWriteOptimize
87872 +
87873 + @Description Calling this routine changes the write optimization
87874 + parameter in the internal driver data base
87875 + from its default configuration: optimize = [DEFAULT_FM_SP_dmaWriteOptimize]
87876 +
87877 + @Param[in] h_FmVsp A handle to a FM VSP module.
87878 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
87879 +
87880 + @Return E_OK on success; Error code otherwise.
87881 +
87882 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87883 +*//***************************************************************************/
87884 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize);
87885 +
87886 +/**************************************************************************//**
87887 + @Function FM_VSP_ConfigNoScatherGather
87888 +
87889 + @Description Calling this routine changes the possibility to receive S/G frame
87890 + in the internal driver data base
87891 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
87892 +
87893 + @Param[in] h_FmVsp A handle to a FM VSP module.
87894 + @Param[in] noScatherGather TRUE to operate without scatter/gather capability.
87895 +
87896 + @Return E_OK on success; Error code otherwise.
87897 +
87898 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87899 +*//***************************************************************************/
87900 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather);
87901 +
87902 +/**************************************************************************//**
87903 + @Function FM_VSP_ConfigPoolDepletion
87904 +
87905 + @Description Calling this routine enables pause frame generation depending on the
87906 + depletion status of BM pools. It also defines the conditions to activate
87907 + this functionality. By default, this functionality is disabled.
87908 +
87909 + @Param[in] h_FmVsp A handle to a FM VSP module.
87910 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
87911 +
87912 + @Return E_OK on success; Error code otherwise.
87913 +
87914 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87915 +*//***************************************************************************/
87916 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion);
87917 +
87918 +/**************************************************************************//**
87919 + @Function FM_VSP_ConfigBackupPools
87920 +
87921 + @Description Calling this routine allows the configuration of some of the BM pools
87922 + defined for this port as backup pools.
87923 + A pool configured to be a backup pool will be used only if all other
87924 + enabled non-backup pools are depleted.
87925 +
87926 + @Param[in] h_FmVsp A handle to a FM VSP module.
87927 + @Param[in] p_BackupBmPools An array of pool id's. All pools specified here will
87928 + be defined as backup pools.
87929 +
87930 + @Return E_OK on success; Error code otherwise.
87931 +
87932 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87933 +*//***************************************************************************/
87934 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools);
87935 +
87936 +/** @} */ /* end of FM_VSP_adv_config_grp group */
87937 +/** @} */ /* end of FM_VSP_init_grp group */
87938 +
87939 +
87940 +/**************************************************************************//**
87941 + @Group FM_VSP_control_grp FM VSP Control Unit
87942 +
87943 + @Description FM VSP runtime control API.
87944 +
87945 + @{
87946 +*//***************************************************************************/
87947 +
87948 +/**************************************************************************//**
87949 + @Function FM_VSP_GetBufferDataOffset
87950 +
87951 + @Description Relevant for Rx ports.
87952 + Returns the data offset from the beginning of the data buffer
87953 +
87954 + @Param[in] h_FmVsp - FM PORT module descriptor
87955 +
87956 + @Return data offset.
87957 +
87958 + @Cautions Allowed only following FM_VSP_Init().
87959 +*//***************************************************************************/
87960 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp);
87961 +
87962 +/**************************************************************************//**
87963 + @Function FM_VSP_GetBufferICInfo
87964 +
87965 + @Description Returns the Internal Context offset from the beginning of the data buffer
87966 +
87967 + @Param[in] h_FmVsp - FM PORT module descriptor
87968 + @Param[in] p_Data - A pointer to the data buffer.
87969 +
87970 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
87971 + configured for this port.
87972 +
87973 + @Cautions Allowed only following FM_VSP_Init().
87974 +*//***************************************************************************/
87975 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data);
87976 +
87977 +/**************************************************************************//**
87978 + @Function FM_VSP_GetBufferPrsResult
87979 +
87980 + @Description Returns the pointer to the parse result in the data buffer.
87981 + In Rx ports this is relevant after reception, if parse
87982 + result is configured to be part of the data passed to the
87983 + application. For non Rx ports it may be used to get the pointer
87984 + of the area in the buffer where parse result should be
87985 + initialized - if so configured.
87986 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
87987 + configuration.
87988 +
87989 + @Param[in] h_FmVsp - FM PORT module descriptor
87990 + @Param[in] p_Data - A pointer to the data buffer.
87991 +
87992 + @Return Parse result pointer on success, NULL if parse result was not
87993 + configured for this port.
87994 +
87995 + @Cautions Allowed only following FM_VSP_Init().
87996 +*//***************************************************************************/
87997 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data);
87998 +
87999 +/**************************************************************************//**
88000 + @Function FM_VSP_GetBufferTimeStamp
88001 +
88002 + @Description Returns the time stamp in the data buffer.
88003 + Relevant for Rx ports for getting the buffer time stamp.
88004 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
88005 + configuration.
88006 +
88007 + @Param[in] h_FmVsp - FM PORT module descriptor
88008 + @Param[in] p_Data - A pointer to the data buffer.
88009 +
88010 + @Return A pointer to the hash result on success, NULL otherwise.
88011 +
88012 + @Cautions Allowed only following FM_VSP_Init().
88013 +*//***************************************************************************/
88014 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data);
88015 +
88016 +/**************************************************************************//**
88017 + @Function FM_VSP_GetBufferHashResult
88018 +
88019 + @Description Given a data buffer, on the condition that hash result was defined
88020 + as a part of the buffer content (see FM_VSP_ConfigBufferPrefixContent)
88021 + this routine will return the pointer to the hash result location in the
88022 + buffer prefix.
88023 +
88024 + @Param[in] h_FmVsp - FM PORT module descriptor
88025 + @Param[in] p_Data - A pointer to the data buffer.
88026 +
88027 + @Return A pointer to the hash result on success, NULL otherwise.
88028 +
88029 + @Cautions Allowed only following FM_VSP_Init().
88030 +*//***************************************************************************/
88031 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data);
88032 +
88033 +
88034 +/** @} */ /* end of FM_VSP_control_grp group */
88035 +/** @} */ /* end of FM_VSP_grp group */
88036 +/** @} */ /* end of FM_grp group */
88037 +
88038 +
88039 +#endif /* __FM_VSP_EXT_H */
88040 --- /dev/null
88041 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
88042 @@ -0,0 +1,76 @@
88043 +/*
88044 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88045 + *
88046 + * Redistribution and use in source and binary forms, with or without
88047 + * modification, are permitted provided that the following conditions are met:
88048 + * * Redistributions of source code must retain the above copyright
88049 + * notice, this list of conditions and the following disclaimer.
88050 + * * Redistributions in binary form must reproduce the above copyright
88051 + * notice, this list of conditions and the following disclaimer in the
88052 + * documentation and/or other materials provided with the distribution.
88053 + * * Neither the name of Freescale Semiconductor nor the
88054 + * names of its contributors may be used to endorse or promote products
88055 + * derived from this software without specific prior written permission.
88056 + *
88057 + *
88058 + * ALTERNATIVELY, this software may be distributed under the terms of the
88059 + * GNU General Public License ("GPL") as published by the Free Software
88060 + * Foundation, either version 2 of that License or (at your option) any
88061 + * later version.
88062 + *
88063 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88064 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88065 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88066 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88067 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88068 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88069 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88070 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88071 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88072 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88073 + */
88074 +
88075 +
88076 +
88077 +#ifndef __MII_ACC_EXT_H
88078 +#define __MII_ACC_EXT_H
88079 +
88080 +
88081 +/**************************************************************************//**
88082 + @Function MII_ReadPhyReg
88083 +
88084 + @Description This routine is called to read a specified PHY
88085 + register value.
88086 +
88087 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
88088 + @Param[in] phyAddr - PHY address (0-31).
88089 + @Param[in] reg - PHY register to read
88090 + @Param[out] p_Data - Gets the register value.
88091 +
88092 + @Return Always zero (success).
88093 +*//***************************************************************************/
88094 +int MII_ReadPhyReg(t_Handle h_MiiAccess,
88095 + uint8_t phyAddr,
88096 + uint8_t reg,
88097 + uint16_t *p_Data);
88098 +
88099 +/**************************************************************************//**
88100 + @Function MII_WritePhyReg
88101 +
88102 + @Description This routine is called to write data to a specified PHY
88103 + register.
88104 +
88105 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
88106 + @Param[in] phyAddr - PHY address (0-31).
88107 + @Param[in] reg - PHY register to write
88108 + @Param[in] data - Data to write in register.
88109 +
88110 + @Return Always zero (success).
88111 +*//***************************************************************************/
88112 +int MII_WritePhyReg(t_Handle h_MiiAccess,
88113 + uint8_t phyAddr,
88114 + uint8_t reg,
88115 + uint16_t data);
88116 +
88117 +
88118 +#endif /* __MII_ACC_EXT_H */
88119 --- /dev/null
88120 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
88121 @@ -0,0 +1,90 @@
88122 +/*
88123 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88124 + *
88125 + * Redistribution and use in source and binary forms, with or without
88126 + * modification, are permitted provided that the following conditions are met:
88127 + * * Redistributions of source code must retain the above copyright
88128 + * notice, this list of conditions and the following disclaimer.
88129 + * * Redistributions in binary form must reproduce the above copyright
88130 + * notice, this list of conditions and the following disclaimer in the
88131 + * documentation and/or other materials provided with the distribution.
88132 + * * Neither the name of Freescale Semiconductor nor the
88133 + * names of its contributors may be used to endorse or promote products
88134 + * derived from this software without specific prior written permission.
88135 + *
88136 + *
88137 + * ALTERNATIVELY, this software may be distributed under the terms of the
88138 + * GNU General Public License ("GPL") as published by the Free Software
88139 + * Foundation, either version 2 of that License or (at your option) any
88140 + * later version.
88141 + *
88142 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88143 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88144 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88145 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88146 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88147 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88148 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88149 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88150 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88151 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88152 + */
88153 +
88154 +
88155 +/**************************************************************************//**
88156 + @File core_ext.h
88157 +
88158 + @Description Generic interface to basic core operations.
88159 +
88160 + The system integrator must ensure that this interface is
88161 + mapped to a specific core implementation, by including the
88162 + appropriate header file.
88163 +*//***************************************************************************/
88164 +#ifndef __CORE_EXT_H
88165 +#define __CORE_EXT_H
88166 +
88167 +#ifdef CONFIG_FMAN_ARM
88168 +#include "arm_ext.h"
88169 +#include <linux/smp.h>
88170 +#else
88171 +#ifdef NCSW_PPC_CORE
88172 +#include "ppc_ext.h"
88173 +#elif defined(NCSW_VXWORKS)
88174 +#include "core_vxw_ext.h"
88175 +#else
88176 +#error "Core is not defined!"
88177 +#endif /* NCSW_CORE */
88178 +
88179 +#if (!defined(CORE_IS_LITTLE_ENDIAN) && !defined(CORE_IS_BIG_ENDIAN))
88180 +#error "Must define core as little-endian or big-endian!"
88181 +#endif /* (!defined(CORE_IS_LITTLE_ENDIAN) && ... */
88182 +
88183 +#ifndef CORE_CACHELINE_SIZE
88184 +#error "Must define the core cache-line size!"
88185 +#endif /* !CORE_CACHELINE_SIZE */
88186 +
88187 +#endif /* CONFIG_FMAN_ARM */
88188 +
88189 +
88190 +/**************************************************************************//**
88191 + @Function CORE_GetId
88192 +
88193 + @Description Returns the core ID in the system.
88194 +
88195 + @Return Core ID.
88196 +*//***************************************************************************/
88197 +uint32_t CORE_GetId(void);
88198 +
88199 +/**************************************************************************//**
88200 + @Function CORE_MemoryBarrier
88201 +
88202 + @Description This routine will cause the core to stop executing any commands
88203 + until all previous memory read/write commands are completely out
88204 + of the core's pipeline.
88205 +
88206 + @Return None.
88207 +*//***************************************************************************/
88208 +void CORE_MemoryBarrier(void);
88209 +#define fsl_mem_core_barrier() CORE_MemoryBarrier()
88210 +
88211 +#endif /* __CORE_EXT_H */
88212 --- /dev/null
88213 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
88214 @@ -0,0 +1,55 @@
88215 +/*
88216 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88217 + *
88218 + * Redistribution and use in source and binary forms, with or without
88219 + * modification, are permitted provided that the following conditions are met:
88220 + * * Redistributions of source code must retain the above copyright
88221 + * notice, this list of conditions and the following disclaimer.
88222 + * * Redistributions in binary form must reproduce the above copyright
88223 + * notice, this list of conditions and the following disclaimer in the
88224 + * documentation and/or other materials provided with the distribution.
88225 + * * Neither the name of Freescale Semiconductor nor the
88226 + * names of its contributors may be used to endorse or promote products
88227 + * derived from this software without specific prior written permission.
88228 + *
88229 + *
88230 + * ALTERNATIVELY, this software may be distributed under the terms of the
88231 + * GNU General Public License ("GPL") as published by the Free Software
88232 + * Foundation, either version 2 of that License or (at your option) any
88233 + * later version.
88234 + *
88235 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88236 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88237 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88238 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88239 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88240 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88241 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88242 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88243 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88244 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88245 + */
88246 +
88247 +
88248 +/**************************************************************************//**
88249 + @File arm_ext.h
88250 +
88251 + @Description Core API for ARM cores
88252 +
88253 + These routines must be implemented by each specific PowerPC
88254 + core driver.
88255 +*//***************************************************************************/
88256 +#ifndef __ARM_EXT_H
88257 +#define __ARM_EXT_H
88258 +
88259 +#include "part_ext.h"
88260 +
88261 +
88262 +#define CORE_IS_LITTLE_ENDIAN
88263 +
88264 +static __inline__ void CORE_MemoryBarrier(void)
88265 +{
88266 + mb();
88267 +}
88268 +
88269 +#endif /* __PPC_EXT_H */
88270 --- /dev/null
88271 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
88272 @@ -0,0 +1,476 @@
88273 +/*
88274 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88275 + *
88276 + * Redistribution and use in source and binary forms, with or without
88277 + * modification, are permitted provided that the following conditions are met:
88278 + * * Redistributions of source code must retain the above copyright
88279 + * notice, this list of conditions and the following disclaimer.
88280 + * * Redistributions in binary form must reproduce the above copyright
88281 + * notice, this list of conditions and the following disclaimer in the
88282 + * documentation and/or other materials provided with the distribution.
88283 + * * Neither the name of Freescale Semiconductor nor the
88284 + * names of its contributors may be used to endorse or promote products
88285 + * derived from this software without specific prior written permission.
88286 + *
88287 + *
88288 + * ALTERNATIVELY, this software may be distributed under the terms of the
88289 + * GNU General Public License ("GPL") as published by the Free Software
88290 + * Foundation, either version 2 of that License or (at your option) any
88291 + * later version.
88292 + *
88293 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88294 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88295 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88296 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88297 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88298 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88299 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88300 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88301 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88302 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88303 + */
88304 +
88305 +
88306 +/**************************************************************************//**
88307 + @File e500v2_ext.h
88308 +
88309 + @Description E500 external definitions prototypes
88310 + This file is not included by the E500
88311 + source file as it is an assembly file. It is used
88312 + only for prototypes exposure, for inclusion
88313 + by user and other modules.
88314 +*//***************************************************************************/
88315 +
88316 +#ifndef __E500V2_EXT_H
88317 +#define __E500V2_EXT_H
88318 +
88319 +#include "std_ext.h"
88320 +
88321 +
88322 +/* Layer 1 Cache Manipulations
88323 + *==============================
88324 + * Should not be called directly by the user.
88325 + */
88326 +void L1DCache_Invalidate (void);
88327 +void L1ICache_Invalidate(void);
88328 +void L1DCache_Enable(void);
88329 +void L1ICache_Enable(void);
88330 +void L1DCache_Disable(void);
88331 +void L1ICache_Disable(void);
88332 +void L1DCache_Flush(void);
88333 +void L1ICache_Flush(void);
88334 +uint32_t L1ICache_IsEnabled(void);
88335 +uint32_t L1DCache_IsEnabled(void);
88336 +/*
88337 + *
88338 + */
88339 +uint32_t L1DCache_LineLock(uint32_t addr);
88340 +uint32_t L1ICache_LineLock(uint32_t addr);
88341 +void L1Cache_BroadCastEnable(void);
88342 +void L1Cache_BroadCastDisable(void);
88343 +
88344 +
88345 +#define CORE_DCacheEnable E500_DCacheEnable
88346 +#define CORE_ICacheEnable E500_ICacheEnable
88347 +#define CORE_DCacheDisable E500_DCacheDisable
88348 +#define CORE_ICacheDisable E500_ICacheDisable
88349 +#define CORE_GetId E500_GetId
88350 +#define CORE_TestAndSet E500_TestAndSet
88351 +#define CORE_MemoryBarrier E500_MemoryBarrier
88352 +#define CORE_InstructionSync E500_InstructionSync
88353 +
88354 +#define CORE_SetDozeMode E500_SetDozeMode
88355 +#define CORE_SetNapMode E500_SetNapMode
88356 +#define CORE_SetSleepMode E500_SetSleepMode
88357 +#define CORE_SetJogMode E500_SetJogMode
88358 +#define CORE_SetDeepSleepMode E500_SetDeepSleepMode
88359 +
88360 +#define CORE_RecoverDozeMode E500_RecoverDozeMode
88361 +#define CORE_RecoverNapMode E500_RecoverNapMode
88362 +#define CORE_RecoverSleepMode E500_RecoverSleepMode
88363 +#define CORE_RecoverJogMode E500_RecoverJogMode
88364 +
88365 +void E500_SetDozeMode(void);
88366 +void E500_SetNapMode(void);
88367 +void E500_SetSleepMode(void);
88368 +void E500_SetJogMode(void);
88369 +t_Error E500_SetDeepSleepMode(uint32_t bptrAddress);
88370 +
88371 +void E500_RecoverDozeMode(void);
88372 +void E500_RecoverNapMode(void);
88373 +void E500_RecoverSleepMode(void);
88374 +void E500_RecoverJogMode(void);
88375 +
88376 +
88377 +/**************************************************************************//**
88378 + @Group E500_id E500 Application Programming Interface
88379 +
88380 + @Description E500 API functions, definitions and enums
88381 +
88382 + @{
88383 +*//***************************************************************************/
88384 +
88385 +/**************************************************************************//**
88386 + @Group E500_init_grp E500 Initialization Unit
88387 +
88388 + @Description E500 initialization unit API functions, definitions and enums
88389 +
88390 + @{
88391 +*//***************************************************************************/
88392 +
88393 +
88394 +/**************************************************************************//**
88395 + @Function E500_DCacheEnable
88396 +
88397 + @Description Enables the data cache for memory pages that are
88398 + not cache inhibited.
88399 +
88400 + @Return None.
88401 +*//***************************************************************************/
88402 +void E500_DCacheEnable(void);
88403 +
88404 +/**************************************************************************//**
88405 + @Function E500_ICacheEnable
88406 +
88407 + @Description Enables the instruction cache for memory pages that are
88408 + not cache inhibited.
88409 +
88410 + @Return None.
88411 +*//***************************************************************************/
88412 +void E500_ICacheEnable(void);
88413 +
88414 +/**************************************************************************//**
88415 + @Function E500_DCacheDisable
88416 +
88417 + @Description Disables the data cache.
88418 +
88419 + @Return None.
88420 +*//***************************************************************************/
88421 +void E500_DCacheDisable(void);
88422 +
88423 +/**************************************************************************//**
88424 + @Function E500_ICacheDisable
88425 +
88426 + @Description Disables the instruction cache.
88427 +
88428 + @Return None.
88429 +*//***************************************************************************/
88430 +void E500_ICacheDisable(void);
88431 +
88432 +/**************************************************************************//**
88433 + @Function E500_DCacheFlush
88434 +
88435 + @Description Flushes the data cache
88436 +
88437 + @Return None.
88438 +*//***************************************************************************/
88439 +void E500_DCacheFlush(void);
88440 +
88441 +/**************************************************************************//**
88442 + @Function E500_ICacheFlush
88443 +
88444 + @Description Flushes the instruction cache.
88445 +
88446 + @Return None.
88447 +*//***************************************************************************/
88448 +void E500_ICacheFlush(void);
88449 +
88450 +/**************************************************************************//**
88451 + @Function E500_DCacheSetStashId
88452 +
88453 + @Description Set Stash Id for data cache
88454 +
88455 + @Param[in] stashId the stash id to be set.
88456 +
88457 + @Return None.
88458 +*//***************************************************************************/
88459 +void E500_DCacheSetStashId(uint8_t stashId);
88460 +
88461 +/**************************************************************************//**
88462 + @Description E500mc L2 Cache Operation Mode
88463 +*//***************************************************************************/
88464 +typedef enum e_E500mcL2CacheMode
88465 +{
88466 + e_L2_CACHE_MODE_DATA_ONLY = 0x00000001, /**< Cache data only */
88467 + e_L2_CACHE_MODE_INST_ONLY = 0x00000002, /**< Cache instructions only */
88468 + e_L2_CACHE_MODE_DATA_AND_INST = 0x00000003 /**< Cache data and instructions */
88469 +} e_E500mcL2CacheMode;
88470 +
88471 +#if defined(CORE_E500MC) || defined(CORE_E5500)
88472 +/**************************************************************************//**
88473 + @Function E500_L2CacheEnable
88474 +
88475 + @Description Enables the cache for memory pages that are not cache inhibited.
88476 +
88477 + @param[in] mode - L2 cache mode: data only, instruction only or instruction and data.
88478 +
88479 + @Return None.
88480 +
88481 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88482 + not possible to call this routine for i-cache and than to call
88483 + again for d-cache; The second call will override the first one.
88484 +*//***************************************************************************/
88485 +void E500_L2CacheEnable(e_E500mcL2CacheMode mode);
88486 +
88487 +/**************************************************************************//**
88488 + @Function E500_L2CacheDisable
88489 +
88490 + @Description Disables the cache (data instruction or both).
88491 +
88492 + @Return None.
88493 +
88494 +*//***************************************************************************/
88495 +void E500_L2CacheDisable(void);
88496 +
88497 +/**************************************************************************//**
88498 + @Function E500_L2CacheFlush
88499 +
88500 + @Description Flushes the cache.
88501 +
88502 + @Return None.
88503 +*//***************************************************************************/
88504 +void E500_L2CacheFlush(void);
88505 +
88506 +/**************************************************************************//**
88507 + @Function E500_L2SetStashId
88508 +
88509 + @Description Set Stash Id
88510 +
88511 + @Param[in] stashId the stash id to be set.
88512 +
88513 + @Return None.
88514 +*//***************************************************************************/
88515 +void E500_L2SetStashId(uint8_t stashId);
88516 +#endif /* defined(CORE_E500MC) || defined(CORE_E5500) */
88517 +
88518 +#ifdef CORE_E6500
88519 +/**************************************************************************//**
88520 + @Function E6500_L2CacheEnable
88521 +
88522 + @Description Enables the cache for memory pages that are not cache inhibited.
88523 +
88524 + @param[in] mode - L2 cache mode: support data & instruction only.
88525 +
88526 + @Return None.
88527 +
88528 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88529 + not possible to call this routine for i-cache and than to call
88530 + again for d-cache; The second call will override the first one.
88531 +*//***************************************************************************/
88532 +void E6500_L2CacheEnable(uintptr_t clusterBase);
88533 +
88534 +/**************************************************************************//**
88535 + @Function E6500_L2CacheDisable
88536 +
88537 + @Description Disables the cache (data instruction or both).
88538 +
88539 + @Return None.
88540 +
88541 +*//***************************************************************************/
88542 +void E6500_L2CacheDisable(uintptr_t clusterBase);
88543 +
88544 +/**************************************************************************//**
88545 + @Function E6500_L2CacheFlush
88546 +
88547 + @Description Flushes the cache.
88548 +
88549 + @Return None.
88550 +*//***************************************************************************/
88551 +void E6500_L2CacheFlush(uintptr_t clusterBase);
88552 +
88553 +/**************************************************************************//**
88554 + @Function E6500_L2SetStashId
88555 +
88556 + @Description Set Stash Id
88557 +
88558 + @Param[in] stashId the stash id to be set.
88559 +
88560 + @Return None.
88561 +*//***************************************************************************/
88562 +void E6500_L2SetStashId(uintptr_t clusterBase, uint8_t stashId);
88563 +
88564 +/**************************************************************************//**
88565 + @Function E6500_GetCcsrBase
88566 +
88567 + @Description Obtain SoC CCSR base address
88568 +
88569 + @Param[in] None.
88570 +
88571 + @Return Physical CCSR base address.
88572 +*//***************************************************************************/
88573 +physAddress_t E6500_GetCcsrBase(void);
88574 +#endif /* CORE_E6500 */
88575 +
88576 +/**************************************************************************//**
88577 + @Function E500_AddressBusStreamingEnable
88578 +
88579 + @Description Enables address bus streaming on the CCB.
88580 +
88581 + This setting, along with the ECM streaming configuration
88582 + parameters, enables address bus streaming on the CCB.
88583 +
88584 + @Return None.
88585 +*//***************************************************************************/
88586 +void E500_AddressBusStreamingEnable(void);
88587 +
88588 +/**************************************************************************//**
88589 + @Function E500_AddressBusStreamingDisable
88590 +
88591 + @Description Disables address bus streaming on the CCB.
88592 +
88593 + @Return None.
88594 +*//***************************************************************************/
88595 +void E500_AddressBusStreamingDisable(void);
88596 +
88597 +/**************************************************************************//**
88598 + @Function E500_AddressBroadcastEnable
88599 +
88600 + @Description Enables address broadcast.
88601 +
88602 + The e500 broadcasts cache management instructions (dcbst, dcblc
88603 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88604 + based on ABE. ABE must be set to allow management of external
88605 + L2 caches.
88606 +
88607 + @Return None.
88608 +*//***************************************************************************/
88609 +void E500_AddressBroadcastEnable(void);
88610 +
88611 +/**************************************************************************//**
88612 + @Function E500_AddressBroadcastDisable
88613 +
88614 + @Description Disables address broadcast.
88615 +
88616 + The e500 broadcasts cache management instructions (dcbst, dcblc
88617 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88618 + based on ABE. ABE must be set to allow management of external
88619 + L2 caches.
88620 +
88621 + @Return None.
88622 +*//***************************************************************************/
88623 +void E500_AddressBroadcastDisable(void);
88624 +
88625 +/**************************************************************************//**
88626 + @Function E500_IsTaskletSupported
88627 +
88628 + @Description Checks if tasklets are supported by the e500 interrupt handler.
88629 +
88630 + @Retval TRUE - Tasklets are supported.
88631 + @Retval FALSE - Tasklets are not supported.
88632 +*//***************************************************************************/
88633 +bool E500_IsTaskletSupported(void);
88634 +
88635 +void E500_EnableTimeBase(void);
88636 +void E500_DisableTimeBase(void);
88637 +
88638 +uint64_t E500_GetTimeBaseTime(void);
88639 +
88640 +void E500_GenericIntrInit(void);
88641 +
88642 +t_Error E500_SetIntr(int ppcIntrSrc,
88643 + void (* Isr)(t_Handle handle),
88644 + t_Handle handle);
88645 +
88646 +t_Error E500_ClearIntr(int ppcIntrSrc);
88647 +
88648 +/**************************************************************************//**
88649 + @Function E500_GenericIntrHandler
88650 +
88651 + @Description This is the general e500 interrupt handler.
88652 +
88653 + It is called by the main assembly interrupt handler
88654 + when an exception occurs and no other function has been
88655 + assigned to this exception.
88656 +
88657 + @Param intrEntry - (In) The exception interrupt vector entry.
88658 +*//***************************************************************************/
88659 +void E500_GenericIntrHandler(uint32_t intrEntry);
88660 +
88661 +/**************************************************************************//**
88662 + @Function CriticalIntr
88663 +
88664 + @Description This is the specific critical e500 interrupt handler.
88665 +
88666 + It is called by the main assembly interrupt handler
88667 + when an critical interrupt.
88668 +
88669 + @Param intrEntry - (In) The exception interrupt vector entry.
88670 +*//***************************************************************************/
88671 +void CriticalIntr(uint32_t intrEntry);
88672 +
88673 +
88674 +/**************************************************************************//**
88675 + @Function E500_GetId
88676 +
88677 + @Description Returns the core ID in the system.
88678 +
88679 + @Return Core ID.
88680 +*//***************************************************************************/
88681 +uint32_t E500_GetId(void);
88682 +
88683 +/**************************************************************************//**
88684 + @Function E500_TestAndSet
88685 +
88686 + @Description This routine tries to atomically test-and-set an integer
88687 + in memory to a non-zero value.
88688 +
88689 + The memory will be set only if it is tested as zero, in which
88690 + case the routine returns the new non-zero value; otherwise the
88691 + routine returns zero.
88692 +
88693 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
88694 + operation should be made.
88695 +
88696 + @Retval Zero - Operation failed - memory was already set.
88697 + @Retval Non-zero - Operation succeeded - memory has been set.
88698 +*//***************************************************************************/
88699 +int E500_TestAndSet(volatile int *p);
88700 +
88701 +/**************************************************************************//**
88702 + @Function E500_MemoryBarrier
88703 +
88704 + @Description This routine will cause the core to stop executing any commands
88705 + until all previous memory read/write commands are completely out
88706 + of the core's pipeline.
88707 +
88708 + @Return None.
88709 +*//***************************************************************************/
88710 +static __inline__ void E500_MemoryBarrier(void)
88711 +{
88712 +#ifndef CORE_E500V2
88713 + __asm__ ("mbar 1");
88714 +#else /* CORE_E500V2 */
88715 + /**** ERRATA WORK AROUND START ****/
88716 + /* ERRATA num: CPU1 */
88717 + /* Description: "mbar MO = 1" instruction fails to order caching-inhibited
88718 + guarded loads and stores. */
88719 +
88720 + /* "msync" instruction is used instead */
88721 +
88722 + __asm__ ("msync");
88723 +
88724 + /**** ERRATA WORK AROUND END ****/
88725 +#endif /* CORE_E500V2 */
88726 +}
88727 +
88728 +/**************************************************************************//**
88729 + @Function E500_InstructionSync
88730 +
88731 + @Description This routine will cause the core to wait for previous instructions
88732 + (including any interrupts they generate) to complete before the
88733 + synchronization command executes, which purges all instructions
88734 + from the processor's pipeline and refetches the next instruction.
88735 +
88736 + @Return None.
88737 +*//***************************************************************************/
88738 +static __inline__ void E500_InstructionSync(void)
88739 +{
88740 + __asm__ ("isync");
88741 +}
88742 +
88743 +
88744 +/** @} */ /* end of E500_init_grp group */
88745 +/** @} */ /* end of E500_grp group */
88746 +
88747 +
88748 +#endif /* __E500V2_EXT_H */
88749 --- /dev/null
88750 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
88751 @@ -0,0 +1,141 @@
88752 +/*
88753 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88754 + *
88755 + * Redistribution and use in source and binary forms, with or without
88756 + * modification, are permitted provided that the following conditions are met:
88757 + * * Redistributions of source code must retain the above copyright
88758 + * notice, this list of conditions and the following disclaimer.
88759 + * * Redistributions in binary form must reproduce the above copyright
88760 + * notice, this list of conditions and the following disclaimer in the
88761 + * documentation and/or other materials provided with the distribution.
88762 + * * Neither the name of Freescale Semiconductor nor the
88763 + * names of its contributors may be used to endorse or promote products
88764 + * derived from this software without specific prior written permission.
88765 + *
88766 + *
88767 + * ALTERNATIVELY, this software may be distributed under the terms of the
88768 + * GNU General Public License ("GPL") as published by the Free Software
88769 + * Foundation, either version 2 of that License or (at your option) any
88770 + * later version.
88771 + *
88772 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88773 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88774 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88775 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88776 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88777 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88778 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88779 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88780 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88781 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88782 + */
88783 +
88784 +
88785 +/**************************************************************************//**
88786 + @File ppc_ext.h
88787 +
88788 + @Description Core API for PowerPC cores
88789 +
88790 + These routines must be implemented by each specific PowerPC
88791 + core driver.
88792 +*//***************************************************************************/
88793 +#ifndef __PPC_EXT_H
88794 +#define __PPC_EXT_H
88795 +
88796 +#include "part_ext.h"
88797 +
88798 +
88799 +#define CORE_IS_BIG_ENDIAN
88800 +
88801 +#if defined(CORE_E300) || defined(CORE_E500V2)
88802 +#define CORE_CACHELINE_SIZE 32
88803 +#elif defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
88804 +#define CORE_CACHELINE_SIZE 64
88805 +#else
88806 +#error "Core not defined!"
88807 +#endif /* defined(CORE_E300) || ... */
88808 +
88809 +
88810 +/**************************************************************************//**
88811 + @Function CORE_TestAndSet
88812 +
88813 + @Description This routine tries to atomically test-and-set an integer
88814 + in memory to a non-zero value.
88815 +
88816 + The memory will be set only if it is tested as zero, in which
88817 + case the routine returns the new non-zero value; otherwise the
88818 + routine returns zero.
88819 +
88820 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
88821 + operation should be made.
88822 +
88823 + @Retval Zero - Operation failed - memory was already set.
88824 + @Retval Non-zero - Operation succeeded - memory has been set.
88825 +*//***************************************************************************/
88826 +int CORE_TestAndSet(volatile int *p);
88827 +
88828 +/**************************************************************************//**
88829 + @Function CORE_InstructionSync
88830 +
88831 + @Description This routine will cause the core to wait for previous instructions
88832 + (including any interrupts they generate) to complete before the
88833 + synchronization command executes, which purges all instructions
88834 + from the processor's pipeline and refetches the next instruction.
88835 +
88836 + @Return None.
88837 +*//***************************************************************************/
88838 +void CORE_InstructionSync(void);
88839 +
88840 +/**************************************************************************//**
88841 + @Function CORE_DCacheEnable
88842 +
88843 + @Description Enables the data cache for memory pages that are
88844 + not cache inhibited.
88845 +
88846 + @Return None.
88847 +*//***************************************************************************/
88848 +void CORE_DCacheEnable(void);
88849 +
88850 +/**************************************************************************//**
88851 + @Function CORE_ICacheEnable
88852 +
88853 + @Description Enables the instruction cache for memory pages that are
88854 + not cache inhibited.
88855 +
88856 + @Return None.
88857 +*//***************************************************************************/
88858 +void CORE_ICacheEnable(void);
88859 +
88860 +/**************************************************************************//**
88861 + @Function CORE_DCacheDisable
88862 +
88863 + @Description Disables the data cache.
88864 +
88865 + @Return None.
88866 +*//***************************************************************************/
88867 +void CORE_DCacheDisable(void);
88868 +
88869 +/**************************************************************************//**
88870 + @Function CORE_ICacheDisable
88871 +
88872 + @Description Disables the instruction cache.
88873 +
88874 + @Return None.
88875 +*//***************************************************************************/
88876 +void CORE_ICacheDisable(void);
88877 +
88878 +
88879 +
88880 +#if defined(CORE_E300)
88881 +#include "e300_ext.h"
88882 +#elif defined(CORE_E500V2) || defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
88883 +#include "e500v2_ext.h"
88884 +#if !defined(NCSW_LINUX)
88885 +#include "e500v2_asm_ext.h"
88886 +#endif
88887 +#else
88888 +#error "Core not defined!"
88889 +#endif
88890 +
88891 +
88892 +#endif /* __PPC_EXT_H */
88893 --- /dev/null
88894 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
88895 @@ -0,0 +1,77 @@
88896 +/*
88897 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88898 + *
88899 + * Redistribution and use in source and binary forms, with or without
88900 + * modification, are permitted provided that the following conditions are met:
88901 + * * Redistributions of source code must retain the above copyright
88902 + * notice, this list of conditions and the following disclaimer.
88903 + * * Redistributions in binary form must reproduce the above copyright
88904 + * notice, this list of conditions and the following disclaimer in the
88905 + * documentation and/or other materials provided with the distribution.
88906 + * * Neither the name of Freescale Semiconductor nor the
88907 + * names of its contributors may be used to endorse or promote products
88908 + * derived from this software without specific prior written permission.
88909 + *
88910 + *
88911 + * ALTERNATIVELY, this software may be distributed under the terms of the
88912 + * GNU General Public License ("GPL") as published by the Free Software
88913 + * Foundation, either version 2 of that License or (at your option) any
88914 + * later version.
88915 + *
88916 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88917 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88918 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88919 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88920 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88921 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88922 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88923 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88924 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88925 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88926 + */
88927 +
88928 +#ifndef __DDR_SDT_EXT_H
88929 +#define __DDR_SDT_EXT_H
88930 +
88931 +
88932 +/**************************************************************************//**
88933 + @Group ddr_Generic_Resources
88934 +
88935 + @Description ddr generic functions, definitions and enums.
88936 +
88937 + @{
88938 +*//***************************************************************************/
88939 +
88940 +
88941 +/**************************************************************************//**
88942 + @Description SPD maximum size
88943 +*//***************************************************************************/
88944 +#define SPD_MAX_SIZE 256
88945 +
88946 +/**************************************************************************//**
88947 + @Description DDR types select
88948 +*//***************************************************************************/
88949 +typedef enum e_DdrType
88950 +{
88951 + e_DDR_DDR1,
88952 + e_DDR_DDR2,
88953 + e_DDR_DDR3,
88954 + e_DDR_DDR3L,
88955 + e_DDR_DDR4
88956 +} e_DdrType;
88957 +
88958 +/**************************************************************************//**
88959 + @Description DDR Mode.
88960 +*//***************************************************************************/
88961 +typedef enum e_DdrMode
88962 +{
88963 + e_DDR_BUS_WIDTH_32BIT,
88964 + e_DDR_BUS_WIDTH_64BIT
88965 +} e_DdrMode;
88966 +
88967 +/** @} */ /* end of ddr_Generic_Resources group */
88968 +
88969 +
88970 +
88971 +#endif /* __DDR_SDT_EXT_H */
88972 +
88973 --- /dev/null
88974 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
88975 @@ -0,0 +1,233 @@
88976 +/*
88977 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88978 + *
88979 + * Redistribution and use in source and binary forms, with or without
88980 + * modification, are permitted provided that the following conditions are met:
88981 + * * Redistributions of source code must retain the above copyright
88982 + * notice, this list of conditions and the following disclaimer.
88983 + * * Redistributions in binary form must reproduce the above copyright
88984 + * notice, this list of conditions and the following disclaimer in the
88985 + * documentation and/or other materials provided with the distribution.
88986 + * * Neither the name of Freescale Semiconductor nor the
88987 + * names of its contributors may be used to endorse or promote products
88988 + * derived from this software without specific prior written permission.
88989 + *
88990 + *
88991 + * ALTERNATIVELY, this software may be distributed under the terms of the
88992 + * GNU General Public License ("GPL") as published by the Free Software
88993 + * Foundation, either version 2 of that License or (at your option) any
88994 + * later version.
88995 + *
88996 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88997 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88998 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88999 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89000 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89001 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89002 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89003 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89004 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89005 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89006 + */
89007 +
89008 +
89009 +/**************************************************************************//**
89010 + @File debug_ext.h
89011 +
89012 + @Description Debug mode definitions.
89013 +*//***************************************************************************/
89014 +
89015 +#ifndef __DEBUG_EXT_H
89016 +#define __DEBUG_EXT_H
89017 +
89018 +#include "std_ext.h"
89019 +#include "xx_ext.h"
89020 +#include "memcpy_ext.h"
89021 +#if (DEBUG_ERRORS > 0)
89022 +#include "sprint_ext.h"
89023 +#include "string_ext.h"
89024 +#endif /* DEBUG_ERRORS > 0 */
89025 +
89026 +
89027 +#if (DEBUG_ERRORS > 0)
89028 +
89029 +/* Internally used macros */
89030 +
89031 +#define DUMP_Print XX_Print
89032 +#define DUMP_MAX_LEVELS 6
89033 +#define DUMP_IDX_LEN 6
89034 +#define DUMP_MAX_STR 64
89035 +
89036 +
89037 +#define _CREATE_DUMP_SUBSTR(phrase) \
89038 + dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \
89039 + snprintf(dumpTmpStr, DUMP_MAX_STR, "%s", #phrase); \
89040 + p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \
89041 + while ((p_DumpToken != NULL) && (dumpTmpLevel < DUMP_MAX_LEVELS)) \
89042 + { \
89043 + strlcat(dumpSubStr, p_DumpToken, DUMP_MAX_STR); \
89044 + if (dumpIsArr[dumpTmpLevel]) \
89045 + { \
89046 + strlcat(dumpSubStr, dumpIdxStr[dumpTmpLevel], DUMP_MAX_STR); \
89047 + p_DumpToken = strtok(NULL, "."); \
89048 + } \
89049 + if ((p_DumpToken != NULL) && \
89050 + ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != NULL)) \
89051 + strlcat(dumpSubStr, ".", DUMP_MAX_STR); \
89052 + }
89053 +
89054 +
89055 +/**************************************************************************//**
89056 + @Group gen_id General Drivers Utilities
89057 +
89058 + @Description External routines.
89059 +
89060 + @{
89061 +*//***************************************************************************/
89062 +
89063 +/**************************************************************************//**
89064 + @Group dump_id Memory and Registers Dump Mechanism
89065 +
89066 + @Description Macros for dumping memory mapped structures.
89067 +
89068 + @{
89069 +*//***************************************************************************/
89070 +
89071 +/**************************************************************************//**
89072 + @Description Declaration of dump mechanism variables.
89073 +
89074 + This macro must be declared at the beginning of each routine
89075 + which uses the dump mechanism macros, before the routine's code
89076 + starts.
89077 +*//***************************************************************************/
89078 +#define DECLARE_DUMP \
89079 + char dumpIdxStr[DUMP_MAX_LEVELS + 1][DUMP_IDX_LEN] = { "", }; \
89080 + char dumpSubStr[DUMP_MAX_STR] = ""; \
89081 + char dumpTmpStr[DUMP_MAX_STR] = ""; \
89082 + char *p_DumpToken = NULL; \
89083 + int dumpArrIdx = 0, dumpArrSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \
89084 + uint8_t dumpIsArr[DUMP_MAX_LEVELS + 1] = { 0 }; \
89085 + /* Prevent warnings if not all used */ \
89086 + UNUSED(dumpIdxStr[0][0]); \
89087 + UNUSED(dumpSubStr[0]); \
89088 + UNUSED(dumpTmpStr[0]); \
89089 + UNUSED(p_DumpToken); \
89090 + UNUSED(dumpArrIdx); \
89091 + UNUSED(dumpArrSize); \
89092 + UNUSED(dumpLevel); \
89093 + UNUSED(dumpTmpLevel); \
89094 + UNUSED(dumpIsArr[0]);
89095 +
89096 +
89097 +/**************************************************************************//**
89098 + @Description Prints a title for a subsequent dumped structure or memory.
89099 +
89100 + The inputs for this macro are the structure/memory title and
89101 + its base addresses.
89102 +*//***************************************************************************/
89103 +#define DUMP_TITLE(addr, msg) \
89104 + DUMP_Print("\r\n"); DUMP_Print msg; \
89105 + if (addr) \
89106 + DUMP_Print(" (%p)", (addr)); \
89107 + DUMP_Print("\r\n---------------------------------------------------------\r\n");
89108 +
89109 +/**************************************************************************//**
89110 + @Description Prints a subtitle for a subsequent dumped sub-structure (optional).
89111 +
89112 + The inputs for this macro are the sub-structure subtitle.
89113 + A separating line with this subtitle will be printed.
89114 +*//***************************************************************************/
89115 +#define DUMP_SUBTITLE(subtitle) \
89116 + DUMP_Print("----------- "); DUMP_Print subtitle; DUMP_Print("\r\n")
89117 +
89118 +
89119 +/**************************************************************************//**
89120 + @Description Dumps a memory region in 4-bytes aligned format.
89121 +
89122 + The inputs for this macro are the base addresses and size
89123 + (in bytes) of the memory region.
89124 +*//***************************************************************************/
89125 +#define DUMP_MEMORY(addr, size) \
89126 + MemDisp((uint8_t *)(addr), (int)(size))
89127 +
89128 +
89129 +/**************************************************************************//**
89130 + @Description Declares a dump loop, for dumping a sub-structure array.
89131 +
89132 + The inputs for this macro are:
89133 + - idx: an index variable, for indexing the sub-structure items
89134 + inside the loop. This variable must be declared separately
89135 + in the beginning of the routine.
89136 + - cnt: the number of times to repeat the loop. This number should
89137 + equal the number of items in the sub-structures array.
89138 +
89139 + Note, that the body of the loop must be written inside brackets.
89140 +*//***************************************************************************/
89141 +#define DUMP_SUBSTRUCT_ARRAY(idx, cnt) \
89142 + for (idx=0, dumpIsArr[dumpLevel++] = 1; \
89143 + (idx < cnt) && (dumpLevel > 0) && snprintf(dumpIdxStr[dumpLevel-1], DUMP_IDX_LEN, "[%d]", idx); \
89144 + idx++, ((idx < cnt) || (dumpIsArr[--dumpLevel] = 0)))
89145 +
89146 +
89147 +/**************************************************************************//**
89148 + @Description Dumps a structure's member variable.
89149 +
89150 + The input for this macro is the full reference for the member
89151 + variable, where the structure is referenced using a pointer.
89152 +
89153 + Note, that a members array must be dumped using DUMP_ARR macro,
89154 + rather than using this macro.
89155 +
89156 + If the member variable is part of a sub-structure hierarchy,
89157 + the full hierarchy (including array indexing) must be specified.
89158 +
89159 + Examples: p_Struct->member
89160 + p_Struct->sub.member
89161 + p_Struct->sub[i].member
89162 +*//***************************************************************************/
89163 +#define DUMP_VAR(st, phrase) \
89164 + do { \
89165 + void *addr = (void *)&((st)->phrase); \
89166 + physAddress_t physAddr = XX_VirtToPhys(addr); \
89167 + _CREATE_DUMP_SUBSTR(phrase); \
89168 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s\r\n", \
89169 + physAddr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); \
89170 + } while (0)
89171 +
89172 +
89173 +/**************************************************************************//**
89174 + @Description Dumps a structure's members array.
89175 +
89176 + The input for this macro is the full reference for the members
89177 + array, where the structure is referenced using a pointer.
89178 +
89179 + If the members array is part of a sub-structure hierarchy,
89180 + the full hierarchy (including array indexing) must be specified.
89181 +
89182 + Examples: p_Struct->array
89183 + p_Struct->sub.array
89184 + p_Struct->sub[i].array
89185 +*//***************************************************************************/
89186 +#define DUMP_ARR(st, phrase) \
89187 + do { \
89188 + physAddress_t physAddr; \
89189 + _CREATE_DUMP_SUBSTR(phrase); \
89190 + dumpArrSize = ARRAY_SIZE((st)->phrase); \
89191 + for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
89192 + physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \
89193 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s[%d]\r\n", \
89194 + physAddr, GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \
89195 + } \
89196 + } while (0)
89197 +
89198 +
89199 +
89200 +#endif /* DEBUG_ERRORS > 0 */
89201 +
89202 +
89203 +/** @} */ /* end of dump_id group */
89204 +/** @} */ /* end of gen_id group */
89205 +
89206 +
89207 +#endif /* __DEBUG_EXT_H */
89208 +
89209 --- /dev/null
89210 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
89211 @@ -0,0 +1,447 @@
89212 +/*
89213 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89214 + *
89215 + * Redistribution and use in source and binary forms, with or without
89216 + * modification, are permitted provided that the following conditions are met:
89217 + * * Redistributions of source code must retain the above copyright
89218 + * notice, this list of conditions and the following disclaimer.
89219 + * * Redistributions in binary form must reproduce the above copyright
89220 + * notice, this list of conditions and the following disclaimer in the
89221 + * documentation and/or other materials provided with the distribution.
89222 + * * Neither the name of Freescale Semiconductor nor the
89223 + * names of its contributors may be used to endorse or promote products
89224 + * derived from this software without specific prior written permission.
89225 + *
89226 + *
89227 + * ALTERNATIVELY, this software may be distributed under the terms of the
89228 + * GNU General Public License ("GPL") as published by the Free Software
89229 + * Foundation, either version 2 of that License or (at your option) any
89230 + * later version.
89231 + *
89232 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89233 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89234 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89235 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89236 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89237 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89238 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89239 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89240 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89241 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89242 + */
89243 +
89244 +
89245 +/**************************************************************************//**
89246 +
89247 + @File endian_ext.h
89248 +
89249 + @Description Big/little endian swapping routines.
89250 +*//***************************************************************************/
89251 +
89252 +#ifndef __ENDIAN_EXT_H
89253 +#define __ENDIAN_EXT_H
89254 +
89255 +#include "std_ext.h"
89256 +
89257 +
89258 +/**************************************************************************//**
89259 + @Group gen_id General Drivers Utilities
89260 +
89261 + @Description General usage API. This API is intended for usage by both the
89262 + internal modules and the user's application.
89263 +
89264 + @{
89265 +*//***************************************************************************/
89266 +
89267 +/**************************************************************************//**
89268 + @Group endian_id Big/Little-Endian Conversion
89269 +
89270 + @Description Routines and macros for Big/Little-Endian conversion and
89271 + general byte swapping.
89272 +
89273 + All routines and macros are expecting unsigned values as
89274 + parameters, but will generate the correct result also for
89275 + signed values. Therefore, signed/unsigned casting is allowed.
89276 + @{
89277 +*//***************************************************************************/
89278 +
89279 +/**************************************************************************//**
89280 + @Collection Byte-Swap Macros
89281 +
89282 + Macros for swapping byte order.
89283 +
89284 + @Cautions The parameters of these macros are evaluated multiple times.
89285 + For calculated expressions or expressions that contain function
89286 + calls it is recommended to use the byte-swap routines.
89287 +
89288 + @{
89289 +*//***************************************************************************/
89290 +
89291 +/**************************************************************************//**
89292 + @Description Swaps the byte order of a given 16-bit value.
89293 +
89294 + @Param[in] val - The 16-bit value to swap.
89295 +
89296 + @Return The byte-swapped value..
89297 +
89298 + @Cautions The given value is evaluated multiple times by this macro.
89299 + For calculated expressions or expressions that contain function
89300 + calls it is recommended to use the SwapUint16() routine.
89301 +
89302 + @hideinitializer
89303 +*//***************************************************************************/
89304 +#define SWAP_UINT16(val) \
89305 + ((uint16_t)((((val) & 0x00FF) << 8) | (((val) & 0xFF00) >> 8)))
89306 +
89307 +/**************************************************************************//**
89308 + @Description Swaps the byte order of a given 32-bit value.
89309 +
89310 + @Param[in] val - The 32-bit value to swap.
89311 +
89312 + @Return The byte-swapped value..
89313 +
89314 + @Cautions The given value is evaluated multiple times by this macro.
89315 + For calculated expressions or expressions that contain function
89316 + calls it is recommended to use the SwapUint32() routine.
89317 +
89318 + @hideinitializer
89319 +*//***************************************************************************/
89320 +#define SWAP_UINT32(val) \
89321 + ((uint32_t)((((val) & 0x000000FF) << 24) | \
89322 + (((val) & 0x0000FF00) << 8) | \
89323 + (((val) & 0x00FF0000) >> 8) | \
89324 + (((val) & 0xFF000000) >> 24)))
89325 +
89326 +/**************************************************************************//**
89327 + @Description Swaps the byte order of a given 64-bit value.
89328 +
89329 + @Param[in] val - The 64-bit value to swap.
89330 +
89331 + @Return The byte-swapped value..
89332 +
89333 + @Cautions The given value is evaluated multiple times by this macro.
89334 + For calculated expressions or expressions that contain function
89335 + calls it is recommended to use the SwapUint64() routine.
89336 +
89337 + @hideinitializer
89338 +*//***************************************************************************/
89339 +#define SWAP_UINT64(val) \
89340 + ((uint64_t)((((val) & 0x00000000000000FFULL) << 56) | \
89341 + (((val) & 0x000000000000FF00ULL) << 40) | \
89342 + (((val) & 0x0000000000FF0000ULL) << 24) | \
89343 + (((val) & 0x00000000FF000000ULL) << 8) | \
89344 + (((val) & 0x000000FF00000000ULL) >> 8) | \
89345 + (((val) & 0x0000FF0000000000ULL) >> 24) | \
89346 + (((val) & 0x00FF000000000000ULL) >> 40) | \
89347 + (((val) & 0xFF00000000000000ULL) >> 56)))
89348 +
89349 +/* @} */
89350 +
89351 +/**************************************************************************//**
89352 + @Collection Byte-Swap Routines
89353 +
89354 + Routines for swapping the byte order of a given parameter and
89355 + returning the swapped value.
89356 +
89357 + These inline routines are safer than the byte-swap macros,
89358 + because they evaluate the parameter expression only once.
89359 + @{
89360 +*//***************************************************************************/
89361 +
89362 +/**************************************************************************//**
89363 + @Function SwapUint16
89364 +
89365 + @Description Returns the byte-swapped value of a given 16-bit value.
89366 +
89367 + @Param[in] val - The 16-bit value.
89368 +
89369 + @Return The byte-swapped value of the parameter.
89370 +*//***************************************************************************/
89371 +static __inline__ uint16_t SwapUint16(uint16_t val)
89372 +{
89373 + return (uint16_t)(((val & 0x00FF) << 8) |
89374 + ((val & 0xFF00) >> 8));
89375 +}
89376 +
89377 +/**************************************************************************//**
89378 + @Function SwapUint32
89379 +
89380 + @Description Returns the byte-swapped value of a given 32-bit value.
89381 +
89382 + @Param[in] val - The 32-bit value.
89383 +
89384 + @Return The byte-swapped value of the parameter.
89385 +*//***************************************************************************/
89386 +static __inline__ uint32_t SwapUint32(uint32_t val)
89387 +{
89388 + return (uint32_t)(((val & 0x000000FF) << 24) |
89389 + ((val & 0x0000FF00) << 8) |
89390 + ((val & 0x00FF0000) >> 8) |
89391 + ((val & 0xFF000000) >> 24));
89392 +}
89393 +
89394 +/**************************************************************************//**
89395 + @Function SwapUint64
89396 +
89397 + @Description Returns the byte-swapped value of a given 64-bit value.
89398 +
89399 + @Param[in] val - The 64-bit value.
89400 +
89401 + @Return The byte-swapped value of the parameter.
89402 +*//***************************************************************************/
89403 +static __inline__ uint64_t SwapUint64(uint64_t val)
89404 +{
89405 + return (uint64_t)(((val & 0x00000000000000FFULL) << 56) |
89406 + ((val & 0x000000000000FF00ULL) << 40) |
89407 + ((val & 0x0000000000FF0000ULL) << 24) |
89408 + ((val & 0x00000000FF000000ULL) << 8) |
89409 + ((val & 0x000000FF00000000ULL) >> 8) |
89410 + ((val & 0x0000FF0000000000ULL) >> 24) |
89411 + ((val & 0x00FF000000000000ULL) >> 40) |
89412 + ((val & 0xFF00000000000000ULL) >> 56));
89413 +}
89414 +
89415 +/* @} */
89416 +
89417 +/**************************************************************************//**
89418 + @Collection In-place Byte-Swap-And-Set Routines
89419 +
89420 + Routines for swapping the byte order of a given variable and
89421 + setting the swapped value back to the same variable.
89422 + @{
89423 +*//***************************************************************************/
89424 +
89425 +/**************************************************************************//**
89426 + @Function SwapUint16P
89427 +
89428 + @Description Swaps the byte order of a given 16-bit variable.
89429 +
89430 + @Param[in] p_Val - Pointer to the 16-bit variable.
89431 +
89432 + @Return None.
89433 +*//***************************************************************************/
89434 +static __inline__ void SwapUint16P(uint16_t *p_Val)
89435 +{
89436 + *p_Val = SwapUint16(*p_Val);
89437 +}
89438 +
89439 +/**************************************************************************//**
89440 + @Function SwapUint32P
89441 +
89442 + @Description Swaps the byte order of a given 32-bit variable.
89443 +
89444 + @Param[in] p_Val - Pointer to the 32-bit variable.
89445 +
89446 + @Return None.
89447 +*//***************************************************************************/
89448 +static __inline__ void SwapUint32P(uint32_t *p_Val)
89449 +{
89450 + *p_Val = SwapUint32(*p_Val);
89451 +}
89452 +
89453 +/**************************************************************************//**
89454 + @Function SwapUint64P
89455 +
89456 + @Description Swaps the byte order of a given 64-bit variable.
89457 +
89458 + @Param[in] p_Val - Pointer to the 64-bit variable.
89459 +
89460 + @Return None.
89461 +*//***************************************************************************/
89462 +static __inline__ void SwapUint64P(uint64_t *p_Val)
89463 +{
89464 + *p_Val = SwapUint64(*p_Val);
89465 +}
89466 +
89467 +/* @} */
89468 +
89469 +
89470 +/**************************************************************************//**
89471 + @Collection Little-Endian Conversion Macros
89472 +
89473 + These macros convert given parameters to or from Little-Endian
89474 + format. Use these macros when you want to read or write a specific
89475 + Little-Endian value in memory, without a-priori knowing the CPU
89476 + byte order.
89477 +
89478 + These macros use the byte-swap routines. For conversion of
89479 + constants in initialization structures, you may use the CONST
89480 + versions of these macros (see below), which are using the
89481 + byte-swap macros instead.
89482 + @{
89483 +*//***************************************************************************/
89484 +
89485 +/**************************************************************************//**
89486 + @Description Converts a given 16-bit value from CPU byte order to
89487 + Little-Endian byte order.
89488 +
89489 + @Param[in] val - The 16-bit value to convert.
89490 +
89491 + @Return The converted value.
89492 +
89493 + @hideinitializer
89494 +*//***************************************************************************/
89495 +#define CPU_TO_LE16(val) SwapUint16(val)
89496 +
89497 +/**************************************************************************//**
89498 + @Description Converts a given 32-bit value from CPU byte order to
89499 + Little-Endian byte order.
89500 +
89501 + @Param[in] val - The 32-bit value to convert.
89502 +
89503 + @Return The converted value.
89504 +
89505 + @hideinitializer
89506 +*//***************************************************************************/
89507 +#define CPU_TO_LE32(val) SwapUint32(val)
89508 +
89509 +/**************************************************************************//**
89510 + @Description Converts a given 64-bit value from CPU byte order to
89511 + Little-Endian byte order.
89512 +
89513 + @Param[in] val - The 64-bit value to convert.
89514 +
89515 + @Return The converted value.
89516 +
89517 + @hideinitializer
89518 +*//***************************************************************************/
89519 +#define CPU_TO_LE64(val) SwapUint64(val)
89520 +
89521 +
89522 +/**************************************************************************//**
89523 + @Description Converts a given 16-bit value from Little-Endian byte order to
89524 + CPU byte order.
89525 +
89526 + @Param[in] val - The 16-bit value to convert.
89527 +
89528 + @Return The converted value.
89529 +
89530 + @hideinitializer
89531 +*//***************************************************************************/
89532 +#define LE16_TO_CPU(val) CPU_TO_LE16(val)
89533 +
89534 +/**************************************************************************//**
89535 + @Description Converts a given 32-bit value from Little-Endian byte order to
89536 + CPU byte order.
89537 +
89538 + @Param[in] val - The 32-bit value to convert.
89539 +
89540 + @Return The converted value.
89541 +
89542 + @hideinitializer
89543 +*//***************************************************************************/
89544 +#define LE32_TO_CPU(val) CPU_TO_LE32(val)
89545 +
89546 +/**************************************************************************//**
89547 + @Description Converts a given 64-bit value from Little-Endian byte order to
89548 + CPU byte order.
89549 +
89550 + @Param[in] val - The 64-bit value to convert.
89551 +
89552 + @Return The converted value.
89553 +
89554 + @hideinitializer
89555 +*//***************************************************************************/
89556 +#define LE64_TO_CPU(val) CPU_TO_LE64(val)
89557 +
89558 +/* @} */
89559 +
89560 +/**************************************************************************//**
89561 + @Collection Little-Endian Constant Conversion Macros
89562 +
89563 + These macros convert given constants to or from Little-Endian
89564 + format. Use these macros when you want to read or write a specific
89565 + Little-Endian constant in memory, without a-priori knowing the
89566 + CPU byte order.
89567 +
89568 + These macros use the byte-swap macros, therefore can be used for
89569 + conversion of constants in initialization structures.
89570 +
89571 + @Cautions The parameters of these macros are evaluated multiple times.
89572 + For non-constant expressions, use the non-CONST macro versions.
89573 +
89574 + @{
89575 +*//***************************************************************************/
89576 +
89577 +/**************************************************************************//**
89578 + @Description Converts a given 16-bit constant from CPU byte order to
89579 + Little-Endian byte order.
89580 +
89581 + @Param[in] val - The 16-bit value to convert.
89582 +
89583 + @Return The converted value.
89584 +
89585 + @hideinitializer
89586 +*//***************************************************************************/
89587 +#define CONST_CPU_TO_LE16(val) SWAP_UINT16(val)
89588 +
89589 +/**************************************************************************//**
89590 + @Description Converts a given 32-bit constant from CPU byte order to
89591 + Little-Endian byte order.
89592 +
89593 + @Param[in] val - The 32-bit value to convert.
89594 +
89595 + @Return The converted value.
89596 +
89597 + @hideinitializer
89598 +*//***************************************************************************/
89599 +#define CONST_CPU_TO_LE32(val) SWAP_UINT32(val)
89600 +
89601 +/**************************************************************************//**
89602 + @Description Converts a given 64-bit constant from CPU byte order to
89603 + Little-Endian byte order.
89604 +
89605 + @Param[in] val - The 64-bit value to convert.
89606 +
89607 + @Return The converted value.
89608 +
89609 + @hideinitializer
89610 +*//***************************************************************************/
89611 +#define CONST_CPU_TO_LE64(val) SWAP_UINT64(val)
89612 +
89613 +
89614 +/**************************************************************************//**
89615 + @Description Converts a given 16-bit constant from Little-Endian byte order
89616 + to CPU byte order.
89617 +
89618 + @Param[in] val - The 16-bit value to convert.
89619 +
89620 + @Return The converted value.
89621 +
89622 + @hideinitializer
89623 +*//***************************************************************************/
89624 +#define CONST_LE16_TO_CPU(val) CONST_CPU_TO_LE16(val)
89625 +
89626 +/**************************************************************************//**
89627 + @Description Converts a given 32-bit constant from Little-Endian byte order
89628 + to CPU byte order.
89629 +
89630 + @Param[in] val - The 32-bit value to convert.
89631 +
89632 + @Return The converted value.
89633 +
89634 + @hideinitializer
89635 +*//***************************************************************************/
89636 +#define CONST_LE32_TO_CPU(val) CONST_CPU_TO_LE32(val)
89637 +
89638 +/**************************************************************************//**
89639 + @Description Converts a given 64-bit constant from Little-Endian byte order
89640 + to CPU byte order.
89641 +
89642 + @Param[in] val - The 64-bit value to convert.
89643 +
89644 + @Return The converted value.
89645 +
89646 + @hideinitializer
89647 +*//***************************************************************************/
89648 +#define CONST_LE64_TO_CPU(val) CONST_CPU_TO_LE64(val)
89649 +
89650 +/* @} */
89651 +
89652 +
89653 +/** @} */ /* end of endian_id group */
89654 +/** @} */ /* end of gen_id group */
89655 +
89656 +
89657 +#endif /* __ENDIAN_EXT_H */
89658 +
89659 --- /dev/null
89660 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
89661 @@ -0,0 +1,205 @@
89662 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
89663 + * All rights reserved.
89664 + *
89665 + * Redistribution and use in source and binary forms, with or without
89666 + * modification, are permitted provided that the following conditions are met:
89667 + * * Redistributions of source code must retain the above copyright
89668 + * notice, this list of conditions and the following disclaimer.
89669 + * * Redistributions in binary form must reproduce the above copyright
89670 + * notice, this list of conditions and the following disclaimer in the
89671 + * documentation and/or other materials provided with the distribution.
89672 + * * Neither the name of Freescale Semiconductor nor the
89673 + * names of its contributors may be used to endorse or promote products
89674 + * derived from this software without specific prior written permission.
89675 + *
89676 + *
89677 + * ALTERNATIVELY, this software may be distributed under the terms of the
89678 + * GNU General Public License ("GPL") as published by the Free Software
89679 + * Foundation, either version 2 of that License or (at your option) any
89680 + * later version.
89681 + *
89682 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89683 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89684 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89685 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89686 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89687 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89688 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89689 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89690 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89691 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89692 + */
89693 +
89694 +
89695 +/**************************************************************************//**
89696 + @File enet_ext.h
89697 +
89698 + @Description Ethernet generic definitions and enums.
89699 +*//***************************************************************************/
89700 +
89701 +#ifndef __ENET_EXT_H
89702 +#define __ENET_EXT_H
89703 +
89704 +#include "fsl_enet.h"
89705 +
89706 +#define ENET_NUM_OCTETS_PER_ADDRESS 6 /**< Number of octets (8-bit bytes) in an ethernet address */
89707 +#define ENET_GROUP_ADDR 0x01 /**< Group address mask for ethernet addresses */
89708 +
89709 +
89710 +/**************************************************************************//**
89711 + @Description Ethernet Address
89712 +*//***************************************************************************/
89713 +typedef uint8_t t_EnetAddr[ENET_NUM_OCTETS_PER_ADDRESS];
89714 +
89715 +/**************************************************************************//**
89716 + @Description Ethernet Address Type.
89717 +*//***************************************************************************/
89718 +typedef enum e_EnetAddrType
89719 +{
89720 + e_ENET_ADDR_TYPE_INDIVIDUAL, /**< Individual (unicast) address */
89721 + e_ENET_ADDR_TYPE_GROUP, /**< Group (multicast) address */
89722 + e_ENET_ADDR_TYPE_BROADCAST /**< Broadcast address */
89723 +} e_EnetAddrType;
89724 +
89725 +/**************************************************************************//**
89726 + @Description Ethernet MAC-PHY Interface
89727 +*//***************************************************************************/
89728 +typedef enum e_EnetInterface
89729 +{
89730 + e_ENET_IF_MII = E_ENET_IF_MII, /**< MII interface */
89731 + e_ENET_IF_RMII = E_ENET_IF_RMII, /**< RMII interface */
89732 + e_ENET_IF_SMII = E_ENET_IF_SMII, /**< SMII interface */
89733 + e_ENET_IF_GMII = E_ENET_IF_GMII, /**< GMII interface */
89734 + e_ENET_IF_RGMII = E_ENET_IF_RGMII, /**< RGMII interface */
89735 + e_ENET_IF_TBI = E_ENET_IF_TBI, /**< TBI interface */
89736 + e_ENET_IF_RTBI = E_ENET_IF_RTBI, /**< RTBI interface */
89737 + e_ENET_IF_SGMII = E_ENET_IF_SGMII, /**< SGMII interface */
89738 + e_ENET_IF_XGMII = E_ENET_IF_XGMII, /**< XGMII interface */
89739 + e_ENET_IF_QSGMII= E_ENET_IF_QSGMII, /**< QSGMII interface */
89740 + e_ENET_IF_XFI = E_ENET_IF_XFI /**< XFI interface */
89741 +} e_EnetInterface;
89742 +
89743 +#define ENET_IF_SGMII_BASEX 0x80000000 /**< SGMII/QSGII interface with 1000BaseX
89744 + auto-negotiation between MAC and phy
89745 + or backplane;
89746 + Note: 1000BaseX auto-negotiation relates
89747 + only to interface between MAC and phy/backplane,
89748 + SGMII phy can still synchronize with far-end phy
89749 + at 10Mbps, 100Mbps or 1000Mbps */
89750 +
89751 +/**************************************************************************//**
89752 + @Description Ethernet Duplex Mode
89753 +*//***************************************************************************/
89754 +typedef enum e_EnetDuplexMode
89755 +{
89756 + e_ENET_HALF_DUPLEX, /**< Half-Duplex mode */
89757 + e_ENET_FULL_DUPLEX /**< Full-Duplex mode */
89758 +} e_EnetDuplexMode;
89759 +
89760 +/**************************************************************************//**
89761 + @Description Ethernet Speed (nominal data rate)
89762 +*//***************************************************************************/
89763 +typedef enum e_EnetSpeed
89764 +{
89765 + e_ENET_SPEED_10 = E_ENET_SPEED_10, /**< 10 Mbps */
89766 + e_ENET_SPEED_100 = E_ENET_SPEED_100, /**< 100 Mbps */
89767 + e_ENET_SPEED_1000 = E_ENET_SPEED_1000, /**< 1000 Mbps = 1 Gbps */
89768 + e_ENET_SPEED_2500 = E_ENET_SPEED_2500, /**< 2500 Mbps = 2.5 Gbps */
89769 + e_ENET_SPEED_10000 = E_ENET_SPEED_10000 /**< 10000 Mbps = 10 Gbps */
89770 +} e_EnetSpeed;
89771 +
89772 +/**************************************************************************//**
89773 + @Description Ethernet mode (combination of MAC-PHY interface and speed)
89774 +*//***************************************************************************/
89775 +typedef enum e_EnetMode
89776 +{
89777 + e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */
89778 + e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */
89779 + e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */
89780 + e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */
89781 + e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */
89782 + e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */
89783 + e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */
89784 + e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */
89785 + e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */
89786 + e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */
89787 + e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */
89788 + e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */
89789 + e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */
89790 + e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10),
89791 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
89792 + SGMII phy according to Cisco SGMII specification */
89793 + e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100),
89794 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
89795 + SGMII phy according to Cisco SGMII specification */
89796 + e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000),
89797 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
89798 + SGMII phy according to Cisco SGMII specification */
89799 + e_ENET_MODE_SGMII_2500 = (e_ENET_IF_SGMII | e_ENET_SPEED_2500),
89800 + e_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_10),
89801 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
89802 + MAC and SGMII phy or backplane */
89803 + e_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_100),
89804 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
89805 + MAC and SGMII phy or backplane */
89806 + e_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_1000),
89807 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
89808 + MAC and SGMII phy or backplane */
89809 + e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
89810 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
89811 + QSGMII phy according to Cisco QSGMII specification */
89812 + e_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
89813 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
89814 + MAC and QSGMII phy or backplane */
89815 + e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */
89816 + e_ENET_MODE_XFI_10000 = (e_ENET_IF_XFI | e_ENET_SPEED_10000) /**< 10000 Mbps XFI */
89817 +} e_EnetMode;
89818 +
89819 +
89820 +#define IS_ENET_MODE_VALID(mode) \
89821 + (((mode) == e_ENET_MODE_MII_10 ) || \
89822 + ((mode) == e_ENET_MODE_MII_100 ) || \
89823 + ((mode) == e_ENET_MODE_RMII_10 ) || \
89824 + ((mode) == e_ENET_MODE_RMII_100 ) || \
89825 + ((mode) == e_ENET_MODE_SMII_10 ) || \
89826 + ((mode) == e_ENET_MODE_SMII_100 ) || \
89827 + ((mode) == e_ENET_MODE_GMII_1000 ) || \
89828 + ((mode) == e_ENET_MODE_RGMII_10 ) || \
89829 + ((mode) == e_ENET_MODE_RGMII_100 ) || \
89830 + ((mode) == e_ENET_MODE_RGMII_1000 ) || \
89831 + ((mode) == e_ENET_MODE_TBI_1000 ) || \
89832 + ((mode) == e_ENET_MODE_RTBI_1000 ) || \
89833 + ((mode) == e_ENET_MODE_SGMII_10 ) || \
89834 + ((mode) == e_ENET_MODE_SGMII_100 ) || \
89835 + ((mode) == e_ENET_MODE_SGMII_1000 ) || \
89836 + ((mode) == e_ENET_MODE_SGMII_BASEX_10 ) || \
89837 + ((mode) == e_ENET_MODE_SGMII_BASEX_100 ) || \
89838 + ((mode) == e_ENET_MODE_SGMII_BASEX_1000 ) || \
89839 + ((mode) == e_ENET_MODE_XGMII_10000) || \
89840 + ((mode) == e_ENET_MODE_QSGMII_1000) || \
89841 + ((mode) == e_ENET_MODE_QSGMII_BASEX_1000) || \
89842 + ((mode) == e_ENET_MODE_XFI_10000))
89843 +
89844 +
89845 +#define MAKE_ENET_MODE(_interface, _speed) (e_EnetMode)((_interface) | (_speed))
89846 +
89847 +#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0x0FFF0000)
89848 +#define ENET_SPEED_FROM_MODE(mode) (e_EnetSpeed)((mode) & 0x0000FFFF)
89849 +
89850 +#define ENET_ADDR_TO_UINT64(_enetAddr) \
89851 + (uint64_t)(((uint64_t)(_enetAddr)[0] << 40) | \
89852 + ((uint64_t)(_enetAddr)[1] << 32) | \
89853 + ((uint64_t)(_enetAddr)[2] << 24) | \
89854 + ((uint64_t)(_enetAddr)[3] << 16) | \
89855 + ((uint64_t)(_enetAddr)[4] << 8) | \
89856 + ((uint64_t)(_enetAddr)[5]))
89857 +
89858 +#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enetAddr) \
89859 + do { \
89860 + int i; \
89861 + for (i=0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
89862 + (_enetAddr)[i] = (uint8_t)((_addr64) >> ((5-i)*8)); \
89863 + } while (0)
89864 +
89865 +
89866 +#endif /* __ENET_EXT_H */
89867 --- /dev/null
89868 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
89869 @@ -0,0 +1,529 @@
89870 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
89871 + * All rights reserved.
89872 + *
89873 + * Redistribution and use in source and binary forms, with or without
89874 + * modification, are permitted provided that the following conditions are met:
89875 + * * Redistributions of source code must retain the above copyright
89876 + * notice, this list of conditions and the following disclaimer.
89877 + * * Redistributions in binary form must reproduce the above copyright
89878 + * notice, this list of conditions and the following disclaimer in the
89879 + * documentation and/or other materials provided with the distribution.
89880 + * * Neither the name of Freescale Semiconductor nor the
89881 + * names of its contributors may be used to endorse or promote products
89882 + * derived from this software without specific prior written permission.
89883 + *
89884 + *
89885 + * ALTERNATIVELY, this software may be distributed under the terms of the
89886 + * GNU General Public License ("GPL") as published by the Free Software
89887 + * Foundation, either version 2 of that License or (at your option) any
89888 + * later version.
89889 + *
89890 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89891 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89892 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89893 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89894 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89895 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89896 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89897 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89898 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89899 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89900 + */
89901 +
89902 +
89903 +/**************************************************************************//**
89904 + @File error_ext.h
89905 +
89906 + @Description Error definitions.
89907 +*//***************************************************************************/
89908 +
89909 +#ifndef __ERROR_EXT_H
89910 +#define __ERROR_EXT_H
89911 +
89912 +#if !defined(NCSW_LINUX)
89913 +#include <errno.h>
89914 +#endif
89915 +
89916 +#include "std_ext.h"
89917 +#include "xx_ext.h"
89918 +#include "core_ext.h"
89919 +
89920 +
89921 +
89922 +
89923 +/**************************************************************************//**
89924 + @Group gen_id General Drivers Utilities
89925 +
89926 + @Description External routines.
89927 +
89928 + @{
89929 +*//***************************************************************************/
89930 +
89931 +/**************************************************************************//**
89932 + @Group gen_error_id Errors, Events and Debug
89933 +
89934 + @Description External routines.
89935 +
89936 + @{
89937 +*//***************************************************************************/
89938 +
89939 +/******************************************************************************
89940 +The scheme below provides the bits description for error codes:
89941 +
89942 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
89943 +| Reserved (should be zero) | Module ID |
89944 +
89945 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
89946 +| Error Type |
89947 +******************************************************************************/
89948 +
89949 +#define ERROR_CODE(_err) ((((uint32_t)_err) & 0x0000FFFF) | __ERR_MODULE__)
89950 +
89951 +#define GET_ERROR_TYPE(_errcode) ((_errcode) & 0x0000FFFF)
89952 + /**< Extract module code from error code (#t_Error) */
89953 +
89954 +#define GET_ERROR_MODULE(_errcode) ((_errcode) & 0x00FF0000)
89955 + /**< Extract error type (#e_ErrorType) from
89956 + error code (#t_Error) */
89957 +
89958 +
89959 +/**************************************************************************//**
89960 + @Description Error Type Enumeration
89961 +*//***************************************************************************/
89962 +typedef enum e_ErrorType /* Comments / Associated Message Strings */
89963 +{ /* ------------------------------------------------------------ */
89964 + E_OK = 0 /* Never use "RETURN_ERROR" with E_OK; Use "return E_OK;" */
89965 + ,E_WRITE_FAILED = EIO /**< Write access failed on memory/device. */
89966 + /* String: none, or device name. */
89967 + ,E_NO_DEVICE = ENXIO /**< The associated device is not initialized. */
89968 + /* String: none. */
89969 + ,E_NOT_AVAILABLE = EAGAIN
89970 + /**< Resource is unavailable. */
89971 + /* String: none, unless the operation is not the main goal
89972 + of the function (in this case add resource description). */
89973 + ,E_NO_MEMORY = ENOMEM /**< External memory allocation failed. */
89974 + /* String: description of item for which allocation failed. */
89975 + ,E_INVALID_ADDRESS = EFAULT
89976 + /**< Invalid address. */
89977 + /* String: description of the specific violation. */
89978 + ,E_BUSY = EBUSY /**< Resource or module is busy. */
89979 + /* String: none, unless the operation is not the main goal
89980 + of the function (in this case add resource description). */
89981 + ,E_ALREADY_EXISTS = EEXIST
89982 + /**< Requested resource or item already exists. */
89983 + /* Use when resource duplication or sharing are not allowed.
89984 + String: none, unless the operation is not the main goal
89985 + of the function (in this case add item description). */
89986 + ,E_INVALID_OPERATION = ENODEV
89987 + /**< The operation/command is invalid (unrecognized). */
89988 + /* String: none. */
89989 + ,E_INVALID_VALUE = EDOM /**< Invalid value. */
89990 + /* Use for non-enumeration parameters, and
89991 + only when other error types are not suitable.
89992 + String: parameter description + "(should be <attribute>)",
89993 + e.g: "Maximum Rx buffer length (should be divisible by 8)",
89994 + "Channel number (should be even)". */
89995 + ,E_NOT_IN_RANGE = ERANGE/**< Parameter value is out of range. */
89996 + /* Don't use this error for enumeration parameters.
89997 + String: parameter description + "(should be %d-%d)",
89998 + e.g: "Number of pad characters (should be 0-15)". */
89999 + ,E_NOT_SUPPORTED = ENOSYS
90000 + /**< The function is not supported or not implemented. */
90001 + /* String: none. */
90002 + ,E_INVALID_STATE /**< The operation is not allowed in current module state. */
90003 + /* String: none. */
90004 + ,E_INVALID_HANDLE /**< Invalid handle of module or object. */
90005 + /* String: none, unless the function takes in more than one
90006 + handle (in this case add the handle description) */
90007 + ,E_INVALID_ID /**< Invalid module ID (usually enumeration or index). */
90008 + /* String: none, unless the function takes in more than one
90009 + ID (in this case add the ID description) */
90010 + ,E_NULL_POINTER /**< Unexpected NULL pointer. */
90011 + /* String: pointer description. */
90012 + ,E_INVALID_SELECTION /**< Invalid selection or mode. */
90013 + /* Use for enumeration values, only when other error types
90014 + are not suitable.
90015 + String: parameter description. */
90016 + ,E_INVALID_COMM_MODE /**< Invalid communication mode. */
90017 + /* String: none, unless the function takes in more than one
90018 + communication mode indications (in this case add
90019 + parameter description). */
90020 + ,E_INVALID_MEMORY_TYPE /**< Invalid memory type. */
90021 + /* String: none, unless the function takes in more than one
90022 + memory types (in this case add memory description,
90023 + e.g: "Data memory", "Buffer descriptors memory"). */
90024 + ,E_INVALID_CLOCK /**< Invalid clock. */
90025 + /* String: none, unless the function takes in more than one
90026 + clocks (in this case add clock description,
90027 + e.g: "Rx clock", "Tx clock"). */
90028 + ,E_CONFLICT /**< Some setting conflicts with another setting. */
90029 + /* String: description of the conflicting settings. */
90030 + ,E_NOT_ALIGNED /**< Non-aligned address. */
90031 + /* String: parameter description + "(should be %d-bytes aligned)",
90032 + e.g: "Rx data buffer (should be 32-bytes aligned)". */
90033 + ,E_NOT_FOUND /**< Requested resource or item was not found. */
90034 + /* Use only when the resource/item is uniquely identified.
90035 + String: none, unless the operation is not the main goal
90036 + of the function (in this case add item description). */
90037 + ,E_FULL /**< Resource is full. */
90038 + /* String: none, unless the operation is not the main goal
90039 + of the function (in this case add resource description). */
90040 + ,E_EMPTY /**< Resource is empty. */
90041 + /* String: none, unless the operation is not the main goal
90042 + of the function (in this case add resource description). */
90043 + ,E_ALREADY_FREE /**< Specified resource or item is already free or deleted. */
90044 + /* String: none, unless the operation is not the main goal
90045 + of the function (in this case add item description). */
90046 + ,E_READ_FAILED /**< Read access failed on memory/device. */
90047 + /* String: none, or device name. */
90048 + ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */
90049 + /* String: none. */
90050 + ,E_SEND_FAILED /**< Send operation failed on device. */
90051 + /* String: none, or device name. */
90052 + ,E_RECEIVE_FAILED /**< Receive operation failed on device. */
90053 + /* String: none, or device name. */
90054 + ,E_TIMEOUT/* = ETIMEDOUT*/ /**< The operation timed out. */
90055 + /* String: none. */
90056 +
90057 + ,E_DUMMY_LAST /* NEVER USED */
90058 +
90059 +} e_ErrorType;
90060 +
90061 +/**************************************************************************//**
90062 + @Description Event Type Enumeration
90063 +*//***************************************************************************/
90064 +typedef enum e_Event /* Comments / Associated Flags and Message Strings */
90065 +{ /* ------------------------------------------------------------ */
90066 + EV_NO_EVENT = 0 /**< No event; Never used. */
90067 +
90068 + ,EV_RX_DISCARD /**< Received packet discarded (by the driver, and only for
90069 + complete packets);
90070 + Flags: error flags in case of error, zero otherwise. */
90071 + /* String: reason for discard, e.g: "Error in frame",
90072 + "Disordered frame", "Incomplete frame", "No frame object". */
90073 + ,EV_RX_ERROR /**< Receive error (by hardware/firmware);
90074 + Flags: usually status flags from the buffer descriptor. */
90075 + /* String: none. */
90076 + ,EV_TX_ERROR /**< Transmit error (by hardware/firmware);
90077 + Flags: usually status flags from the buffer descriptor. */
90078 + /* String: none. */
90079 + ,EV_NO_BUFFERS /**< System ran out of buffer objects;
90080 + Flags: zero. */
90081 + /* String: none. */
90082 + ,EV_NO_MB_FRAMES /**< System ran out of multi-buffer frame objects;
90083 + Flags: zero. */
90084 + /* String: none. */
90085 + ,EV_NO_SB_FRAMES /**< System ran out of single-buffer frame objects;
90086 + Flags: zero. */
90087 + /* String: none. */
90088 + ,EV_TX_QUEUE_FULL /**< Transmit queue is full;
90089 + Flags: zero. */
90090 + /* String: none. */
90091 + ,EV_RX_QUEUE_FULL /**< Receive queue is full;
90092 + Flags: zero. */
90093 + /* String: none. */
90094 + ,EV_INTR_QUEUE_FULL /**< Interrupt queue overflow;
90095 + Flags: zero. */
90096 + /* String: none. */
90097 + ,EV_NO_DATA_BUFFER /**< Data buffer allocation (from higher layer) failed;
90098 + Flags: zero. */
90099 + /* String: none. */
90100 + ,EV_OBJ_POOL_EMPTY /**< Objects pool is empty;
90101 + Flags: zero. */
90102 + /* String: object description (name). */
90103 + ,EV_BUS_ERROR /**< Illegal access on bus;
90104 + Flags: the address (if available) or bus identifier */
90105 + /* String: bus/address/module description. */
90106 + ,EV_PTP_TXTS_QUEUE_FULL /**< PTP Tx timestamps queue is full;
90107 + Flags: zero. */
90108 + /* String: none. */
90109 + ,EV_PTP_RXTS_QUEUE_FULL /**< PTP Rx timestamps queue is full;
90110 + Flags: zero. */
90111 + /* String: none. */
90112 + ,EV_DUMMY_LAST
90113 +
90114 +} e_Event;
90115 +
90116 +
90117 +/**************************************************************************//**
90118 + @Collection Debug Levels for Errors and Events
90119 +
90120 + The level description refers to errors only.
90121 + For events, classification is done by the user.
90122 +
90123 + The TRACE, INFO and WARNING levels are allowed only when using
90124 + the DBG macro, and are not allowed when using the error macros
90125 + (RETURN_ERROR or REPORT_ERROR).
90126 + @{
90127 +*//***************************************************************************/
90128 +#define REPORT_LEVEL_CRITICAL 1 /**< Crasher: Incorrect flow, NULL pointers/handles. */
90129 +#define REPORT_LEVEL_MAJOR 2 /**< Cannot proceed: Invalid operation, parameters or
90130 + configuration. */
90131 +#define REPORT_LEVEL_MINOR 3 /**< Recoverable problem: a repeating call with the same
90132 + parameters may be successful. */
90133 +#define REPORT_LEVEL_WARNING 4 /**< Something is not exactly right, yet it is not an error. */
90134 +#define REPORT_LEVEL_INFO 5 /**< Messages which may be of interest to user/programmer. */
90135 +#define REPORT_LEVEL_TRACE 6 /**< Program flow messages. */
90136 +
90137 +#define EVENT_DISABLED 0xFF /**< Disabled event (not reported at all) */
90138 +
90139 +/* @} */
90140 +
90141 +
90142 +
90143 +#define NO_MSG ("")
90144 +
90145 +#ifndef DEBUG_GLOBAL_LEVEL
90146 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
90147 +#endif /* DEBUG_GLOBAL_LEVEL */
90148 +
90149 +#ifndef ERROR_GLOBAL_LEVEL
90150 +#define ERROR_GLOBAL_LEVEL DEBUG_GLOBAL_LEVEL
90151 +#endif /* ERROR_GLOBAL_LEVEL */
90152 +
90153 +#ifndef EVENT_GLOBAL_LEVEL
90154 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
90155 +#endif /* EVENT_GLOBAL_LEVEL */
90156 +
90157 +#ifdef EVENT_LOCAL_LEVEL
90158 +#define EVENT_DYNAMIC_LEVEL EVENT_LOCAL_LEVEL
90159 +#else
90160 +#define EVENT_DYNAMIC_LEVEL EVENT_GLOBAL_LEVEL
90161 +#endif /* EVENT_LOCAL_LEVEL */
90162 +
90163 +
90164 +#ifndef DEBUG_DYNAMIC_LEVEL
90165 +#define DEBUG_USING_STATIC_LEVEL
90166 +
90167 +#ifdef DEBUG_STATIC_LEVEL
90168 +#define DEBUG_DYNAMIC_LEVEL DEBUG_STATIC_LEVEL
90169 +#else
90170 +#define DEBUG_DYNAMIC_LEVEL DEBUG_GLOBAL_LEVEL
90171 +#endif /* DEBUG_STATIC_LEVEL */
90172 +
90173 +#else /* DEBUG_DYNAMIC_LEVEL */
90174 +#ifdef DEBUG_STATIC_LEVEL
90175 +#error "Please use either DEBUG_STATIC_LEVEL or DEBUG_DYNAMIC_LEVEL (not both)"
90176 +#else
90177 +int DEBUG_DYNAMIC_LEVEL = DEBUG_GLOBAL_LEVEL;
90178 +#endif /* DEBUG_STATIC_LEVEL */
90179 +#endif /* !DEBUG_DYNAMIC_LEVEL */
90180 +
90181 +
90182 +#ifndef ERROR_DYNAMIC_LEVEL
90183 +
90184 +#ifdef ERROR_STATIC_LEVEL
90185 +#define ERROR_DYNAMIC_LEVEL ERROR_STATIC_LEVEL
90186 +#else
90187 +#define ERROR_DYNAMIC_LEVEL ERROR_GLOBAL_LEVEL
90188 +#endif /* ERROR_STATIC_LEVEL */
90189 +
90190 +#else /* ERROR_DYNAMIC_LEVEL */
90191 +#ifdef ERROR_STATIC_LEVEL
90192 +#error "Please use either ERROR_STATIC_LEVEL or ERROR_DYNAMIC_LEVEL (not both)"
90193 +#else
90194 +int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL;
90195 +#endif /* ERROR_STATIC_LEVEL */
90196 +#endif /* !ERROR_DYNAMIC_LEVEL */
90197 +
90198 +#define PRINT_FORMAT "[CPU%02d, %s:%d %s]"
90199 +#define PRINT_FMT_PARAMS raw_smp_processor_id(), __FILE__, __LINE__, __FUNCTION__
90200 +
90201 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
90202 +/* No debug/error/event messages at all */
90203 +#define DBG(_level, _vmsg)
90204 +
90205 +#define REPORT_ERROR(_level, _err, _vmsg)
90206 +
90207 +#define RETURN_ERROR(_level, _err, _vmsg) \
90208 + return ERROR_CODE(_err)
90209 +
90210 +#if (REPORT_EVENTS > 0)
90211 +
90212 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90213 + do { \
90214 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90215 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90216 + } \
90217 + } while (0)
90218 +
90219 +#else
90220 +
90221 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90222 +
90223 +#endif /* (REPORT_EVENTS > 0) */
90224 +
90225 +
90226 +#else /* DEBUG_ERRORS > 0 */
90227 +
90228 +extern const char *dbgLevelStrings[];
90229 +extern const char *moduleStrings[];
90230 +#if (REPORT_EVENTS > 0)
90231 +extern const char *eventStrings[];
90232 +#endif /* (REPORT_EVENTS > 0) */
90233 +
90234 +char * ErrTypeStrings (e_ErrorType err);
90235 +
90236 +
90237 +#if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING))
90238 +/* No need for DBG macro - debug level is higher anyway */
90239 +#define DBG(_level, _vmsg)
90240 +#else
90241 +#define DBG(_level, _vmsg) \
90242 + do { \
90243 + if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \
90244 + XX_Print("> %s (%s) " PRINT_FORMAT ": ", \
90245 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90246 + moduleStrings[__ERR_MODULE__ >> 16], \
90247 + PRINT_FMT_PARAMS); \
90248 + XX_Print _vmsg; \
90249 + XX_Print("\r\n"); \
90250 + } \
90251 + } while (0)
90252 +#endif /* (defined(DEBUG_USING_STATIC_LEVEL) && (DEBUG_DYNAMIC_LEVEL < WARNING)) */
90253 +
90254 +
90255 +#define REPORT_ERROR(_level, _err, _vmsg) \
90256 + do { \
90257 + if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \
90258 + XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \
90259 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90260 + moduleStrings[__ERR_MODULE__ >> 16], \
90261 + PRINT_FMT_PARAMS, \
90262 + ErrTypeStrings((e_ErrorType)GET_ERROR_TYPE(_err))); \
90263 + XX_Print _vmsg; \
90264 + XX_Print("\r\n"); \
90265 + } \
90266 + } while (0)
90267 +
90268 +
90269 +#define RETURN_ERROR(_level, _err, _vmsg) \
90270 + do { \
90271 + REPORT_ERROR(_level, (_err), _vmsg); \
90272 + return ERROR_CODE(_err); \
90273 + } while (0)
90274 +
90275 +
90276 +#if (REPORT_EVENTS > 0)
90277 +
90278 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90279 + do { \
90280 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90281 + XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \
90282 + dbgLevelStrings[_ev##_LEVEL - 1], \
90283 + moduleStrings[__ERR_MODULE__ >> 16], \
90284 + PRINT_FMT_PARAMS, \
90285 + eventStrings[((_ev) - EV_NO_EVENT - 1)], \
90286 + (uint16_t)(_flg)); \
90287 + XX_Print _vmsg; \
90288 + XX_Print("\r\n"); \
90289 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90290 + } \
90291 + } while (0)
90292 +
90293 +#else /* not REPORT_EVENTS */
90294 +
90295 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90296 +
90297 +#endif /* (REPORT_EVENTS > 0) */
90298 +
90299 +#endif /* (DEBUG_ERRORS > 0) */
90300 +
90301 +
90302 +/**************************************************************************//**
90303 + @Function ASSERT_COND
90304 +
90305 + @Description Assertion macro.
90306 +
90307 + @Param[in] _cond - The condition being checked, in positive form;
90308 + Failure of the condition triggers the assert.
90309 +*//***************************************************************************/
90310 +#ifdef DISABLE_ASSERTIONS
90311 +#define ASSERT_COND(_cond)
90312 +#else
90313 +#define ASSERT_COND(_cond) \
90314 + do { \
90315 + if (!(_cond)) { \
90316 + XX_Print("*** ASSERT_COND failed " PRINT_FORMAT "\r\n", \
90317 + PRINT_FMT_PARAMS); \
90318 + XX_Exit(1); \
90319 + } \
90320 + } while (0)
90321 +#endif /* DISABLE_ASSERTIONS */
90322 +
90323 +
90324 +#ifdef DISABLE_INIT_PARAMETERS_CHECK
90325 +
90326 +#define CHECK_INIT_PARAMETERS(handle, f_check)
90327 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval)
90328 +
90329 +#else
90330 +
90331 +#define CHECK_INIT_PARAMETERS(handle, f_check) \
90332 + do { \
90333 + t_Error err = f_check(handle); \
90334 + if (err != E_OK) { \
90335 + RETURN_ERROR(MAJOR, err, NO_MSG); \
90336 + } \
90337 + } while (0)
90338 +
90339 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) \
90340 + do { \
90341 + t_Error err = f_check(handle); \
90342 + if (err != E_OK) { \
90343 + REPORT_ERROR(MAJOR, err, NO_MSG); \
90344 + return (retval); \
90345 + } \
90346 + } while (0)
90347 +
90348 +#endif /* DISABLE_INIT_PARAMETERS_CHECK */
90349 +
90350 +#ifdef DISABLE_SANITY_CHECKS
90351 +
90352 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err)
90353 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval)
90354 +#define SANITY_CHECK_RETURN(_cond, _err)
90355 +#define SANITY_CHECK_EXIT(_cond, _err)
90356 +
90357 +#else /* DISABLE_SANITY_CHECKS */
90358 +
90359 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err) \
90360 + do { \
90361 + if (!(_cond)) { \
90362 + RETURN_ERROR(CRITICAL, (_err), NO_MSG); \
90363 + } \
90364 + } while (0)
90365 +
90366 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) \
90367 + do { \
90368 + if (!(_cond)) { \
90369 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90370 + return (retval); \
90371 + } \
90372 + } while (0)
90373 +
90374 +#define SANITY_CHECK_RETURN(_cond, _err) \
90375 + do { \
90376 + if (!(_cond)) { \
90377 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90378 + return; \
90379 + } \
90380 + } while (0)
90381 +
90382 +#define SANITY_CHECK_EXIT(_cond, _err) \
90383 + do { \
90384 + if (!(_cond)) { \
90385 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90386 + XX_Exit(1); \
90387 + } \
90388 + } while (0)
90389 +
90390 +#endif /* DISABLE_SANITY_CHECKS */
90391 +
90392 +/** @} */ /* end of Debug/error Utils group */
90393 +
90394 +/** @} */ /* end of General Utils group */
90395 +
90396 +#endif /* __ERROR_EXT_H */
90397 +
90398 +
90399 --- /dev/null
90400 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
90401 @@ -0,0 +1,358 @@
90402 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90403 + * All rights reserved.
90404 + *
90405 + * Redistribution and use in source and binary forms, with or without
90406 + * modification, are permitted provided that the following conditions are met:
90407 + * * Redistributions of source code must retain the above copyright
90408 + * notice, this list of conditions and the following disclaimer.
90409 + * * Redistributions in binary form must reproduce the above copyright
90410 + * notice, this list of conditions and the following disclaimer in the
90411 + * documentation and/or other materials provided with the distribution.
90412 + * * Neither the name of Freescale Semiconductor nor the
90413 + * names of its contributors may be used to endorse or promote products
90414 + * derived from this software without specific prior written permission.
90415 + *
90416 + *
90417 + * ALTERNATIVELY, this software may be distributed under the terms of the
90418 + * GNU General Public License ("GPL") as published by the Free Software
90419 + * Foundation, either version 2 of that License or (at your option) any
90420 + * later version.
90421 + *
90422 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90423 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90424 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90425 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90426 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90427 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90428 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90429 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90430 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90431 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90432 + */
90433 +
90434 +
90435 +/**************************************************************************//**
90436 +
90437 + @File list_ext.h
90438 +
90439 + @Description External prototypes for list.c
90440 +*//***************************************************************************/
90441 +
90442 +#ifndef __LIST_EXT_H
90443 +#define __LIST_EXT_H
90444 +
90445 +
90446 +#include "std_ext.h"
90447 +
90448 +
90449 +/**************************************************************************//**
90450 + @Group etc_id Utility Library Application Programming Interface
90451 +
90452 + @Description External routines.
90453 +
90454 + @{
90455 +*//***************************************************************************/
90456 +
90457 +/**************************************************************************//**
90458 + @Group list_id List
90459 +
90460 + @Description List module functions,definitions and enums.
90461 +
90462 + @{
90463 +*//***************************************************************************/
90464 +
90465 +/**************************************************************************//**
90466 + @Description List structure.
90467 +*//***************************************************************************/
90468 +typedef struct List
90469 +{
90470 + struct List *p_Next; /**< A pointer to the next list object */
90471 + struct List *p_Prev; /**< A pointer to the previous list object */
90472 +} t_List;
90473 +
90474 +
90475 +/**************************************************************************//**
90476 + @Function LIST_FIRST/LIST_LAST/LIST_NEXT/LIST_PREV
90477 +
90478 + @Description Macro to get first/last/next/previous entry in a list.
90479 +
90480 + @Param[in] p_List - A pointer to a list.
90481 +*//***************************************************************************/
90482 +#define LIST_FIRST(p_List) (p_List)->p_Next
90483 +#define LIST_LAST(p_List) (p_List)->p_Prev
90484 +#define LIST_NEXT LIST_FIRST
90485 +#define LIST_PREV LIST_LAST
90486 +
90487 +
90488 +/**************************************************************************//**
90489 + @Function LIST_INIT
90490 +
90491 + @Description Macro for initialization of a list struct.
90492 +
90493 + @Param[in] lst - The t_List object to initialize.
90494 +*//***************************************************************************/
90495 +#define LIST_INIT(lst) {&(lst), &(lst)}
90496 +
90497 +
90498 +/**************************************************************************//**
90499 + @Function LIST
90500 +
90501 + @Description Macro to declare of a list.
90502 +
90503 + @Param[in] listName - The list object name.
90504 +*//***************************************************************************/
90505 +#define LIST(listName) t_List listName = LIST_INIT(listName)
90506 +
90507 +
90508 +/**************************************************************************//**
90509 + @Function INIT_LIST
90510 +
90511 + @Description Macro to initialize a list pointer.
90512 +
90513 + @Param[in] p_List - The list pointer.
90514 +*//***************************************************************************/
90515 +#define INIT_LIST(p_List) LIST_FIRST(p_List) = LIST_LAST(p_List) = (p_List)
90516 +
90517 +
90518 +/**************************************************************************//**
90519 + @Function LIST_OBJECT
90520 +
90521 + @Description Macro to get the struct (object) for this entry.
90522 +
90523 + @Param[in] type - The type of the struct (object) this list is embedded in.
90524 + @Param[in] member - The name of the t_List object within the struct.
90525 +
90526 + @Return The structure pointer for this entry.
90527 +*//***************************************************************************/
90528 +#define MEMBER_OFFSET(type, member) (PTR_TO_UINT(&((type *)0)->member))
90529 +#define LIST_OBJECT(p_List, type, member) \
90530 + ((type *)((char *)(p_List)-MEMBER_OFFSET(type, member)))
90531 +
90532 +
90533 +/**************************************************************************//**
90534 + @Function LIST_FOR_EACH
90535 +
90536 + @Description Macro to iterate over a list.
90537 +
90538 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90539 + @Param[in] p_Head - A pointer to the head for your list pointer.
90540 +
90541 + @Cautions You can't delete items with this routine.
90542 + For deletion use LIST_FOR_EACH_SAFE().
90543 +*//***************************************************************************/
90544 +#define LIST_FOR_EACH(p_Pos, p_Head) \
90545 + for (p_Pos = LIST_FIRST(p_Head); p_Pos != (p_Head); p_Pos = LIST_NEXT(p_Pos))
90546 +
90547 +
90548 +/**************************************************************************//**
90549 + @Function LIST_FOR_EACH_SAFE
90550 +
90551 + @Description Macro to iterate over a list safe against removal of list entry.
90552 +
90553 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90554 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90555 + @Param[in] p_Head - A pointer to the head for your list pointer.
90556 +*//***************************************************************************/
90557 +#define LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \
90558 + for (p_Pos = LIST_FIRST(p_Head), p_Tmp = LIST_FIRST(p_Pos); \
90559 + p_Pos != (p_Head); \
90560 + p_Pos = p_Tmp, p_Tmp = LIST_NEXT(p_Pos))
90561 +
90562 +
90563 +/**************************************************************************//**
90564 + @Function LIST_FOR_EACH_OBJECT_SAFE
90565 +
90566 + @Description Macro to iterate over list of given type safely.
90567 +
90568 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90569 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90570 + @Param[in] type - The type of the struct this is embedded in.
90571 + @Param[in] p_Head - A pointer to the head for your list pointer.
90572 + @Param[in] member - The name of the list_struct within the struct.
90573 +
90574 + @Cautions You can't delete items with this routine.
90575 + For deletion use LIST_FOR_EACH_SAFE().
90576 +*//***************************************************************************/
90577 +#define LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \
90578 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member), \
90579 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member); \
90580 + &p_Pos->member != (p_Head); \
90581 + p_Pos = p_Tmp, \
90582 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member))
90583 +
90584 +/**************************************************************************//**
90585 + @Function LIST_FOR_EACH_OBJECT
90586 +
90587 + @Description Macro to iterate over list of given type.
90588 +
90589 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90590 + @Param[in] type - The type of the struct this is embedded in.
90591 + @Param[in] p_Head - A pointer to the head for your list pointer.
90592 + @Param[in] member - The name of the list_struct within the struct.
90593 +
90594 + @Cautions You can't delete items with this routine.
90595 + For deletion use LIST_FOR_EACH_SAFE().
90596 +*//***************************************************************************/
90597 +#define LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \
90598 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member); \
90599 + &p_Pos->member != (p_Head); \
90600 + p_Pos = LIST_OBJECT(LIST_FIRST(&(p_Pos->member)), type, member))
90601 +
90602 +
90603 +/**************************************************************************//**
90604 + @Function LIST_Add
90605 +
90606 + @Description Add a new entry to a list.
90607 +
90608 + Insert a new entry after the specified head.
90609 + This is good for implementing stacks.
90610 +
90611 + @Param[in] p_New - A pointer to a new list entry to be added.
90612 + @Param[in] p_Head - A pointer to a list head to add it after.
90613 +
90614 + @Return none.
90615 +*//***************************************************************************/
90616 +static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head)
90617 +{
90618 + LIST_PREV(LIST_NEXT(p_Head)) = p_New;
90619 + LIST_NEXT(p_New) = LIST_NEXT(p_Head);
90620 + LIST_PREV(p_New) = p_Head;
90621 + LIST_NEXT(p_Head) = p_New;
90622 +}
90623 +
90624 +
90625 +/**************************************************************************//**
90626 + @Function LIST_AddToTail
90627 +
90628 + @Description Add a new entry to a list.
90629 +
90630 + Insert a new entry before the specified head.
90631 + This is useful for implementing queues.
90632 +
90633 + @Param[in] p_New - A pointer to a new list entry to be added.
90634 + @Param[in] p_Head - A pointer to a list head to add it before.
90635 +
90636 + @Return none.
90637 +*//***************************************************************************/
90638 +static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head)
90639 +{
90640 + LIST_NEXT(LIST_PREV(p_Head)) = p_New;
90641 + LIST_PREV(p_New) = LIST_PREV(p_Head);
90642 + LIST_NEXT(p_New) = p_Head;
90643 + LIST_PREV(p_Head) = p_New;
90644 +}
90645 +
90646 +
90647 +/**************************************************************************//**
90648 + @Function LIST_Del
90649 +
90650 + @Description Deletes entry from a list.
90651 +
90652 + @Param[in] p_Entry - A pointer to the element to delete from the list.
90653 +
90654 + @Return none.
90655 +
90656 + @Cautions LIST_IsEmpty() on entry does not return true after this,
90657 + the entry is in an undefined state.
90658 +*//***************************************************************************/
90659 +static __inline__ void LIST_Del(t_List *p_Entry)
90660 +{
90661 + LIST_PREV(LIST_NEXT(p_Entry)) = LIST_PREV(p_Entry);
90662 + LIST_NEXT(LIST_PREV(p_Entry)) = LIST_NEXT(p_Entry);
90663 +}
90664 +
90665 +
90666 +/**************************************************************************//**
90667 + @Function LIST_DelAndInit
90668 +
90669 + @Description Deletes entry from list and reinitialize it.
90670 +
90671 + @Param[in] p_Entry - A pointer to the element to delete from the list.
90672 +
90673 + @Return none.
90674 +*//***************************************************************************/
90675 +static __inline__ void LIST_DelAndInit(t_List *p_Entry)
90676 +{
90677 + LIST_Del(p_Entry);
90678 + INIT_LIST(p_Entry);
90679 +}
90680 +
90681 +
90682 +/**************************************************************************//**
90683 + @Function LIST_Move
90684 +
90685 + @Description Delete from one list and add as another's head.
90686 +
90687 + @Param[in] p_Entry - A pointer to the list entry to move.
90688 + @Param[in] p_Head - A pointer to the list head that will precede our entry.
90689 +
90690 + @Return none.
90691 +*//***************************************************************************/
90692 +static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head)
90693 +{
90694 + LIST_Del(p_Entry);
90695 + LIST_Add(p_Entry, p_Head);
90696 +}
90697 +
90698 +
90699 +/**************************************************************************//**
90700 + @Function LIST_MoveToTail
90701 +
90702 + @Description Delete from one list and add as another's tail.
90703 +
90704 + @Param[in] p_Entry - A pointer to the entry to move.
90705 + @Param[in] p_Head - A pointer to the list head that will follow our entry.
90706 +
90707 + @Return none.
90708 +*//***************************************************************************/
90709 +static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head)
90710 +{
90711 + LIST_Del(p_Entry);
90712 + LIST_AddToTail(p_Entry, p_Head);
90713 +}
90714 +
90715 +
90716 +/**************************************************************************//**
90717 + @Function LIST_IsEmpty
90718 +
90719 + @Description Tests whether a list is empty.
90720 +
90721 + @Param[in] p_List - A pointer to the list to test.
90722 +
90723 + @Return 1 if the list is empty, 0 otherwise.
90724 +*//***************************************************************************/
90725 +static __inline__ int LIST_IsEmpty(t_List *p_List)
90726 +{
90727 + return (LIST_FIRST(p_List) == p_List);
90728 +}
90729 +
90730 +
90731 +/**************************************************************************//**
90732 + @Function LIST_Append
90733 +
90734 + @Description Join two lists.
90735 +
90736 + @Param[in] p_NewList - A pointer to the new list to add.
90737 + @Param[in] p_Head - A pointer to the place to add it in the first list.
90738 +
90739 + @Return none.
90740 +*//***************************************************************************/
90741 +void LIST_Append(t_List *p_NewList, t_List *p_Head);
90742 +
90743 +
90744 +/**************************************************************************//**
90745 + @Function LIST_NumOfObjs
90746 +
90747 + @Description Counts number of objects in the list
90748 +
90749 + @Param[in] p_List - A pointer to the list which objects are to be counted.
90750 +
90751 + @Return Number of objects in the list.
90752 +*//***************************************************************************/
90753 +int LIST_NumOfObjs(t_List *p_List);
90754 +
90755 +/** @} */ /* end of list_id group */
90756 +/** @} */ /* end of etc_id group */
90757 +
90758 +
90759 +#endif /* __LIST_EXT_H */
90760 --- /dev/null
90761 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
90762 @@ -0,0 +1,318 @@
90763 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90764 + * All rights reserved.
90765 + *
90766 + * Redistribution and use in source and binary forms, with or without
90767 + * modification, are permitted provided that the following conditions are met:
90768 + * * Redistributions of source code must retain the above copyright
90769 + * notice, this list of conditions and the following disclaimer.
90770 + * * Redistributions in binary form must reproduce the above copyright
90771 + * notice, this list of conditions and the following disclaimer in the
90772 + * documentation and/or other materials provided with the distribution.
90773 + * * Neither the name of Freescale Semiconductor nor the
90774 + * names of its contributors may be used to endorse or promote products
90775 + * derived from this software without specific prior written permission.
90776 + *
90777 + *
90778 + * ALTERNATIVELY, this software may be distributed under the terms of the
90779 + * GNU General Public License ("GPL") as published by the Free Software
90780 + * Foundation, either version 2 of that License or (at your option) any
90781 + * later version.
90782 + *
90783 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90784 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90785 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90786 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90787 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90788 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90789 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90790 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90791 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90792 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90793 + */
90794 +
90795 +
90796 +/**************************************************************************//**
90797 +
90798 + @File mem_ext.h
90799 +
90800 + @Description External prototypes for the memory manager object
90801 +*//***************************************************************************/
90802 +
90803 +#ifndef __MEM_EXT_H
90804 +#define __MEM_EXT_H
90805 +
90806 +#include "std_ext.h"
90807 +#include "part_ext.h"
90808 +
90809 +
90810 +/**************************************************************************//**
90811 + @Group etc_id Utility Library Application Programming Interface
90812 +
90813 + @Description External routines.
90814 +
90815 + @{
90816 +*//***************************************************************************/
90817 +
90818 +/**************************************************************************//**
90819 + @Group mem_id Slab Memory Manager
90820 +
90821 + @Description Slab Memory Manager module functions, definitions and enums.
90822 +
90823 + @{
90824 +*//***************************************************************************/
90825 +
90826 +/* Each block is of the following structure:
90827 + *
90828 + *
90829 + * +-----------+----------+---------------------------+-----------+-----------+
90830 + * | Alignment | Prefix | Data | Postfix | Alignment |
90831 + * | field | field | field | field | Padding |
90832 + * | | | | | |
90833 + * +-----------+----------+---------------------------+-----------+-----------+
90834 + * and at the beginning of all bytes, an additional optional padding might reside
90835 + * to ensure that the first blocks data field is aligned as requested.
90836 + */
90837 +
90838 +
90839 +#define MEM_MAX_NAME_LENGTH 8
90840 +
90841 +/**************************************************************************//*
90842 + @Description Memory Segment structure
90843 +*//***************************************************************************/
90844 +
90845 +typedef struct
90846 +{
90847 + char name[MEM_MAX_NAME_LENGTH];
90848 + /* The segment's name */
90849 + uint8_t **p_Bases; /* Base addresses of the segments */
90850 + uint8_t **p_BlocksStack; /* Array of pointers to blocks */
90851 + t_Handle h_Spinlock;
90852 + uint16_t dataSize; /* Size of each data block */
90853 + uint16_t prefixSize; /* How many bytes to reserve before the data */
90854 + uint16_t postfixSize; /* How many bytes to reserve after the data */
90855 + uint16_t alignment; /* Requested alignment for the data field */
90856 + int allocOwner; /* Memory allocation owner */
90857 + uint32_t getFailures; /* Number of times get failed */
90858 + uint32_t num; /* Number of blocks in segment */
90859 + uint32_t current; /* Current block */
90860 + bool consecutiveMem; /* Allocate consecutive data blocks memory */
90861 +#ifdef DEBUG_MEM_LEAKS
90862 + void *p_MemDbg; /* MEM debug database (MEM leaks detection) */
90863 + uint32_t blockOffset;
90864 + uint32_t blockSize;
90865 +#endif /* DEBUG_MEM_LEAKS */
90866 +} t_MemorySegment;
90867 +
90868 +
90869 +
90870 +/**************************************************************************//**
90871 + @Function MEM_Init
90872 +
90873 + @Description Create a new memory segment.
90874 +
90875 + @Param[in] name - Name of memory partition.
90876 + @Param[in] p_Handle - Handle to new segment is returned through here.
90877 + @Param[in] num - Number of blocks in new segment.
90878 + @Param[in] dataSize - Size of blocks in segment.
90879 + @Param[in] prefixSize - How many bytes to allocate before the data.
90880 + @Param[in] postfixSize - How many bytes to allocate after the data.
90881 + @Param[in] alignment - Requested alignment for data field (in bytes).
90882 +
90883 + @Return E_OK - success, E_NO_MEMORY - out of memory.
90884 +*//***************************************************************************/
90885 +t_Error MEM_Init(char name[],
90886 + t_Handle *p_Handle,
90887 + uint32_t num,
90888 + uint16_t dataSize,
90889 + uint16_t prefixSize,
90890 + uint16_t postfixSize,
90891 + uint16_t alignment);
90892 +
90893 +/**************************************************************************//**
90894 + @Function MEM_InitSmart
90895 +
90896 + @Description Create a new memory segment.
90897 +
90898 + @Param[in] name - Name of memory partition.
90899 + @Param[in] p_Handle - Handle to new segment is returned through here.
90900 + @Param[in] num - Number of blocks in new segment.
90901 + @Param[in] dataSize - Size of blocks in segment.
90902 + @Param[in] prefixSize - How many bytes to allocate before the data.
90903 + @Param[in] postfixSize - How many bytes to allocate after the data.
90904 + @Param[in] alignment - Requested alignment for data field (in bytes).
90905 + @Param[in] memPartitionId - Memory partition ID for allocation.
90906 + @Param[in] consecutiveMem - Whether to allocate the memory blocks
90907 + continuously or not.
90908 +
90909 + @Return E_OK - success, E_NO_MEMORY - out of memory.
90910 +*//***************************************************************************/
90911 +t_Error MEM_InitSmart(char name[],
90912 + t_Handle *p_Handle,
90913 + uint32_t num,
90914 + uint16_t dataSize,
90915 + uint16_t prefixSize,
90916 + uint16_t postfixSize,
90917 + uint16_t alignment,
90918 + uint8_t memPartitionId,
90919 + bool consecutiveMem);
90920 +
90921 +/**************************************************************************//**
90922 + @Function MEM_InitByAddress
90923 +
90924 + @Description Create a new memory segment with a specified base address.
90925 +
90926 + @Param[in] name - Name of memory partition.
90927 + @Param[in] p_Handle - Handle to new segment is returned through here.
90928 + @Param[in] num - Number of blocks in new segment.
90929 + @Param[in] dataSize - Size of blocks in segment.
90930 + @Param[in] prefixSize - How many bytes to allocate before the data.
90931 + @Param[in] postfixSize - How many bytes to allocate after the data.
90932 + @Param[in] alignment - Requested alignment for data field (in bytes).
90933 + @Param[in] address - The required base address.
90934 +
90935 + @Return E_OK - success, E_NO_MEMORY - out of memory.
90936 + *//***************************************************************************/
90937 +t_Error MEM_InitByAddress(char name[],
90938 + t_Handle *p_Handle,
90939 + uint32_t num,
90940 + uint16_t dataSize,
90941 + uint16_t prefixSize,
90942 + uint16_t postfixSize,
90943 + uint16_t alignment,
90944 + uint8_t *address);
90945 +
90946 +/**************************************************************************//**
90947 + @Function MEM_Free
90948 +
90949 + @Description Free a specific memory segment.
90950 +
90951 + @Param[in] h_Mem - Handle to memory segment.
90952 +
90953 + @Return None.
90954 +*//***************************************************************************/
90955 +void MEM_Free(t_Handle h_Mem);
90956 +
90957 +/**************************************************************************//**
90958 + @Function MEM_Get
90959 +
90960 + @Description Get a block of memory from a segment.
90961 +
90962 + @Param[in] h_Mem - Handle to memory segment.
90963 +
90964 + @Return Pointer to new memory block on success,0 otherwise.
90965 +*//***************************************************************************/
90966 +void * MEM_Get(t_Handle h_Mem);
90967 +
90968 +/**************************************************************************//**
90969 + @Function MEM_GetN
90970 +
90971 + @Description Get up to N blocks of memory from a segment.
90972 +
90973 + The blocks are assumed to be of a fixed size (one size per segment).
90974 +
90975 + @Param[in] h_Mem - Handle to memory segment.
90976 + @Param[in] num - Number of blocks to allocate.
90977 + @Param[out] array - Array of at least num pointers to which the addresses
90978 + of the allocated blocks are written.
90979 +
90980 + @Return The number of blocks actually allocated.
90981 +
90982 + @Cautions Interrupts are disabled for all of the allocation loop.
90983 + Although this loop is very short for each block (several machine
90984 + instructions), you should not allocate a very large number
90985 + of blocks via this routine.
90986 +*//***************************************************************************/
90987 +uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]);
90988 +
90989 +/**************************************************************************//**
90990 + @Function MEM_Put
90991 +
90992 + @Description Put a block of memory back to a segment.
90993 +
90994 + @Param[in] h_Mem - Handle to memory segment.
90995 + @Param[in] p_Block - The block to return.
90996 +
90997 + @Return Pointer to new memory block on success,0 otherwise.
90998 +*//***************************************************************************/
90999 +t_Error MEM_Put(t_Handle h_Mem, void *p_Block);
91000 +
91001 +/**************************************************************************//**
91002 + @Function MEM_ComputePartitionSize
91003 +
91004 + @Description calculate a tight upper boundary of the size of a partition with
91005 + given attributes.
91006 +
91007 + The returned value is suitable if one wants to use MEM_InitByAddress().
91008 +
91009 + @Param[in] num - The number of blocks in the segment.
91010 + @Param[in] dataSize - Size of block to get.
91011 + @Param[in] prefixSize - The prefix size
91012 + @Param postfixSize - The postfix size
91013 + @Param[in] alignment - The requested alignment value (in bytes)
91014 +
91015 + @Return The memory block size a segment with the given attributes needs.
91016 +*//***************************************************************************/
91017 +uint32_t MEM_ComputePartitionSize(uint32_t num,
91018 + uint16_t dataSize,
91019 + uint16_t prefixSize,
91020 + uint16_t postfixSize,
91021 + uint16_t alignment);
91022 +
91023 +#ifdef DEBUG_MEM_LEAKS
91024 +#if !((defined(__MWERKS__) || defined(__GNUC__)) && (__dest_os == __ppc_eabi))
91025 +#error "Memory-Leaks-Debug option is supported only for freescale CodeWarrior"
91026 +#endif /* !(defined(__MWERKS__) && ... */
91027 +
91028 +/**************************************************************************//**
91029 + @Function MEM_CheckLeaks
91030 +
91031 + @Description Report MEM object leaks.
91032 +
91033 + This routine is automatically called by the MEM_Free() routine,
91034 + but it can also be invoked while the MEM object is alive.
91035 +
91036 + @Param[in] h_Mem - Handle to memory segment.
91037 +
91038 + @Return None.
91039 +*//***************************************************************************/
91040 +void MEM_CheckLeaks(t_Handle h_Mem);
91041 +
91042 +#else /* not DEBUG_MEM_LEAKS */
91043 +#define MEM_CheckLeaks(h_Mem)
91044 +#endif /* not DEBUG_MEM_LEAKS */
91045 +
91046 +/**************************************************************************//**
91047 + @Description Get base of MEM
91048 +*//***************************************************************************/
91049 +#define MEM_GetBase(h_Mem) ((t_MemorySegment *)(h_Mem))->p_Bases[0]
91050 +
91051 +/**************************************************************************//**
91052 + @Description Get size of MEM block
91053 +*//***************************************************************************/
91054 +#define MEM_GetSize(h_Mem) ((t_MemorySegment *)(h_Mem))->dataSize
91055 +
91056 +/**************************************************************************//**
91057 + @Description Get prefix size of MEM block
91058 +*//***************************************************************************/
91059 +#define MEM_GetPrefixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->prefixSize
91060 +
91061 +/**************************************************************************//**
91062 + @Description Get postfix size of MEM block
91063 +*//***************************************************************************/
91064 +#define MEM_GetPostfixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->postfixSize
91065 +
91066 +/**************************************************************************//**
91067 + @Description Get alignment of MEM block (in bytes)
91068 +*//***************************************************************************/
91069 +#define MEM_GetAlignment(h_Mem) ((t_MemorySegment *)(h_Mem))->alignment
91070 +
91071 +/**************************************************************************//**
91072 + @Description Get the number of blocks in the segment
91073 +*//***************************************************************************/
91074 +#define MEM_GetNumOfBlocks(h_Mem) ((t_MemorySegment *)(h_Mem))->num
91075 +
91076 +/** @} */ /* end of MEM group */
91077 +/** @} */ /* end of etc_id group */
91078 +
91079 +
91080 +#endif /* __MEM_EXT_H */
91081 --- /dev/null
91082 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
91083 @@ -0,0 +1,208 @@
91084 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91085 + * All rights reserved.
91086 + *
91087 + * Redistribution and use in source and binary forms, with or without
91088 + * modification, are permitted provided that the following conditions are met:
91089 + * * Redistributions of source code must retain the above copyright
91090 + * notice, this list of conditions and the following disclaimer.
91091 + * * Redistributions in binary form must reproduce the above copyright
91092 + * notice, this list of conditions and the following disclaimer in the
91093 + * documentation and/or other materials provided with the distribution.
91094 + * * Neither the name of Freescale Semiconductor nor the
91095 + * names of its contributors may be used to endorse or promote products
91096 + * derived from this software without specific prior written permission.
91097 + *
91098 + *
91099 + * ALTERNATIVELY, this software may be distributed under the terms of the
91100 + * GNU General Public License ("GPL") as published by the Free Software
91101 + * Foundation, either version 2 of that License or (at your option) any
91102 + * later version.
91103 + *
91104 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91105 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91106 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91107 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91108 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91109 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91110 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91111 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91112 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91113 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91114 + */
91115 +
91116 +
91117 +/**************************************************************************//**
91118 +
91119 + @File memcpy_ext.h
91120 +
91121 + @Description Efficient functions for copying and setting blocks of memory.
91122 +*//***************************************************************************/
91123 +
91124 +#ifndef __MEMCPY_EXT_H
91125 +#define __MEMCPY_EXT_H
91126 +
91127 +#include "std_ext.h"
91128 +
91129 +
91130 +/**************************************************************************//**
91131 + @Group etc_id Utility Library Application Programming Interface
91132 +
91133 + @Description External routines.
91134 +
91135 + @{
91136 +*//***************************************************************************/
91137 +
91138 +/**************************************************************************//**
91139 + @Group mem_cpy Memory Copy
91140 +
91141 + @Description Memory Copy module functions,definitions and enums.
91142 +
91143 + @{
91144 +*//***************************************************************************/
91145 +
91146 +/**************************************************************************//**
91147 + @Function MemCpy32
91148 +
91149 + @Description Copies one memory buffer into another one in 4-byte chunks!
91150 + Which should be more efficient than byte by byte.
91151 +
91152 + For large buffers (over 60 bytes) this function is about 4 times
91153 + more efficient than the trivial memory copy. For short buffers
91154 + it is reduced to the trivial copy and may be a bit worse.
91155 +
91156 + @Param[in] pDst - The address of the destination buffer.
91157 + @Param[in] pSrc - The address of the source buffer.
91158 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91159 +
91160 + @Return pDst (the address of the destination buffer).
91161 +
91162 + @Cautions There is no parameter or boundary checking! It is up to the user
91163 + to supply non-null parameters as source & destination and size
91164 + that actually fits into the destination buffer.
91165 +*//***************************************************************************/
91166 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size);
91167 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91168 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size);
91169 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91170 +
91171 +/**************************************************************************//**
91172 + @Function MemCpy64
91173 +
91174 + @Description Copies one memory buffer into another one in 8-byte chunks!
91175 + Which should be more efficient than byte by byte.
91176 +
91177 + For large buffers (over 60 bytes) this function is about 8 times
91178 + more efficient than the trivial memory copy. For short buffers
91179 + it is reduced to the trivial copy and may be a bit worse.
91180 +
91181 + Some testing suggests that MemCpy32() preforms better than
91182 + MemCpy64() over small buffers. On average they break even at
91183 + 100 byte buffers. For buffers larger than that MemCpy64 is
91184 + superior.
91185 +
91186 + @Param[in] pDst - The address of the destination buffer.
91187 + @Param[in] pSrc - The address of the source buffer.
91188 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91189 +
91190 + @Return pDst (the address of the destination buffer).
91191 +
91192 + @Cautions There is no parameter or boundary checking! It is up to the user
91193 + to supply non null parameters as source & destination and size
91194 + that actually fits into their buffer.
91195 +
91196 + Do not use under Linux.
91197 +*//***************************************************************************/
91198 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size);
91199 +
91200 +/**************************************************************************//**
91201 + @Function MemSet32
91202 +
91203 + @Description Sets all bytes of a memory buffer to a specific value, in
91204 + 4-byte chunks.
91205 +
91206 + @Param[in] pDst - The address of the destination buffer.
91207 + @Param[in] val - Value to set destination bytes to.
91208 + @Param[in] size - The number of bytes that will be set to val.
91209 +
91210 + @Return pDst (the address of the destination buffer).
91211 +
91212 + @Cautions There is no parameter or boundary checking! It is up to the user
91213 + to supply non null parameter as destination and size
91214 + that actually fits into the destination buffer.
91215 +*//***************************************************************************/
91216 +void * MemSet32(void* pDst, uint8_t val, uint32_t size);
91217 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size);
91218 +
91219 +/**************************************************************************//**
91220 + @Function MemSet64
91221 +
91222 + @Description Sets all bytes of a memory buffer to a specific value, in
91223 + 8-byte chunks.
91224 +
91225 + @Param[in] pDst - The address of the destination buffer.
91226 + @Param[in] val - Value to set destination bytes to.
91227 + @Param[in] size - The number of bytes that will be set to val.
91228 +
91229 + @Return pDst (the address of the destination buffer).
91230 +
91231 + @Cautions There is no parameter or boundary checking! It is up to the user
91232 + to supply non null parameter as destination and size
91233 + that actually fits into the destination buffer.
91234 +*//***************************************************************************/
91235 +void * MemSet64(void* pDst, uint8_t val, uint32_t size);
91236 +
91237 +/**************************************************************************//**
91238 + @Function MemDisp
91239 +
91240 + @Description Displays a block of memory in chunks of 32 bits.
91241 +
91242 + @Param[in] addr - The address of the memory to display.
91243 + @Param[in] size - The number of bytes that will be displayed.
91244 +
91245 + @Return None.
91246 +
91247 + @Cautions There is no parameter or boundary checking! It is up to the user
91248 + to supply non null parameter as destination and size
91249 + that actually fits into the destination buffer.
91250 +*//***************************************************************************/
91251 +void MemDisp(uint8_t *addr, int size);
91252 +
91253 +/**************************************************************************//**
91254 + @Function MemCpy8
91255 +
91256 + @Description Trivial copy one memory buffer into another byte by byte
91257 +
91258 + @Param[in] pDst - The address of the destination buffer.
91259 + @Param[in] pSrc - The address of the source buffer.
91260 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91261 +
91262 + @Return pDst (the address of the destination buffer).
91263 +
91264 + @Cautions There is no parameter or boundary checking! It is up to the user
91265 + to supply non-null parameters as source & destination and size
91266 + that actually fits into the destination buffer.
91267 +*//***************************************************************************/
91268 +void * MemCpy8(void* pDst,void* pSrc, uint32_t size);
91269 +
91270 +/**************************************************************************//**
91271 + @Function MemSet8
91272 +
91273 + @Description Sets all bytes of a memory buffer to a specific value byte by byte.
91274 +
91275 + @Param[in] pDst - The address of the destination buffer.
91276 + @Param[in] c - Value to set destination bytes to.
91277 + @Param[in] size - The number of bytes that will be set to val.
91278 +
91279 + @Return pDst (the address of the destination buffer).
91280 +
91281 + @Cautions There is no parameter or boundary checking! It is up to the user
91282 + to supply non null parameter as destination and size
91283 + that actually fits into the destination buffer.
91284 +*//***************************************************************************/
91285 +void * MemSet8(void* pDst, int c, uint32_t size);
91286 +
91287 +/** @} */ /* end of mem_cpy group */
91288 +/** @} */ /* end of etc_id group */
91289 +
91290 +
91291 +#endif /* __MEMCPY_EXT_H */
91292 --- /dev/null
91293 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
91294 @@ -0,0 +1,310 @@
91295 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91296 + * All rights reserved.
91297 + *
91298 + * Redistribution and use in source and binary forms, with or without
91299 + * modification, are permitted provided that the following conditions are met:
91300 + * * Redistributions of source code must retain the above copyright
91301 + * notice, this list of conditions and the following disclaimer.
91302 + * * Redistributions in binary form must reproduce the above copyright
91303 + * notice, this list of conditions and the following disclaimer in the
91304 + * documentation and/or other materials provided with the distribution.
91305 + * * Neither the name of Freescale Semiconductor nor the
91306 + * names of its contributors may be used to endorse or promote products
91307 + * derived from this software without specific prior written permission.
91308 + *
91309 + *
91310 + * ALTERNATIVELY, this software may be distributed under the terms of the
91311 + * GNU General Public License ("GPL") as published by the Free Software
91312 + * Foundation, either version 2 of that License or (at your option) any
91313 + * later version.
91314 + *
91315 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91316 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91317 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91318 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91319 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91320 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91321 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91322 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91323 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91324 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91325 + */
91326 +
91327 +
91328 +/**************************************************************************//**
91329 + @File mm_ext.h
91330 +
91331 + @Description Memory Manager Application Programming Interface
91332 +*//***************************************************************************/
91333 +#ifndef __MM_EXT
91334 +#define __MM_EXT
91335 +
91336 +#include "std_ext.h"
91337 +
91338 +#define MM_MAX_ALIGNMENT 20 /* Alignments from 2 to 128 are available
91339 + where maximum alignment defined as
91340 + MM_MAX_ALIGNMENT power of 2 */
91341 +
91342 +#define MM_MAX_NAME_LEN 32
91343 +
91344 +/**************************************************************************//**
91345 + @Group etc_id Utility Library Application Programming Interface
91346 +
91347 + @Description External routines.
91348 +
91349 + @{
91350 +*//***************************************************************************/
91351 +
91352 +/**************************************************************************//**
91353 + @Group mm_grp Flexible Memory Manager
91354 +
91355 + @Description Flexible Memory Manager module functions,definitions and enums.
91356 + (All of the following functions,definitions and enums can be found in mm_ext.h)
91357 +
91358 + @{
91359 +*//***************************************************************************/
91360 +
91361 +
91362 +/**************************************************************************//**
91363 + @Function MM_Init
91364 +
91365 + @Description Initializes a new MM object.
91366 +
91367 + It initializes a new memory block consisting of base address
91368 + and size of the available memory by calling to MemBlock_Init
91369 + routine. It is also initializes a new free block for each
91370 + by calling FreeBlock_Init routine, which is pointed to
91371 + the almost all memory started from the required alignment
91372 + from the base address and to the end of the memory.
91373 + The handle to the new MM object is returned via "MM"
91374 + argument (passed by reference).
91375 +
91376 + @Param[in] h_MM - Handle to the MM object.
91377 + @Param[in] base - Base address of the MM.
91378 + @Param[in] size - Size of the MM.
91379 +
91380 + @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.
91381 +*//***************************************************************************/
91382 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size);
91383 +
91384 +/**************************************************************************//**
91385 + @Function MM_Get
91386 +
91387 + @Description Allocates a block of memory according to the given size and the alignment.
91388 +
91389 + The Alignment argument tells from which
91390 + free list allocate a block of memory. 2^alignment indicates
91391 + the alignment that the base address of the allocated block
91392 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91393 + are available for the alignment argument.
91394 + The routine passes through the specific free list of free
91395 + blocks and seeks for a first block that have anough memory
91396 + that is required (best fit).
91397 + After the block is found and data is allocated, it calls
91398 + the internal MM_CutFree routine to update all free lists
91399 + do not include a just allocated block. Of course, each
91400 + free list contains a free blocks with the same alignment.
91401 + It is also creates a busy block that holds
91402 + information about an allocated block.
91403 +
91404 + @Param[in] h_MM - Handle to the MM object.
91405 + @Param[in] size - Size of the MM.
91406 + @Param[in] alignment - Index as a power of two defines a required
91407 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91408 + @Param[in] name - The name that specifies an allocated block.
91409 +
91410 + @Return base address of an allocated block ILLEGAL_BASE if can't allocate a block
91411 +*//***************************************************************************/
91412 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char *name);
91413 +
91414 +/**************************************************************************//**
91415 + @Function MM_GetBase
91416 +
91417 + @Description Gets the base address of the required MM objects.
91418 +
91419 + @Param[in] h_MM - Handle to the MM object.
91420 +
91421 + @Return base address of the block.
91422 +*//***************************************************************************/
91423 +uint64_t MM_GetBase(t_Handle h_MM);
91424 +
91425 +/**************************************************************************//**
91426 + @Function MM_GetForce
91427 +
91428 + @Description Force memory allocation.
91429 +
91430 + It means to allocate a block of memory of the given
91431 + size from the given base address.
91432 + The routine checks if the required block can be allocated
91433 + (that is it is free) and then, calls the internal MM_CutFree
91434 + routine to update all free lists do not include that block.
91435 +
91436 + @Param[in] h_MM - Handle to the MM object.
91437 + @Param[in] base - Base address of the MM.
91438 + @Param[in] size - Size of the MM.
91439 + @Param[in] name - Name that specifies an allocated block.
91440 +
91441 + @Return base address of an allocated block, ILLEGAL_BASE if can't allocate a block.
91442 +*//***************************************************************************/
91443 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char *name);
91444 +
91445 +/**************************************************************************//**
91446 + @Function MM_GetForceMin
91447 +
91448 + @Description Allocates a block of memory according to the given size, the alignment and minimum base address.
91449 +
91450 + The Alignment argument tells from which
91451 + free list allocate a block of memory. 2^alignment indicates
91452 + the alignment that the base address of the allocated block
91453 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91454 + are available for the alignment argument.
91455 + The minimum baser address forces the location of the block
91456 + to be from a given address onward.
91457 + The routine passes through the specific free list of free
91458 + blocks and seeks for the first base address equal or smaller
91459 + than the required minimum address and end address larger than
91460 + than the required base + its size - i.e. that may contain
91461 + the required block.
91462 + After the block is found and data is allocated, it calls
91463 + the internal MM_CutFree routine to update all free lists
91464 + do not include a just allocated block. Of course, each
91465 + free list contains a free blocks with the same alignment.
91466 + It is also creates a busy block that holds
91467 + information about an allocated block.
91468 +
91469 + @Param[in] h_MM - Handle to the MM object.
91470 + @Param[in] size - Size of the MM.
91471 + @Param[in] alignment - Index as a power of two defines a required
91472 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91473 + @Param[in] min - The minimum base address of the block.
91474 + @Param[in] name - Name that specifies an allocated block.
91475 +
91476 + @Return base address of an allocated block,ILLEGAL_BASE if can't allocate a block.
91477 +*//***************************************************************************/
91478 +uint64_t MM_GetForceMin(t_Handle h_MM,
91479 + uint64_t size,
91480 + uint64_t alignment,
91481 + uint64_t min,
91482 + char *name);
91483 +
91484 +/**************************************************************************//**
91485 + @Function MM_Put
91486 +
91487 + @Description Puts a block of memory of the given base address back to the memory.
91488 +
91489 + It checks if there is a busy block with the
91490 + given base address. If not, it returns 0, that
91491 + means can't free a block. Otherwise, it gets parameters of
91492 + the busy block and after it updates lists of free blocks,
91493 + removes that busy block from the list by calling to MM_CutBusy
91494 + routine.
91495 + After that it calls to MM_AddFree routine to add a new free
91496 + block to the free lists.
91497 +
91498 + @Param[in] h_MM - Handle to the MM object.
91499 + @Param[in] base - Base address of the MM.
91500 +
91501 + @Return The size of bytes released, 0 if failed.
91502 +*//***************************************************************************/
91503 +uint64_t MM_Put(t_Handle h_MM, uint64_t base);
91504 +
91505 +/**************************************************************************//**
91506 + @Function MM_PutForce
91507 +
91508 + @Description Releases a block of memory of the required size from the required base address.
91509 +
91510 + First, it calls to MM_CutBusy routine
91511 + to cut a free block from the busy list. And then, calls to
91512 + MM_AddFree routine to add the free block to the free lists.
91513 +
91514 + @Param[in] h_MM - Handle to the MM object.
91515 + @Param[in] base - Base address of of a block to free.
91516 + @Param[in] size - Size of a block to free.
91517 +
91518 + @Return The number of bytes released, 0 on failure.
91519 +*//***************************************************************************/
91520 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size);
91521 +
91522 +/**************************************************************************//**
91523 + @Function MM_Add
91524 +
91525 + @Description Adds a new memory block for memory allocation.
91526 +
91527 + When a new memory block is initialized and added to the
91528 + memory list, it calls to MM_AddFree routine to add the
91529 + new free block to the free lists.
91530 +
91531 + @Param[in] h_MM - Handle to the MM object.
91532 + @Param[in] base - Base address of the memory block.
91533 + @Param[in] size - Size of the memory block.
91534 +
91535 + @Return E_OK on success, otherwise returns an error code.
91536 +*//***************************************************************************/
91537 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size);
91538 +
91539 +/**************************************************************************//**
91540 + @Function MM_Dump
91541 +
91542 + @Description Prints results of free and busy lists.
91543 +
91544 + @Param[in] h_MM - Handle to the MM object.
91545 +*//***************************************************************************/
91546 +void MM_Dump(t_Handle h_MM);
91547 +
91548 +/**************************************************************************//**
91549 + @Function MM_Free
91550 +
91551 + @Description Releases memory allocated for MM object.
91552 +
91553 + @Param[in] h_MM - Handle of the MM object.
91554 +*//***************************************************************************/
91555 +void MM_Free(t_Handle h_MM);
91556 +
91557 +/**************************************************************************//**
91558 + @Function MM_GetMemBlock
91559 +
91560 + @Description Returns base address of the memory block specified by the index.
91561 +
91562 + If index is 0, returns base address
91563 + of the first memory block, 1 - returns base address
91564 + of the second memory block, etc.
91565 + Note, those memory blocks are allocated by the
91566 + application before MM_Init or MM_Add and have to
91567 + be released by the application before or after invoking
91568 + the MM_Free routine.
91569 +
91570 + @Param[in] h_MM - Handle to the MM object.
91571 + @Param[in] index - Index of the memory block.
91572 +
91573 + @Return valid base address or ILLEGAL_BASE if no memory block specified by the index.
91574 +*//***************************************************************************/
91575 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index);
91576 +
91577 +/**************************************************************************//**
91578 + @Function MM_InRange
91579 +
91580 + @Description Checks if a specific address is in the memory range of the passed MM object.
91581 +
91582 + @Param[in] h_MM - Handle to the MM object.
91583 + @Param[in] addr - The address to be checked.
91584 +
91585 + @Return TRUE if the address is in the address range of the block, FALSE otherwise.
91586 +*//***************************************************************************/
91587 +bool MM_InRange(t_Handle h_MM, uint64_t addr);
91588 +
91589 +/**************************************************************************//**
91590 + @Function MM_GetFreeMemSize
91591 +
91592 + @Description Returns the size (in bytes) of free memory.
91593 +
91594 + @Param[in] h_MM - Handle to the MM object.
91595 +
91596 + @Return Free memory size in bytes.
91597 +*//***************************************************************************/
91598 +uint64_t MM_GetFreeMemSize(t_Handle h_MM);
91599 +
91600 +
91601 +/** @} */ /* end of mm_grp group */
91602 +/** @} */ /* end of etc_id group */
91603 +
91604 +#endif /* __MM_EXT_H */
91605 --- /dev/null
91606 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
91607 @@ -0,0 +1,118 @@
91608 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91609 + * All rights reserved.
91610 + *
91611 + * Redistribution and use in source and binary forms, with or without
91612 + * modification, are permitted provided that the following conditions are met:
91613 + * * Redistributions of source code must retain the above copyright
91614 + * notice, this list of conditions and the following disclaimer.
91615 + * * Redistributions in binary form must reproduce the above copyright
91616 + * notice, this list of conditions and the following disclaimer in the
91617 + * documentation and/or other materials provided with the distribution.
91618 + * * Neither the name of Freescale Semiconductor nor the
91619 + * names of its contributors may be used to endorse or promote products
91620 + * derived from this software without specific prior written permission.
91621 + *
91622 + *
91623 + * ALTERNATIVELY, this software may be distributed under the terms of the
91624 + * GNU General Public License ("GPL") as published by the Free Software
91625 + * Foundation, either version 2 of that License or (at your option) any
91626 + * later version.
91627 + *
91628 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91629 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91630 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91631 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91632 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91633 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91634 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91635 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91636 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91637 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91638 + */
91639 +
91640 +
91641 +/**************************************************************************//**
91642 + @File sprint_ext.h
91643 +
91644 + @Description Debug routines (externals).
91645 +
91646 +*//***************************************************************************/
91647 +
91648 +#ifndef __SPRINT_EXT_H
91649 +#define __SPRINT_EXT_H
91650 +
91651 +
91652 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
91653 +#include <linux/kernel.h>
91654 +
91655 +#elif defined(NCSW_VXWORKS)
91656 +#include "private/stdioP.h"
91657 +
91658 +#else
91659 +#include <stdio.h>
91660 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
91661 +
91662 +#include "std_ext.h"
91663 +
91664 +
91665 +/**************************************************************************//**
91666 + @Group etc_id Utility Library Application Programming Interface
91667 +
91668 + @Description External routines.
91669 +
91670 + @{
91671 +*//***************************************************************************/
91672 +
91673 +/**************************************************************************//**
91674 + @Group sprint_id Sprint
91675 +
91676 + @Description Sprint & Sscan module functions,definitions and enums.
91677 +
91678 + @{
91679 +*//***************************************************************************/
91680 +
91681 +/**************************************************************************//**
91682 + @Function Sprint
91683 +
91684 + @Description Format a string and place it in a buffer.
91685 +
91686 + @Param[in] buff - The buffer to place the result into.
91687 + @Param[in] str - The format string to use.
91688 + @Param[in] ... - Arguments for the format string.
91689 +
91690 + @Return Number of bytes formatted.
91691 +*//***************************************************************************/
91692 +int Sprint(char *buff, const char *str, ...);
91693 +
91694 +/**************************************************************************//**
91695 + @Function Snprint
91696 +
91697 + @Description Format a string and place it in a buffer.
91698 +
91699 + @Param[in] buf - The buffer to place the result into.
91700 + @Param[in] size - The size of the buffer, including the trailing null space.
91701 + @Param[in] fmt - The format string to use.
91702 + @Param[in] ... - Arguments for the format string.
91703 +
91704 + @Return Number of bytes formatted.
91705 +*//***************************************************************************/
91706 +int Snprint(char * buf, uint32_t size, const char *fmt, ...);
91707 +
91708 +/**************************************************************************//**
91709 + @Function Sscan
91710 +
91711 + @Description Unformat a buffer into a list of arguments.
91712 +
91713 + @Param[in] buf - input buffer.
91714 + @Param[in] fmt - formatting of buffer.
91715 + @Param[out] ... - resulting arguments.
91716 +
91717 + @Return Number of bytes unformatted.
91718 +*//***************************************************************************/
91719 +int Sscan(const char * buf, const char * fmt, ...);
91720 +
91721 +/** @} */ /* end of sprint_id group */
91722 +/** @} */ /* end of etc_id group */
91723 +
91724 +
91725 +#endif /* __SPRINT_EXT_H */
91726 --- /dev/null
91727 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
91728 @@ -0,0 +1,37 @@
91729 +/*
91730 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91731 + *
91732 + * Redistribution and use in source and binary forms, with or without
91733 + * modification, are permitted provided that the following conditions are met:
91734 + * * Redistributions of source code must retain the above copyright
91735 + * notice, this list of conditions and the following disclaimer.
91736 + * * Redistributions in binary form must reproduce the above copyright
91737 + * notice, this list of conditions and the following disclaimer in the
91738 + * documentation and/or other materials provided with the distribution.
91739 + * * Neither the name of Freescale Semiconductor nor the
91740 + * names of its contributors may be used to endorse or promote products
91741 + * derived from this software without specific prior written permission.
91742 + *
91743 + *
91744 + * ALTERNATIVELY, this software may be distributed under the terms of the
91745 + * GNU General Public License ("GPL") as published by the Free Software
91746 + * Foundation, either version 2 of that License or (at your option) any
91747 + * later version.
91748 + *
91749 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91750 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91751 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91752 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91753 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91754 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91755 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91756 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91757 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91758 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91759 + */
91760 +
91761 +#ifndef FL_E500_MACROS_H
91762 +#define FL_E500_MACROS_H
91763 +
91764 +#endif /* FL_E500_MACROS_H */
91765 +
91766 --- /dev/null
91767 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
91768 @@ -0,0 +1,52 @@
91769 +/*
91770 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91771 + *
91772 + * Redistribution and use in source and binary forms, with or without
91773 + * modification, are permitted provided that the following conditions are met:
91774 + * * Redistributions of source code must retain the above copyright
91775 + * notice, this list of conditions and the following disclaimer.
91776 + * * Redistributions in binary form must reproduce the above copyright
91777 + * notice, this list of conditions and the following disclaimer in the
91778 + * documentation and/or other materials provided with the distribution.
91779 + * * Neither the name of Freescale Semiconductor nor the
91780 + * names of its contributors may be used to endorse or promote products
91781 + * derived from this software without specific prior written permission.
91782 + *
91783 + *
91784 + * ALTERNATIVELY, this software may be distributed under the terms of the
91785 + * GNU General Public License ("GPL") as published by the Free Software
91786 + * Foundation, either version 2 of that License or (at your option) any
91787 + * later version.
91788 + *
91789 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91790 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91791 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91792 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91793 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91794 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91795 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91796 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91797 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91798 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91799 + */
91800 +
91801 +#ifndef __GENERAL_H
91802 +#define __GENERAL_H
91803 +
91804 +#include "std_ext.h"
91805 +#if !defined(NCSW_LINUX)
91806 +#include "errno.h"
91807 +#endif
91808 +
91809 +
91810 +extern uint32_t get_mac_addr_crc(uint64_t _addr);
91811 +
91812 +#ifndef CONFIG_FMAN_ARM
91813 +#define iowrite32be(val, addr) WRITE_UINT32(*addr, val)
91814 +#define ioread32be(addr) GET_UINT32(*addr)
91815 +#endif
91816 +
91817 +#define ether_crc(len, addr) get_mac_addr_crc(*(uint64_t *)(addr)>>16)
91818 +
91819 +
91820 +#endif /* __GENERAL_H */
91821 --- /dev/null
91822 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
91823 @@ -0,0 +1,78 @@
91824 +/*
91825 + * Copyright 2008-2013 Freescale Semiconductor Inc.
91826 + *
91827 + * Redistribution and use in source and binary forms, with or without
91828 + * modification, are permitted provided that the following conditions are met:
91829 + * * Redistributions of source code must retain the above copyright
91830 + * notice, this list of conditions and the following disclaimer.
91831 + * * Redistributions in binary form must reproduce the above copyright
91832 + * notice, this list of conditions and the following disclaimer in the
91833 + * documentation and/or other materials provided with the distribution.
91834 + * * Neither the name of Freescale Semiconductor nor the
91835 + * names of its contributors may be used to endorse or promote products
91836 + * derived from this software without specific prior written permission.
91837 + *
91838 + *
91839 + * ALTERNATIVELY, this software may be distributed under the terms of the
91840 + * GNU General Public License ("GPL") as published by the Free Software
91841 + * Foundation, either version 2 of that License or (at your option) any
91842 + * later version.
91843 + *
91844 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91845 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91846 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91847 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91848 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91849 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91850 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91851 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91852 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91853 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91854 + */
91855 +
91856 +
91857 +#ifndef __FMAN_COMMON_H
91858 +#define __FMAN_COMMON_H
91859 +
91860 +/**************************************************************************//**
91861 + @Description NIA Description
91862 +*//***************************************************************************/
91863 +#define NIA_ORDER_RESTOR 0x00800000
91864 +#define NIA_ENG_FM_CTL 0x00000000
91865 +#define NIA_ENG_PRS 0x00440000
91866 +#define NIA_ENG_KG 0x00480000
91867 +#define NIA_ENG_PLCR 0x004C0000
91868 +#define NIA_ENG_BMI 0x00500000
91869 +#define NIA_ENG_QMI_ENQ 0x00540000
91870 +#define NIA_ENG_QMI_DEQ 0x00580000
91871 +#define NIA_ENG_MASK 0x007C0000
91872 +
91873 +#define NIA_FM_CTL_AC_CC 0x00000006
91874 +#define NIA_FM_CTL_AC_HC 0x0000000C
91875 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
91876 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
91877 +#define NIA_FM_CTL_AC_FRAG 0x0000000e
91878 +#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010
91879 +#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012
91880 +#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018
91881 +#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012
91882 +#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014
91883 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
91884 +
91885 +
91886 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
91887 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
91888 +#define NIA_BMI_AC_RELEASE 0x000000C0
91889 +#define NIA_BMI_AC_DISCARD 0x000000C1
91890 +#define NIA_BMI_AC_TX 0x00000274
91891 +#define NIA_BMI_AC_FETCH 0x00000208
91892 +#define NIA_BMI_AC_MASK 0x000003FF
91893 +
91894 +#define NIA_KG_DIRECT 0x00000100
91895 +#define NIA_KG_CC_EN 0x00000200
91896 +#define NIA_PLCR_ABSOLUTE 0x00008000
91897 +
91898 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
91899 +#define NIA_BMI_AC_FETCH_ALL_FRAME 0x0000020c
91900 +
91901 +#endif /* __FMAN_COMMON_H */
91902 --- /dev/null
91903 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
91904 @@ -0,0 +1,273 @@
91905 +/*
91906 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91907 + *
91908 + * Redistribution and use in source and binary forms, with or without
91909 + * modification, are permitted provided that the following conditions are met:
91910 + * * Redistributions of source code must retain the above copyright
91911 + * notice, this list of conditions and the following disclaimer.
91912 + * * Redistributions in binary form must reproduce the above copyright
91913 + * notice, this list of conditions and the following disclaimer in the
91914 + * documentation and/or other materials provided with the distribution.
91915 + * * Neither the name of Freescale Semiconductor nor the
91916 + * names of its contributors may be used to endorse or promote products
91917 + * derived from this software without specific prior written permission.
91918 + *
91919 + *
91920 + * ALTERNATIVELY, this software may be distributed under the terms of the
91921 + * GNU General Public License ("GPL") as published by the Free Software
91922 + * Foundation, either version 2 of that License or (at your option) any
91923 + * later version.
91924 + *
91925 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91926 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91927 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91928 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91929 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91930 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91931 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91932 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91933 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91934 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91935 + */
91936 +
91937 +#ifndef __FSL_ENET_H
91938 +#define __FSL_ENET_H
91939 +
91940 +/**
91941 + @Description Ethernet MAC-PHY Interface
91942 +*/
91943 +
91944 +enum enet_interface {
91945 + E_ENET_IF_MII = 0x00010000, /**< MII interface */
91946 + E_ENET_IF_RMII = 0x00020000, /**< RMII interface */
91947 + E_ENET_IF_SMII = 0x00030000, /**< SMII interface */
91948 + E_ENET_IF_GMII = 0x00040000, /**< GMII interface */
91949 + E_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */
91950 + E_ENET_IF_TBI = 0x00060000, /**< TBI interface */
91951 + E_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */
91952 + E_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */
91953 + E_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */
91954 + E_ENET_IF_QSGMII = 0x000a0000, /**< QSGMII interface */
91955 + E_ENET_IF_XFI = 0x000b0000 /**< XFI interface */
91956 +};
91957 +
91958 +/**
91959 + @Description Ethernet Speed (nominal data rate)
91960 +*/
91961 +enum enet_speed {
91962 + E_ENET_SPEED_10 = 10, /**< 10 Mbps */
91963 + E_ENET_SPEED_100 = 100, /**< 100 Mbps */
91964 + E_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */
91965 + E_ENET_SPEED_2500 = 2500, /**< 2500 Mbps = 2.5 Gbps */
91966 + E_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */
91967 +};
91968 +
91969 +enum mac_type {
91970 + E_MAC_DTSEC,
91971 + E_MAC_TGEC,
91972 + E_MAC_MEMAC
91973 +};
91974 +
91975 +/**************************************************************************//**
91976 + @Description Enum for inter-module interrupts registration
91977 +*//***************************************************************************/
91978 +enum fman_event_modules {
91979 + E_FMAN_MOD_PRS, /**< Parser event */
91980 + E_FMAN_MOD_KG, /**< Keygen event */
91981 + E_FMAN_MOD_PLCR, /**< Policer event */
91982 + E_FMAN_MOD_10G_MAC, /**< 10G MAC event */
91983 + E_FMAN_MOD_1G_MAC, /**< 1G MAC event */
91984 + E_FMAN_MOD_TMR, /**< Timer event */
91985 + E_FMAN_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
91986 + E_FMAN_MOD_MACSEC,
91987 + E_FMAN_MOD_DUMMY_LAST
91988 +};
91989 +
91990 +/**************************************************************************//**
91991 + @Description Enum for interrupts types
91992 +*//***************************************************************************/
91993 +enum fman_intr_type {
91994 + E_FMAN_INTR_TYPE_ERR,
91995 + E_FMAN_INTR_TYPE_NORMAL
91996 +};
91997 +
91998 +/**************************************************************************//**
91999 + @Description enum for defining MAC types
92000 +*//***************************************************************************/
92001 +enum fman_mac_type {
92002 + E_FMAN_MAC_10G = 0, /**< 10G MAC */
92003 + E_FMAN_MAC_1G /**< 1G MAC */
92004 +};
92005 +
92006 +enum fman_mac_exceptions {
92007 + E_FMAN_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0,
92008 + /**< 10GEC MDIO scan event interrupt */
92009 + E_FMAN_MAC_EX_10G_MDIO_CMD_CMPL,
92010 + /**< 10GEC MDIO command completion interrupt */
92011 + E_FMAN_MAC_EX_10G_REM_FAULT,
92012 + /**< 10GEC, mEMAC Remote fault interrupt */
92013 + E_FMAN_MAC_EX_10G_LOC_FAULT,
92014 + /**< 10GEC, mEMAC Local fault interrupt */
92015 + E_FMAN_MAC_EX_10G_1TX_ECC_ER,
92016 + /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
92017 + E_FMAN_MAC_EX_10G_TX_FIFO_UNFL,
92018 + /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
92019 + E_FMAN_MAC_EX_10G_TX_FIFO_OVFL,
92020 + /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
92021 + E_FMAN_MAC_EX_10G_TX_ER,
92022 + /**< 10GEC Transmit frame error interrupt */
92023 + E_FMAN_MAC_EX_10G_RX_FIFO_OVFL,
92024 + /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
92025 + E_FMAN_MAC_EX_10G_RX_ECC_ER,
92026 + /**< 10GEC, mEMAC Receive frame ECC error interrupt */
92027 + E_FMAN_MAC_EX_10G_RX_JAB_FRM,
92028 + /**< 10GEC Receive jabber frame interrupt */
92029 + E_FMAN_MAC_EX_10G_RX_OVRSZ_FRM,
92030 + /**< 10GEC Receive oversized frame interrupt */
92031 + E_FMAN_MAC_EX_10G_RX_RUNT_FRM,
92032 + /**< 10GEC Receive runt frame interrupt */
92033 + E_FMAN_MAC_EX_10G_RX_FRAG_FRM,
92034 + /**< 10GEC Receive fragment frame interrupt */
92035 + E_FMAN_MAC_EX_10G_RX_LEN_ER,
92036 + /**< 10GEC Receive payload length error interrupt */
92037 + E_FMAN_MAC_EX_10G_RX_CRC_ER,
92038 + /**< 10GEC Receive CRC error interrupt */
92039 + E_FMAN_MAC_EX_10G_RX_ALIGN_ER,
92040 + /**< 10GEC Receive alignment error interrupt */
92041 + E_FMAN_MAC_EX_1G_BAB_RX,
92042 + /**< dTSEC Babbling receive error */
92043 + E_FMAN_MAC_EX_1G_RX_CTL,
92044 + /**< dTSEC Receive control (pause frame) interrupt */
92045 + E_FMAN_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET,
92046 + /**< dTSEC Graceful transmit stop complete */
92047 + E_FMAN_MAC_EX_1G_BAB_TX,
92048 + /**< dTSEC Babbling transmit error */
92049 + E_FMAN_MAC_EX_1G_TX_CTL,
92050 + /**< dTSEC Transmit control (pause frame) interrupt */
92051 + E_FMAN_MAC_EX_1G_TX_ERR,
92052 + /**< dTSEC Transmit error */
92053 + E_FMAN_MAC_EX_1G_LATE_COL,
92054 + /**< dTSEC Late collision */
92055 + E_FMAN_MAC_EX_1G_COL_RET_LMT,
92056 + /**< dTSEC Collision retry limit */
92057 + E_FMAN_MAC_EX_1G_TX_FIFO_UNDRN,
92058 + /**< dTSEC Transmit FIFO underrun */
92059 + E_FMAN_MAC_EX_1G_MAG_PCKT,
92060 + /**< dTSEC Magic Packet detection */
92061 + E_FMAN_MAC_EX_1G_MII_MNG_RD_COMPLET,
92062 + /**< dTSEC MII management read completion */
92063 + E_FMAN_MAC_EX_1G_MII_MNG_WR_COMPLET,
92064 + /**< dTSEC MII management write completion */
92065 + E_FMAN_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET,
92066 + /**< dTSEC Graceful receive stop complete */
92067 + E_FMAN_MAC_EX_1G_TX_DATA_ERR,
92068 + /**< dTSEC Internal data error on transmit */
92069 + E_FMAN_MAC_EX_1G_RX_DATA_ERR,
92070 + /**< dTSEC Internal data error on receive */
92071 + E_FMAN_MAC_EX_1G_1588_TS_RX_ERR,
92072 + /**< dTSEC Time-Stamp Receive Error */
92073 + E_FMAN_MAC_EX_1G_RX_MIB_CNT_OVFL,
92074 + /**< dTSEC MIB counter overflow */
92075 + E_FMAN_MAC_EX_TS_FIFO_ECC_ERR,
92076 + /**< mEMAC Time-stamp FIFO ECC error interrupt;
92077 + not supported on T4240/B4860 rev1 chips */
92078 +};
92079 +
92080 +#define ENET_IF_SGMII_BASEX 0x80000000
92081 + /**< SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
92082 + and phy or backplane;
92083 + Note: 1000BaseX auto-negotiation relates only to interface between MAC
92084 + and phy/backplane, SGMII phy can still synchronize with far-end phy at
92085 + 10Mbps, 100Mbps or 1000Mbps */
92086 +
92087 +enum enet_mode {
92088 + E_ENET_MODE_INVALID = 0,
92089 + /**< Invalid Ethernet mode */
92090 + E_ENET_MODE_MII_10 = (E_ENET_IF_MII | E_ENET_SPEED_10),
92091 + /**< 10 Mbps MII */
92092 + E_ENET_MODE_MII_100 = (E_ENET_IF_MII | E_ENET_SPEED_100),
92093 + /**< 100 Mbps MII */
92094 + E_ENET_MODE_RMII_10 = (E_ENET_IF_RMII | E_ENET_SPEED_10),
92095 + /**< 10 Mbps RMII */
92096 + E_ENET_MODE_RMII_100 = (E_ENET_IF_RMII | E_ENET_SPEED_100),
92097 + /**< 100 Mbps RMII */
92098 + E_ENET_MODE_SMII_10 = (E_ENET_IF_SMII | E_ENET_SPEED_10),
92099 + /**< 10 Mbps SMII */
92100 + E_ENET_MODE_SMII_100 = (E_ENET_IF_SMII | E_ENET_SPEED_100),
92101 + /**< 100 Mbps SMII */
92102 + E_ENET_MODE_GMII_1000 = (E_ENET_IF_GMII | E_ENET_SPEED_1000),
92103 + /**< 1000 Mbps GMII */
92104 + E_ENET_MODE_RGMII_10 = (E_ENET_IF_RGMII | E_ENET_SPEED_10),
92105 + /**< 10 Mbps RGMII */
92106 + E_ENET_MODE_RGMII_100 = (E_ENET_IF_RGMII | E_ENET_SPEED_100),
92107 + /**< 100 Mbps RGMII */
92108 + E_ENET_MODE_RGMII_1000 = (E_ENET_IF_RGMII | E_ENET_SPEED_1000),
92109 + /**< 1000 Mbps RGMII */
92110 + E_ENET_MODE_TBI_1000 = (E_ENET_IF_TBI | E_ENET_SPEED_1000),
92111 + /**< 1000 Mbps TBI */
92112 + E_ENET_MODE_RTBI_1000 = (E_ENET_IF_RTBI | E_ENET_SPEED_1000),
92113 + /**< 1000 Mbps RTBI */
92114 + E_ENET_MODE_SGMII_10 = (E_ENET_IF_SGMII | E_ENET_SPEED_10),
92115 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
92116 + SGMII phy according to Cisco SGMII specification */
92117 + E_ENET_MODE_SGMII_100 = (E_ENET_IF_SGMII | E_ENET_SPEED_100),
92118 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
92119 + SGMII phy according to Cisco SGMII specification */
92120 + E_ENET_MODE_SGMII_1000 = (E_ENET_IF_SGMII | E_ENET_SPEED_1000),
92121 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
92122 + SGMII phy according to Cisco SGMII specification */
92123 + E_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92124 + | E_ENET_SPEED_10),
92125 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
92126 + MAC and SGMII phy or backplane */
92127 + E_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92128 + | E_ENET_SPEED_100),
92129 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
92130 + MAC and SGMII phy or backplane */
92131 + E_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92132 + | E_ENET_SPEED_1000),
92133 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
92134 + MAC and SGMII phy or backplane */
92135 + E_ENET_MODE_QSGMII_1000 = (E_ENET_IF_QSGMII | E_ENET_SPEED_1000),
92136 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
92137 + QSGMII phy according to Cisco QSGMII specification */
92138 + E_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_QSGMII
92139 + | E_ENET_SPEED_1000),
92140 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
92141 + MAC and QSGMII phy or backplane */
92142 + E_ENET_MODE_XGMII_10000 = (E_ENET_IF_XGMII | E_ENET_SPEED_10000),
92143 + /**< 10000 Mbps XGMII */
92144 + E_ENET_MODE_XFI_10000 = (E_ENET_IF_XFI | E_ENET_SPEED_10000)
92145 + /**< 10000 Mbps XFI */
92146 +};
92147 +
92148 +enum fmam_mac_statistics_level {
92149 + E_FMAN_MAC_NONE_STATISTICS, /**< No statistics */
92150 + E_FMAN_MAC_PARTIAL_STATISTICS, /**< Only error counters are available;
92151 + Optimized for performance */
92152 + E_FMAN_MAC_FULL_STATISTICS /**< All counters available; Not
92153 + optimized for performance */
92154 +};
92155 +
92156 +#define _MAKE_ENET_MODE(_interface, _speed) (enum enet_mode)((_interface) \
92157 + | (_speed))
92158 +
92159 +#define _ENET_INTERFACE_FROM_MODE(mode) (enum enet_interface) \
92160 + ((mode) & 0x0FFF0000)
92161 +#define _ENET_SPEED_FROM_MODE(mode) (enum enet_speed)((mode) & 0x0000FFFF)
92162 +#define _ENET_ADDR_TO_UINT64(_enet_addr) \
92163 + (uint64_t)(((uint64_t)(_enet_addr)[0] << 40) | \
92164 + ((uint64_t)(_enet_addr)[1] << 32) | \
92165 + ((uint64_t)(_enet_addr)[2] << 24) | \
92166 + ((uint64_t)(_enet_addr)[3] << 16) | \
92167 + ((uint64_t)(_enet_addr)[4] << 8) | \
92168 + ((uint64_t)(_enet_addr)[5]))
92169 +
92170 +#define _MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \
92171 + do { \
92172 + int i; \
92173 + for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
92174 + (_enet_addr)[i] = (uint8_t)((_addr64) >> ((5-i)*8));\
92175 + } while (0)
92176 +
92177 +#endif /* __FSL_ENET_H */
92178 --- /dev/null
92179 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
92180 @@ -0,0 +1,825 @@
92181 +/*
92182 + * Copyright 2013 Freescale Semiconductor Inc.
92183 + *
92184 + * Redistribution and use in source and binary forms, with or without
92185 + * modification, are permitted provided that the following conditions are met:
92186 + * * Redistributions of source code must retain the above copyright
92187 + * notice, this list of conditions and the following disclaimer.
92188 + * * Redistributions in binary form must reproduce the above copyright
92189 + * notice, this list of conditions and the following disclaimer in the
92190 + * documentation and/or other materials provided with the distribution.
92191 + * * Neither the name of Freescale Semiconductor nor the
92192 + * names of its contributors may be used to endorse or promote products
92193 + * derived from this software without specific prior written permission.
92194 + *
92195 + *
92196 + * ALTERNATIVELY, this software may be distributed under the terms of the
92197 + * GNU General Public License ("GPL") as published by the Free Software
92198 + * Foundation, either version 2 of that License or (at your option) any
92199 + * later version.
92200 + *
92201 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92202 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92203 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92204 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92205 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92206 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92207 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92208 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92209 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92210 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92211 + */
92212 +
92213 +#ifndef __FSL_FMAN_H
92214 +#define __FSL_FMAN_H
92215 +
92216 +#include "common/general.h"
92217 +
92218 +struct fman_ext_pool_params {
92219 + uint8_t id; /**< External buffer pool id */
92220 + uint16_t size; /**< External buffer pool buffer size */
92221 +};
92222 +
92223 +struct fman_ext_pools {
92224 + uint8_t num_pools_used; /**< Number of pools use by this port */
92225 + struct fman_ext_pool_params *ext_buf_pool;
92226 + /**< Parameters for each port */
92227 +};
92228 +
92229 +struct fman_backup_bm_pools {
92230 + uint8_t num_backup_pools; /**< Number of BM backup pools -
92231 + must be smaller than the total number
92232 + of pools defined for the specified
92233 + port.*/
92234 + uint8_t *pool_ids; /**< numOfBackupPools pool id's,
92235 + specifying which pools should be used
92236 + only as backup. Pool id's specified
92237 + here must be a subset of the pools
92238 + used by the specified port.*/
92239 +};
92240 +
92241 +/**************************************************************************//**
92242 + @Description A structure for defining BM pool depletion criteria
92243 +*//***************************************************************************/
92244 +struct fman_buf_pool_depletion {
92245 + bool buf_pool_depletion_enabled;
92246 + bool pools_grp_mode_enable; /**< select mode in which pause frames
92247 + will be sent after a number of pools
92248 + (all together!) are depleted */
92249 + uint8_t num_pools; /**< the number of depleted pools that
92250 + will invoke pause frames transmission.
92251 + */
92252 + bool *pools_to_consider; /**< For each pool, TRUE if it should be
92253 + considered for depletion (Note - this
92254 + pool must be used by this port!). */
92255 + bool single_pool_mode_enable; /**< select mode in which pause frames
92256 + will be sent after a single-pool
92257 + is depleted; */
92258 + bool *pools_to_consider_for_single_mode;
92259 + /**< For each pool, TRUE if it should be
92260 + considered for depletion (Note - this
92261 + pool must be used by this port!) */
92262 + bool has_pfc_priorities;
92263 + bool *pfc_priorities_en; /**< This field is used by the MAC as
92264 + the Priority Enable Vector in the PFC
92265 + frame which is transmitted */
92266 +};
92267 +
92268 +/**************************************************************************//**
92269 + @Description Enum for defining port DMA swap mode
92270 +*//***************************************************************************/
92271 +enum fman_dma_swap_option {
92272 + FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
92273 + FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
92274 + in PowerPc Little Endian mode. */
92275 + FMAN_DMA_SWP_BE /**< The transferred data should be swapped
92276 + in Big Endian mode */
92277 +};
92278 +
92279 +/**************************************************************************//**
92280 + @Description Enum for defining port DMA cache attributes
92281 +*//***************************************************************************/
92282 +enum fman_dma_cache_option {
92283 + FMAN_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */
92284 + FMAN_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */
92285 +};
92286 +
92287 +typedef struct t_FmPrsResult fm_prs_result_t;
92288 +typedef enum e_EnetMode enet_mode_t;
92289 +typedef t_Handle handle_t;
92290 +
92291 +struct fman_revision_info {
92292 + uint8_t majorRev; /**< Major revision */
92293 + uint8_t minorRev; /**< Minor revision */
92294 +};
92295 +
92296 +/* sizes */
92297 +#define CAPWAP_FRAG_EXTRA_SPACE 32
92298 +#define OFFSET_UNITS 16
92299 +#define MAX_INT_OFFSET 240
92300 +#define MAX_IC_SIZE 256
92301 +#define MAX_EXT_OFFSET 496
92302 +#define MAX_EXT_BUFFER_OFFSET 511
92303 +
92304 +/**************************************************************************
92305 + @Description Memory Mapped Registers
92306 +***************************************************************************/
92307 +#define FMAN_LIODN_TBL 64 /* size of LIODN table */
92308 +
92309 +struct fman_fpm_regs {
92310 + uint32_t fmfp_tnc; /**< FPM TNUM Control 0x00 */
92311 + uint32_t fmfp_prc; /**< FPM Port_ID FmCtl Association 0x04 */
92312 + uint32_t fmfp_brkc; /**< FPM Breakpoint Control 0x08 */
92313 + uint32_t fmfp_mxd; /**< FPM Flush Control 0x0c */
92314 + uint32_t fmfp_dist1; /**< FPM Dispatch Thresholds1 0x10 */
92315 + uint32_t fmfp_dist2; /**< FPM Dispatch Thresholds2 0x14 */
92316 + uint32_t fm_epi; /**< FM Error Pending Interrupts 0x18 */
92317 + uint32_t fm_rie; /**< FM Error Interrupt Enable 0x1c */
92318 + uint32_t fmfp_fcev[4]; /**< FPM FMan-Controller Event 1-4 0x20-0x2f */
92319 + uint32_t res0030[4]; /**< res 0x30 - 0x3f */
92320 + uint32_t fmfp_cee[4]; /**< PM FMan-Controller Event 1-4 0x40-0x4f */
92321 + uint32_t res0050[4]; /**< res 0x50-0x5f */
92322 + uint32_t fmfp_tsc1; /**< FPM TimeStamp Control1 0x60 */
92323 + uint32_t fmfp_tsc2; /**< FPM TimeStamp Control2 0x64 */
92324 + uint32_t fmfp_tsp; /**< FPM Time Stamp 0x68 */
92325 + uint32_t fmfp_tsf; /**< FPM Time Stamp Fraction 0x6c */
92326 + uint32_t fm_rcr; /**< FM Rams Control 0x70 */
92327 + uint32_t fmfp_extc; /**< FPM External Requests Control 0x74 */
92328 + uint32_t fmfp_ext1; /**< FPM External Requests Config1 0x78 */
92329 + uint32_t fmfp_ext2; /**< FPM External Requests Config2 0x7c */
92330 + uint32_t fmfp_drd[16]; /**< FPM Data_Ram Data 0-15 0x80 - 0xbf */
92331 + uint32_t fmfp_dra; /**< FPM Data Ram Access 0xc0 */
92332 + uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 0xc4 */
92333 + uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 0xc8 */
92334 + uint32_t fm_rstc; /**< FM Reset Command 0xcc */
92335 + uint32_t fm_cld; /**< FM Classifier Debug 0xd0 */
92336 + uint32_t fm_npi; /**< FM Normal Pending Interrupts 0xd4 */
92337 + uint32_t fmfp_exte; /**< FPM External Requests Enable 0xd8 */
92338 + uint32_t fmfp_ee; /**< FPM Event & Mask 0xdc */
92339 + uint32_t fmfp_cev[4]; /**< FPM CPU Event 1-4 0xe0-0xef */
92340 + uint32_t res00f0[4]; /**< res 0xf0-0xff */
92341 + uint32_t fmfp_ps[64]; /**< FPM Port Status 0x100-0x1ff */
92342 + uint32_t fmfp_clfabc; /**< FPM CLFABC 0x200 */
92343 + uint32_t fmfp_clfcc; /**< FPM CLFCC 0x204 */
92344 + uint32_t fmfp_clfaval; /**< FPM CLFAVAL 0x208 */
92345 + uint32_t fmfp_clfbval; /**< FPM CLFBVAL 0x20c */
92346 + uint32_t fmfp_clfcval; /**< FPM CLFCVAL 0x210 */
92347 + uint32_t fmfp_clfamsk; /**< FPM CLFAMSK 0x214 */
92348 + uint32_t fmfp_clfbmsk; /**< FPM CLFBMSK 0x218 */
92349 + uint32_t fmfp_clfcmsk; /**< FPM CLFCMSK 0x21c */
92350 + uint32_t fmfp_clfamc; /**< FPM CLFAMC 0x220 */
92351 + uint32_t fmfp_clfbmc; /**< FPM CLFBMC 0x224 */
92352 + uint32_t fmfp_clfcmc; /**< FPM CLFCMC 0x228 */
92353 + uint32_t fmfp_decceh; /**< FPM DECCEH 0x22c */
92354 + uint32_t res0230[116]; /**< res 0x230 - 0x3ff */
92355 + uint32_t fmfp_ts[128]; /**< 0x400: FPM Task Status 0x400 - 0x5ff */
92356 + uint32_t res0600[0x400 - 384];
92357 +};
92358 +
92359 +struct fman_bmi_regs {
92360 + uint32_t fmbm_init; /**< BMI Initialization 0x00 */
92361 + uint32_t fmbm_cfg1; /**< BMI Configuration 1 0x04 */
92362 + uint32_t fmbm_cfg2; /**< BMI Configuration 2 0x08 */
92363 + uint32_t res000c[5]; /**< 0x0c - 0x1f */
92364 + uint32_t fmbm_ievr; /**< Interrupt Event Register 0x20 */
92365 + uint32_t fmbm_ier; /**< Interrupt Enable Register 0x24 */
92366 + uint32_t fmbm_ifr; /**< Interrupt Force Register 0x28 */
92367 + uint32_t res002c[5]; /**< 0x2c - 0x3f */
92368 + uint32_t fmbm_arb[8]; /**< BMI Arbitration 0x40 - 0x5f */
92369 + uint32_t res0060[12]; /**<0x60 - 0x8f */
92370 + uint32_t fmbm_dtc[3]; /**< Debug Trap Counter 0x90 - 0x9b */
92371 + uint32_t res009c; /**< 0x9c */
92372 + uint32_t fmbm_dcv[3][4]; /**< Debug Compare val 0xa0-0xcf */
92373 + uint32_t fmbm_dcm[3][4]; /**< Debug Compare Mask 0xd0-0xff */
92374 + uint32_t fmbm_gde; /**< BMI Global Debug Enable 0x100 */
92375 + uint32_t fmbm_pp[63]; /**< BMI Port Parameters 0x104 - 0x1ff */
92376 + uint32_t res0200; /**< 0x200 */
92377 + uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size 0x204 - 0x2ff */
92378 + uint32_t res0300; /**< 0x300 */
92379 + uint32_t fmbm_spliodn[63]; /**< Port Partition ID 0x304 - 0x3ff */
92380 +};
92381 +
92382 +struct fman_qmi_regs {
92383 + uint32_t fmqm_gc; /**< General Configuration Register 0x00 */
92384 + uint32_t res0004; /**< 0x04 */
92385 + uint32_t fmqm_eie; /**< Error Interrupt Event Register 0x08 */
92386 + uint32_t fmqm_eien; /**< Error Interrupt Enable Register 0x0c */
92387 + uint32_t fmqm_eif; /**< Error Interrupt Force Register 0x10 */
92388 + uint32_t fmqm_ie; /**< Interrupt Event Register 0x14 */
92389 + uint32_t fmqm_ien; /**< Interrupt Enable Register 0x18 */
92390 + uint32_t fmqm_if; /**< Interrupt Force Register 0x1c */
92391 + uint32_t fmqm_gs; /**< Global Status Register 0x20 */
92392 + uint32_t fmqm_ts; /**< Task Status Register 0x24 */
92393 + uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter 0x28 */
92394 + uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter 0x2c */
92395 + uint32_t fmqm_dc0; /**< Dequeue Counter 0 0x30 */
92396 + uint32_t fmqm_dc1; /**< Dequeue Counter 1 0x34 */
92397 + uint32_t fmqm_dc2; /**< Dequeue Counter 2 0x38 */
92398 + uint32_t fmqm_dc3; /**< Dequeue Counter 3 0x3c */
92399 + uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter 0x40 */
92400 + uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter 0x44 */
92401 + uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter 0x48 */
92402 + uint32_t fmqm_dcc; /**< Dequeue Confirm Counter 0x4c */
92403 + uint32_t res0050[7]; /**< 0x50 - 0x6b */
92404 + uint32_t fmqm_tapc; /**< Tnum Aging Period Control 0x6c */
92405 + uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter 0x70 */
92406 + uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter 0x74 */
92407 + uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter 0x78 */
92408 + uint32_t res007c; /**< 0x7c */
92409 + uint32_t fmqm_dtc; /**< 0x80 Debug Trap Counter 0x80 */
92410 + uint32_t fmqm_efddd; /**< 0x84 Enqueue Frame desc Dynamic dbg 0x84 */
92411 + uint32_t res0088[2]; /**< 0x88 - 0x8f */
92412 + struct {
92413 + uint32_t fmqm_dtcfg1; /**< 0x90 dbg trap cfg 1 Register 0x00 */
92414 + uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register 0x04 */
92415 + uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register 0x08 */
92416 + uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register 0x0c */
92417 + uint32_t fmqm_dtcfg2; /**< dbg Trap cfg 2 Register 0x10 */
92418 + uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register 0x14 */
92419 + uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register 0x18 */
92420 + uint32_t res001c; /**< 0x1c */
92421 + } dbg_traps[3]; /**< 0x90 - 0xef */
92422 + uint8_t res00f0[0x400 - 0xf0]; /**< 0xf0 - 0x3ff */
92423 +};
92424 +
92425 +struct fman_dma_regs {
92426 + uint32_t fmdmsr; /**< FM DMA status register 0x00 */
92427 + uint32_t fmdmmr; /**< FM DMA mode register 0x04 */
92428 + uint32_t fmdmtr; /**< FM DMA bus threshold register 0x08 */
92429 + uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x0c */
92430 + uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x10 */
92431 + uint32_t fmdmtah; /**< FM DMA transfer bus address high reg 0x14 */
92432 + uint32_t fmdmtal; /**< FM DMA transfer bus address low reg 0x18 */
92433 + uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID reg 0x1c */
92434 + uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x20 */
92435 + uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x24 */
92436 + uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x28 */
92437 + uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x2c */
92438 + uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug reg 0x30 */
92439 + uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value reg #1 0x34 */
92440 + uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value reg #2 0x38 */
92441 + uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x3c */
92442 + uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x40 */
92443 + uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x44 */
92444 + uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Cntr 0x48 */
92445 + uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Cntr 0x4c */
92446 + uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x50 */
92447 + uint32_t fmdmdcr; /**< FM DMA Debug Counter 0x54 */
92448 + uint32_t fmdmemsr; /**< FM DMA Emergency Smoother Register 0x58 */
92449 + uint32_t res005c; /**< 0x5c */
92450 + uint32_t fmdmplr[FMAN_LIODN_TBL / 2]; /**< DMA LIODN regs 0x60-0xdf */
92451 + uint32_t res00e0[0x400 - 56];
92452 +};
92453 +
92454 +struct fman_rg {
92455 + struct fman_fpm_regs *fpm_rg;
92456 + struct fman_dma_regs *dma_rg;
92457 + struct fman_bmi_regs *bmi_rg;
92458 + struct fman_qmi_regs *qmi_rg;
92459 +};
92460 +
92461 +enum fman_dma_cache_override {
92462 + E_FMAN_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
92463 + E_FMAN_DMA_NO_STASH_DATA, /**< No data stashing in system level cache */
92464 + E_FMAN_DMA_MAY_STASH_DATA, /**< Stashing allowed in sys level cache */
92465 + E_FMAN_DMA_STASH_DATA /**< Stashing performed in system level cache */
92466 +};
92467 +
92468 +enum fman_dma_aid_mode {
92469 + E_FMAN_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
92470 + E_FMAN_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
92471 +};
92472 +
92473 +enum fman_dma_dbg_cnt_mode {
92474 + E_FMAN_DMA_DBG_NO_CNT = 0, /**< No counting */
92475 + E_FMAN_DMA_DBG_CNT_DONE, /**< Count DONE commands */
92476 + E_FMAN_DMA_DBG_CNT_COMM_Q_EM, /**< command Q emergency signal */
92477 + E_FMAN_DMA_DBG_CNT_INT_READ_EM, /**< Read buf emergency signal */
92478 + E_FMAN_DMA_DBG_CNT_INT_WRITE_EM, /**< Write buf emergency signal */
92479 + E_FMAN_DMA_DBG_CNT_FPM_WAIT, /**< FPM WAIT signal */
92480 + E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors */
92481 + E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT /**< RAW & WAR protection counter */
92482 +};
92483 +
92484 +enum fman_dma_emergency_level {
92485 + E_FMAN_DMA_EM_EBS = 0, /**< EBS emergency */
92486 + E_FMAN_DMA_EM_SOS /**< SOS emergency */
92487 +};
92488 +
92489 +enum fman_catastrophic_err {
92490 + E_FMAN_CATAST_ERR_STALL_PORT = 0, /**< Port_ID stalled reset required */
92491 + E_FMAN_CATAST_ERR_STALL_TASK /**< Only erroneous task is stalled */
92492 +};
92493 +
92494 +enum fman_dma_err {
92495 + E_FMAN_DMA_ERR_CATASTROPHIC = 0, /**< Catastrophic DMA error */
92496 + E_FMAN_DMA_ERR_REPORT /**< Reported DMA error */
92497 +};
92498 +
92499 +struct fman_cfg {
92500 + uint16_t liodn_bs_pr_port[FMAN_LIODN_TBL];/* base per port */
92501 + bool en_counters;
92502 + uint8_t disp_limit_tsh;
92503 + uint8_t prs_disp_tsh;
92504 + uint8_t plcr_disp_tsh;
92505 + uint8_t kg_disp_tsh;
92506 + uint8_t bmi_disp_tsh;
92507 + uint8_t qmi_enq_disp_tsh;
92508 + uint8_t qmi_deq_disp_tsh;
92509 + uint8_t fm_ctl1_disp_tsh;
92510 + uint8_t fm_ctl2_disp_tsh;
92511 + enum fman_dma_cache_override dma_cache_override;
92512 + enum fman_dma_aid_mode dma_aid_mode;
92513 + bool dma_aid_override;
92514 + uint8_t dma_axi_dbg_num_of_beats;
92515 + uint8_t dma_cam_num_of_entries;
92516 + uint32_t dma_watchdog;
92517 + uint8_t dma_comm_qtsh_asrt_emer;
92518 + uint8_t dma_write_buf_tsh_asrt_emer;
92519 + uint8_t dma_read_buf_tsh_asrt_emer;
92520 + uint8_t dma_comm_qtsh_clr_emer;
92521 + uint8_t dma_write_buf_tsh_clr_emer;
92522 + uint8_t dma_read_buf_tsh_clr_emer;
92523 + uint32_t dma_sos_emergency;
92524 + enum fman_dma_dbg_cnt_mode dma_dbg_cnt_mode;
92525 + bool dma_stop_on_bus_error;
92526 + bool dma_en_emergency;
92527 + uint32_t dma_emergency_bus_select;
92528 + enum fman_dma_emergency_level dma_emergency_level;
92529 + bool dma_en_emergency_smoother;
92530 + uint32_t dma_emergency_switch_counter;
92531 + bool halt_on_external_activ;
92532 + bool halt_on_unrecov_ecc_err;
92533 + enum fman_catastrophic_err catastrophic_err;
92534 + enum fman_dma_err dma_err;
92535 + bool en_muram_test_mode;
92536 + bool en_iram_test_mode;
92537 + bool external_ecc_rams_enable;
92538 + uint16_t tnum_aging_period;
92539 + uint32_t exceptions;
92540 + uint16_t clk_freq;
92541 + bool pedantic_dma;
92542 + uint32_t cam_base_addr;
92543 + uint32_t fifo_base_addr;
92544 + uint32_t total_fifo_size;
92545 + uint8_t total_num_of_tasks;
92546 + bool qmi_deq_option_support;
92547 + uint32_t qmi_def_tnums_thresh;
92548 + bool fman_partition_array;
92549 + uint8_t num_of_fman_ctrl_evnt_regs;
92550 +};
92551 +
92552 +/**************************************************************************//**
92553 + @Description Exceptions
92554 +*//***************************************************************************/
92555 +#define FMAN_EX_DMA_BUS_ERROR 0x80000000
92556 +#define FMAN_EX_DMA_READ_ECC 0x40000000
92557 +#define FMAN_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
92558 +#define FMAN_EX_DMA_FM_WRITE_ECC 0x10000000
92559 +#define FMAN_EX_FPM_STALL_ON_TASKS 0x08000000
92560 +#define FMAN_EX_FPM_SINGLE_ECC 0x04000000
92561 +#define FMAN_EX_FPM_DOUBLE_ECC 0x02000000
92562 +#define FMAN_EX_QMI_SINGLE_ECC 0x01000000
92563 +#define FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000
92564 +#define FMAN_EX_QMI_DOUBLE_ECC 0x00400000
92565 +#define FMAN_EX_BMI_LIST_RAM_ECC 0x00200000
92566 +#define FMAN_EX_BMI_PIPELINE_ECC 0x00100000
92567 +#define FMAN_EX_BMI_STATISTICS_RAM_ECC 0x00080000
92568 +#define FMAN_EX_IRAM_ECC 0x00040000
92569 +#define FMAN_EX_NURAM_ECC 0x00020000
92570 +#define FMAN_EX_BMI_DISPATCH_RAM_ECC 0x00010000
92571 +
92572 +enum fman_exceptions {
92573 + E_FMAN_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
92574 + E_FMAN_EX_DMA_READ_ECC, /**< Read Buffer ECC error */
92575 + E_FMAN_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC err on sys side */
92576 + E_FMAN_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */
92577 + E_FMAN_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
92578 + E_FMAN_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
92579 + E_FMAN_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
92580 + E_FMAN_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
92581 + E_FMAN_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
92582 + E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< DeQ from unknown port id */
92583 + E_FMAN_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
92584 + E_FMAN_EX_BMI_STORAGE_PROFILE_ECC, /**< storage profile */
92585 + E_FMAN_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics RAM ECC Err Enable */
92586 + E_FMAN_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
92587 + E_FMAN_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
92588 + E_FMAN_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
92589 +};
92590 +
92591 +enum fman_counters {
92592 + E_FMAN_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI tot enQ frames counter */
92593 + E_FMAN_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI tot deQ frames counter */
92594 + E_FMAN_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
92595 + E_FMAN_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
92596 + E_FMAN_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
92597 + E_FMAN_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
92598 + E_FMAN_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI deQ from dflt queue cntr */
92599 + E_FMAN_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI deQ from FQ context cntr */
92600 + E_FMAN_COUNTERS_DEQ_FROM_FD, /**< QMI deQ from FD command field cntr */
92601 + E_FMAN_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
92602 + E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA full entry cntr */
92603 + E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA full CAM Q cntr */
92604 + E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA sync counter */
92605 +};
92606 +
92607 +#define FPM_PRT_FM_CTL1 0x00000001
92608 +#define FPM_PRT_FM_CTL2 0x00000002
92609 +
92610 +/**************************************************************************//**
92611 + @Description DMA definitions
92612 +*//***************************************************************************/
92613 +
92614 +/* masks */
92615 +#define DMA_MODE_AID_OR 0x20000000
92616 +#define DMA_MODE_SBER 0x10000000
92617 +#define DMA_MODE_BER 0x00200000
92618 +#define DMA_MODE_EB 0x00100000
92619 +#define DMA_MODE_ECC 0x00000020
92620 +#define DMA_MODE_PRIVILEGE_PROT 0x00001000
92621 +#define DMA_MODE_SECURE_PROT 0x00000800
92622 +#define DMA_MODE_EMER_READ 0x00080000
92623 +#define DMA_MODE_EMER_WRITE 0x00040000
92624 +#define DMA_MODE_CACHE_OR_MASK 0xC0000000
92625 +#define DMA_MODE_CEN_MASK 0x0000E000
92626 +#define DMA_MODE_DBG_MASK 0x00000380
92627 +#define DMA_MODE_AXI_DBG_MASK 0x0F000000
92628 +
92629 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
92630 +
92631 +#define DMA_TRANSFER_PORTID_MASK 0xFF000000
92632 +#define DMA_TRANSFER_TNUM_MASK 0x00FF0000
92633 +#define DMA_TRANSFER_LIODN_MASK 0x00000FFF
92634 +
92635 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
92636 +#define DMA_LOW_LIODN_MASK 0x00000FFF
92637 +
92638 +#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000
92639 +#define DMA_STATUS_BUS_ERR 0x08000000
92640 +#define DMA_STATUS_READ_ECC 0x04000000
92641 +#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000
92642 +#define DMA_STATUS_FM_WRITE_ECC 0x01000000
92643 +#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000
92644 +#define DMA_STATUS_FM_DPEXT_ECC 0x00400000
92645 +#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000
92646 +#define DMA_STATUS_FM_DPDAT_ECC 0x00100000
92647 +#define DMA_STATUS_FM_SPDAT_ECC 0x00080000
92648 +
92649 +#define FM_LIODN_BASE_MASK 0x00000FFF
92650 +
92651 +/* shifts */
92652 +#define DMA_MODE_CACHE_OR_SHIFT 30
92653 +#define DMA_MODE_BUS_PRI_SHIFT 16
92654 +#define DMA_MODE_AXI_DBG_SHIFT 24
92655 +#define DMA_MODE_CEN_SHIFT 13
92656 +#define DMA_MODE_BUS_PROT_SHIFT 10
92657 +#define DMA_MODE_DBG_SHIFT 7
92658 +#define DMA_MODE_EMER_LVL_SHIFT 6
92659 +#define DMA_MODE_AID_MODE_SHIFT 4
92660 +#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16
92661 +#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32
92662 +
92663 +#define DMA_THRESH_COMMQ_SHIFT 24
92664 +#define DMA_THRESH_READ_INT_BUF_SHIFT 16
92665 +
92666 +#define DMA_LIODN_SHIFT 16
92667 +
92668 +#define DMA_TRANSFER_PORTID_SHIFT 24
92669 +#define DMA_TRANSFER_TNUM_SHIFT 16
92670 +
92671 +/* sizes */
92672 +#define DMA_MAX_WATCHDOG 0xffffffff
92673 +
92674 +/* others */
92675 +#define DMA_CAM_SIZEOF_ENTRY 0x40
92676 +#define DMA_CAM_ALIGN 0x1000
92677 +#define DMA_CAM_UNITS 8
92678 +
92679 +/**************************************************************************//**
92680 + @Description General defines
92681 +*//***************************************************************************/
92682 +
92683 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
92684 +#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL
92685 +
92686 +/**************************************************************************//**
92687 + @Description FPM defines
92688 +*//***************************************************************************/
92689 +
92690 +/* masks */
92691 +#define FPM_EV_MASK_DOUBLE_ECC 0x80000000
92692 +#define FPM_EV_MASK_STALL 0x40000000
92693 +#define FPM_EV_MASK_SINGLE_ECC 0x20000000
92694 +#define FPM_EV_MASK_RELEASE_FM 0x00010000
92695 +#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000
92696 +#define FPM_EV_MASK_STALL_EN 0x00004000
92697 +#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000
92698 +#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008
92699 +#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004
92700 +
92701 +#define FPM_RAM_RAMS_ECC_EN 0x80000000
92702 +#define FPM_RAM_IRAM_ECC_EN 0x40000000
92703 +#define FPM_RAM_MURAM_ECC 0x00008000
92704 +#define FPM_RAM_IRAM_ECC 0x00004000
92705 +#define FPM_RAM_MURAM_TEST_ECC 0x20000000
92706 +#define FPM_RAM_IRAM_TEST_ECC 0x10000000
92707 +#define FPM_RAM_RAMS_ECC_EN_SRC_SEL 0x08000000
92708 +
92709 +#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000
92710 +#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000
92711 +
92712 +#define FPM_REV1_MAJOR_MASK 0x0000FF00
92713 +#define FPM_REV1_MINOR_MASK 0x000000FF
92714 +
92715 +#define FPM_REV2_INTEG_MASK 0x00FF0000
92716 +#define FPM_REV2_ERR_MASK 0x0000FF00
92717 +#define FPM_REV2_CFG_MASK 0x000000FF
92718 +
92719 +#define FPM_TS_FRACTION_MASK 0x0000FFFF
92720 +#define FPM_TS_CTL_EN 0x80000000
92721 +
92722 +#define FPM_PRC_REALSE_STALLED 0x00800000
92723 +
92724 +#define FPM_PS_STALLED 0x00800000
92725 +#define FPM_PS_FM_CTL1_SEL 0x80000000
92726 +#define FPM_PS_FM_CTL2_SEL 0x40000000
92727 +#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL)
92728 +
92729 +#define FPM_RSTC_FM_RESET 0x80000000
92730 +#define FPM_RSTC_10G0_RESET 0x04000000
92731 +#define FPM_RSTC_1G0_RESET 0x40000000
92732 +#define FPM_RSTC_1G1_RESET 0x20000000
92733 +#define FPM_RSTC_1G2_RESET 0x10000000
92734 +#define FPM_RSTC_1G3_RESET 0x08000000
92735 +#define FPM_RSTC_1G4_RESET 0x02000000
92736 +
92737 +
92738 +#define FPM_DISP_LIMIT_MASK 0x1F000000
92739 +#define FPM_THR1_PRS_MASK 0xFF000000
92740 +#define FPM_THR1_KG_MASK 0x00FF0000
92741 +#define FPM_THR1_PLCR_MASK 0x0000FF00
92742 +#define FPM_THR1_BMI_MASK 0x000000FF
92743 +
92744 +#define FPM_THR2_QMI_ENQ_MASK 0xFF000000
92745 +#define FPM_THR2_QMI_DEQ_MASK 0x000000FF
92746 +#define FPM_THR2_FM_CTL1_MASK 0x00FF0000
92747 +#define FPM_THR2_FM_CTL2_MASK 0x0000FF00
92748 +
92749 +/* shifts */
92750 +#define FPM_DISP_LIMIT_SHIFT 24
92751 +
92752 +#define FPM_THR1_PRS_SHIFT 24
92753 +#define FPM_THR1_KG_SHIFT 16
92754 +#define FPM_THR1_PLCR_SHIFT 8
92755 +#define FPM_THR1_BMI_SHIFT 0
92756 +
92757 +#define FPM_THR2_QMI_ENQ_SHIFT 24
92758 +#define FPM_THR2_QMI_DEQ_SHIFT 0
92759 +#define FPM_THR2_FM_CTL1_SHIFT 16
92760 +#define FPM_THR2_FM_CTL2_SHIFT 8
92761 +
92762 +#define FPM_EV_MASK_CAT_ERR_SHIFT 1
92763 +#define FPM_EV_MASK_DMA_ERR_SHIFT 0
92764 +
92765 +#define FPM_REV1_MAJOR_SHIFT 8
92766 +#define FPM_REV1_MINOR_SHIFT 0
92767 +
92768 +#define FPM_REV2_INTEG_SHIFT 16
92769 +#define FPM_REV2_ERR_SHIFT 8
92770 +#define FPM_REV2_CFG_SHIFT 0
92771 +
92772 +#define FPM_TS_INT_SHIFT 16
92773 +
92774 +#define FPM_PORT_FM_CTL_PORTID_SHIFT 24
92775 +
92776 +#define FPM_PS_FM_CTL_SEL_SHIFT 30
92777 +#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16
92778 +
92779 +#define FPM_DISP_LIMIT_SHIFT 24
92780 +
92781 +/* Interrupts defines */
92782 +#define FPM_EVENT_FM_CTL_0 0x00008000
92783 +#define FPM_EVENT_FM_CTL 0x0000FF00
92784 +#define FPM_EVENT_FM_CTL_BRK 0x00000080
92785 +
92786 +/* others */
92787 +#define FPM_MAX_DISP_LIMIT 31
92788 +#define FPM_RSTC_FM_RESET 0x80000000
92789 +#define FPM_RSTC_1G0_RESET 0x40000000
92790 +#define FPM_RSTC_1G1_RESET 0x20000000
92791 +#define FPM_RSTC_1G2_RESET 0x10000000
92792 +#define FPM_RSTC_1G3_RESET 0x08000000
92793 +#define FPM_RSTC_10G0_RESET 0x04000000
92794 +#define FPM_RSTC_1G4_RESET 0x02000000
92795 +#define FPM_RSTC_1G5_RESET 0x01000000
92796 +#define FPM_RSTC_1G6_RESET 0x00800000
92797 +#define FPM_RSTC_1G7_RESET 0x00400000
92798 +#define FPM_RSTC_10G1_RESET 0x00200000
92799 +/**************************************************************************//**
92800 + @Description BMI defines
92801 +*//***************************************************************************/
92802 +/* masks */
92803 +#define BMI_INIT_START 0x80000000
92804 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
92805 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
92806 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
92807 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
92808 +#define BMI_NUM_OF_TASKS_MASK 0x3F000000
92809 +#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000
92810 +#define BMI_NUM_OF_DMAS_MASK 0x00000F00
92811 +#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F
92812 +#define BMI_FIFO_SIZE_MASK 0x000003FF
92813 +#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000
92814 +#define BMI_CFG2_DMAS_MASK 0x0000003F
92815 +#define BMI_TOTAL_FIFO_SIZE_MASK 0x07FF0000
92816 +#define BMI_TOTAL_NUM_OF_TASKS_MASK 0x007F0000
92817 +
92818 +/* shifts */
92819 +#define BMI_CFG2_TASKS_SHIFT 16
92820 +#define BMI_CFG2_DMAS_SHIFT 0
92821 +#define BMI_CFG1_FIFO_SIZE_SHIFT 16
92822 +#define BMI_FIFO_SIZE_SHIFT 0
92823 +#define BMI_EXTRA_FIFO_SIZE_SHIFT 16
92824 +#define BMI_NUM_OF_TASKS_SHIFT 24
92825 +#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16
92826 +#define BMI_NUM_OF_DMAS_SHIFT 8
92827 +#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0
92828 +
92829 +/* others */
92830 +#define BMI_FIFO_ALIGN 0x100
92831 +#define FMAN_BMI_FIFO_UNITS 0x100
92832 +
92833 +
92834 +/**************************************************************************//**
92835 + @Description QMI defines
92836 +*//***************************************************************************/
92837 +/* masks */
92838 +#define QMI_CFG_ENQ_EN 0x80000000
92839 +#define QMI_CFG_DEQ_EN 0x40000000
92840 +#define QMI_CFG_EN_COUNTERS 0x10000000
92841 +#define QMI_CFG_SOFT_RESET 0x01000000
92842 +#define QMI_CFG_DEQ_MASK 0x0000003F
92843 +#define QMI_CFG_ENQ_MASK 0x00003F00
92844 +
92845 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
92846 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
92847 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
92848 +
92849 +/* shifts */
92850 +#define QMI_CFG_ENQ_SHIFT 8
92851 +#define QMI_TAPC_TAP 22
92852 +
92853 +#define QMI_GS_HALT_NOT_BUSY 0x00000002
92854 +
92855 +/**************************************************************************//**
92856 + @Description IRAM defines
92857 +*//***************************************************************************/
92858 +/* masks */
92859 +#define IRAM_IADD_AIE 0x80000000
92860 +#define IRAM_READY 0x80000000
92861 +
92862 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg);
92863 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg);
92864 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg);
92865 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg);
92866 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg);
92867 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg);
92868 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg);
92869 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg);
92870 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg);
92871 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg);
92872 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg,
92873 + uint8_t event_reg_id);
92874 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg);
92875 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg);
92876 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
92877 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg);
92878 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
92879 + uint8_t port_id);
92880 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
92881 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg,
92882 + uint8_t port_id);
92883 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
92884 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg,
92885 + uint8_t port_id);
92886 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg);
92887 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg,
92888 + uint8_t reg_id);
92889 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg);
92890 +void fman_get_revision(struct fman_fpm_regs *fpm_rg, uint8_t *major,
92891 + uint8_t *minor);
92892 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
92893 + enum fman_counters reg_name);
92894 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg);
92895 +
92896 +
92897 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg);
92898 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id,
92899 + uint32_t enable_events);
92900 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
92901 + uint8_t port_id,
92902 + uint8_t num_fman_ctrls,
92903 + uint32_t or_fman_ctrl);
92904 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
92905 + uint8_t port_id,
92906 + bool independent_mode,
92907 + bool is_rx_port);
92908 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
92909 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
92910 +void fman_set_liodn_per_port(struct fman_rg *fman_rg,
92911 + uint8_t port_id,
92912 + uint16_t liodn_base,
92913 + uint16_t liodn_offset);
92914 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
92915 + uint8_t port_id,
92916 + uint32_t size_of_fifo,
92917 + uint32_t extra_size_of_fifo);
92918 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
92919 + uint8_t port_id,
92920 + uint8_t num_of_tasks,
92921 + uint8_t num_of_extra_tasks);
92922 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
92923 + uint8_t port_id,
92924 + uint8_t num_of_open_dmas,
92925 + uint8_t num_of_extra_open_dmas,
92926 + uint8_t total_num_of_dmas);
92927 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights);
92928 +int fman_set_exception(struct fman_rg *fman_rg,
92929 + enum fman_exceptions exception,
92930 + bool enable);
92931 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, bool is_write,
92932 + bool enable);
92933 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri);
92934 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
92935 + uint32_t congestion_group_id,
92936 + uint8_t piority_bit_map,
92937 + uint32_t reg_num);
92938 +
92939 +
92940 +void fman_defconfig(struct fman_cfg *cfg, bool is_master);
92941 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg);
92942 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg);
92943 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg);
92944 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg);
92945 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg);
92946 +void fman_free_resources(struct fman_rg *fman_rg);
92947 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg);
92948 +void fman_reset(struct fman_fpm_regs *fpm_rg);
92949 +void fman_resume(struct fman_fpm_regs *fpm_rg);
92950 +
92951 +
92952 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
92953 + uint8_t count1ubit,
92954 + uint16_t fm_clk_freq);
92955 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg);
92956 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg);
92957 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg);
92958 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
92959 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t macId, bool is_10g);
92960 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
92961 +bool fman_rams_ecc_is_external_ctl(struct fman_fpm_regs *fpm_rg);
92962 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg);
92963 +int fman_modify_counter(struct fman_rg *fman_rg,
92964 + enum fman_counters reg_name,
92965 + uint32_t val);
92966 +void fman_force_intr(struct fman_rg *fman_rg,
92967 + enum fman_exceptions exception);
92968 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
92969 + uint8_t port_id,
92970 + uint8_t base_storage_profile,
92971 + uint8_t log2_num_of_profiles);
92972 +
92973 +/**************************************************************************//**
92974 + @Description default values
92975 +*//***************************************************************************/
92976 +#define DEFAULT_CATASTROPHIC_ERR E_FMAN_CATAST_ERR_STALL_PORT
92977 +#define DEFAULT_DMA_ERR E_FMAN_DMA_ERR_CATASTROPHIC
92978 +#define DEFAULT_HALT_ON_EXTERNAL_ACTIVATION FALSE /* do not change! if changed, must be disabled for rev1 ! */
92979 +#define DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR FALSE /* do not change! if changed, must be disabled for rev1 ! */
92980 +#define DEFAULT_EXTERNAL_ECC_RAMS_ENABLE FALSE
92981 +#define DEFAULT_AID_OVERRIDE FALSE
92982 +#define DEFAULT_AID_MODE E_FMAN_DMA_AID_OUT_TNUM
92983 +#define DEFAULT_DMA_COMM_Q_LOW 0x2A
92984 +#define DEFAULT_DMA_COMM_Q_HIGH 0x3F
92985 +#define DEFAULT_CACHE_OVERRIDE E_FMAN_DMA_NO_CACHE_OR
92986 +#define DEFAULT_DMA_CAM_NUM_OF_ENTRIES 64
92987 +#define DEFAULT_DMA_DBG_CNT_MODE E_FMAN_DMA_DBG_NO_CNT
92988 +#define DEFAULT_DMA_EN_EMERGENCY FALSE
92989 +#define DEFAULT_DMA_SOS_EMERGENCY 0
92990 +#define DEFAULT_DMA_WATCHDOG 0 /* disabled */
92991 +#define DEFAULT_DMA_EN_EMERGENCY_SMOOTHER FALSE
92992 +#define DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER 0
92993 +#define DEFAULT_DISP_LIMIT 0
92994 +#define DEFAULT_PRS_DISP_TH 16
92995 +#define DEFAULT_PLCR_DISP_TH 16
92996 +#define DEFAULT_KG_DISP_TH 16
92997 +#define DEFAULT_BMI_DISP_TH 16
92998 +#define DEFAULT_QMI_ENQ_DISP_TH 16
92999 +#define DEFAULT_QMI_DEQ_DISP_TH 16
93000 +#define DEFAULT_FM_CTL1_DISP_TH 16
93001 +#define DEFAULT_FM_CTL2_DISP_TH 16
93002 +#define DEFAULT_TNUM_AGING_PERIOD 4
93003 +
93004 +
93005 +#endif /* __FSL_FMAN_H */
93006 --- /dev/null
93007 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
93008 @@ -0,0 +1,1096 @@
93009 +/*
93010 + * Copyright 2008-2012 Freescale Semiconductor Inc.
93011 + *
93012 + * Redistribution and use in source and binary forms, with or without
93013 + * modification, are permitted provided that the following conditions are met:
93014 + * * Redistributions of source code must retain the above copyright
93015 + * notice, this list of conditions and the following disclaimer.
93016 + * * Redistributions in binary form must reproduce the above copyright
93017 + * notice, this list of conditions and the following disclaimer in the
93018 + * documentation and/or other materials provided with the distribution.
93019 + * * Neither the name of Freescale Semiconductor nor the
93020 + * names of its contributors may be used to endorse or promote products
93021 + * derived from this software without specific prior written permission.
93022 + *
93023 + *
93024 + * ALTERNATIVELY, this software may be distributed under the terms of the
93025 + * GNU General Public License ("GPL") as published by the Free Software
93026 + * Foundation, either version 2 of that License or (at your option) any
93027 + * later version.
93028 + *
93029 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93030 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93031 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93032 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93033 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93034 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93035 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93036 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93037 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93038 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93039 + */
93040 +
93041 +#ifndef __FSL_FMAN_DTSEC_H
93042 +#define __FSL_FMAN_DTSEC_H
93043 +
93044 +#include "common/general.h"
93045 +#include "fsl_enet.h"
93046 +
93047 +/**
93048 + * DOC: dTSEC Init sequence
93049 + *
93050 + * To prepare dTSEC block for transfer use the following call sequence:
93051 + *
93052 + * - fman_dtsec_defconfig() - This step is optional and yet recommended. Its
93053 + * use is to obtain the default dTSEC configuration parameters.
93054 + *
93055 + * - Change dtsec configuration in &dtsec_cfg. This structure will be used
93056 + * to customize the dTSEC behavior.
93057 + *
93058 + * - fman_dtsec_init() - Applies the configuration on dTSEC hardware. Note that
93059 + * dTSEC is initialized while both Tx and Rx are disabled.
93060 + *
93061 + * - fman_dtsec_set_mac_address() - Set the station address (mac address).
93062 + * This is used by dTSEC to match against received packets.
93063 + *
93064 + * - fman_dtsec_adjust_link() - Set the link speed and duplex parameters
93065 + * after the PHY establishes the link.
93066 + *
93067 + * - dtsec_enable_tx() and dtsec_enable_rx() to enable transmission and
93068 + * reception.
93069 + */
93070 +
93071 +/**
93072 + * DOC: dTSEC Graceful stop
93073 + *
93074 + * To temporary stop dTSEC activity use fman_dtsec_stop_tx() and
93075 + * fman_dtsec_stop_rx(). Note that these functions request dTSEC graceful stop
93076 + * but return before this stop is complete. To query for graceful stop
93077 + * completion use fman_dtsec_get_event() and check DTSEC_IEVENT_GTSC and
93078 + * DTSEC_IEVENT_GRSC bits. Alternatively the dTSEC interrupt mask can be set to
93079 + * enable graceful stop interrupts.
93080 + *
93081 + * To resume operation after graceful stop use fman_dtsec_start_tx() and
93082 + * fman_dtsec_start_rx().
93083 + */
93084 +
93085 +/**
93086 + * DOC: dTSEC interrupt handling
93087 + *
93088 + * This code does not provide an interrupt handler for dTSEC. Instead this
93089 + * handler should be implemented and registered to the operating system by the
93090 + * caller. Some primitives for accessing the event status and mask registers
93091 + * are provided.
93092 + *
93093 + * See "dTSEC Events" section for a list of events that dTSEC can generate.
93094 + */
93095 +
93096 +/**
93097 + * DOC: dTSEC Events
93098 + *
93099 + * Interrupt events cause dTSEC event bits to be set. Software may poll the
93100 + * event register at any time to check for pending interrupts. If an event
93101 + * occurs and its corresponding enable bit is set in the interrupt mask
93102 + * register, the event also causes a hardware interrupt at the PIC.
93103 + *
93104 + * To poll for event status use the fman_dtsec_get_event() function.
93105 + * To configure the interrupt mask use fman_dtsec_enable_interrupt() and
93106 + * fman_dtsec_disable_interrupt() functions.
93107 + * After servicing a dTSEC interrupt use fman_dtsec_ack_event to reset the
93108 + * serviced event bit.
93109 + *
93110 + * The following events may be signaled by dTSEC hardware:
93111 + *
93112 + * %DTSEC_IEVENT_BABR - Babbling receive error. This bit indicates that
93113 + * a frame was received with length in excess of the MAC's maximum frame length
93114 + * register.
93115 + *
93116 + * %DTSEC_IEVENT_RXC - Receive control (pause frame) interrupt. A pause
93117 + * control frame was received while Rx pause frame handling is enabled.
93118 + * Also see fman_dtsec_handle_rx_pause().
93119 + *
93120 + * %DTSEC_IEVENT_MSRO - MIB counter overflow. The count for one of the MIB
93121 + * counters has exceeded the size of its register.
93122 + *
93123 + * %DTSEC_IEVENT_GTSC - Graceful transmit stop complete. Graceful stop is now
93124 + * complete. The transmitter is in a stopped state, in which only pause frames
93125 + * can be transmitted.
93126 + * Also see fman_dtsec_stop_tx().
93127 + *
93128 + * %DTSEC_IEVENT_BABT - Babbling transmit error. The transmitted frame length
93129 + * has exceeded the value in the MAC's Maximum Frame Length register.
93130 + *
93131 + * %DTSEC_IEVENT_TXC - Transmit control (pause frame) interrupt. his bit
93132 + * indicates that a control frame was transmitted.
93133 + *
93134 + * %DTSEC_IEVENT_TXE - Transmit error. This bit indicates that an error
93135 + * occurred on the transmitted channel. This bit is set whenever any transmit
93136 + * error occurs which causes the dTSEC to discard all or part of a frame
93137 + * (LC, CRL, XFUN).
93138 + *
93139 + * %DTSEC_IEVENT_LC - Late collision. This bit indicates that a collision
93140 + * occurred beyond the collision window (slot time) in half-duplex mode.
93141 + * The frame is truncated with a bad CRC and the remainder of the frame
93142 + * is discarded.
93143 + *
93144 + * %DTSEC_IEVENT_CRL - Collision retry limit. is bit indicates that the number
93145 + * of successive transmission collisions has exceeded the MAC's half-duplex
93146 + * register's retransmission maximum count. The frame is discarded without
93147 + * being transmitted and transmission of the next frame commences. This only
93148 + * occurs while in half-duplex mode.
93149 + * The number of retransmit attempts can be set in
93150 + * &dtsec_halfdup_cfg.@retransmit before calling fman_dtsec_init().
93151 + *
93152 + * %DTSEC_IEVENT_XFUN - Transmit FIFO underrun. This bit indicates that the
93153 + * transmit FIFO became empty before the complete frame was transmitted.
93154 + * The frame is truncated with a bad CRC and the remainder of the frame is
93155 + * discarded.
93156 + *
93157 + * %DTSEC_IEVENT_MAG - TBD
93158 + *
93159 + * %DTSEC_IEVENT_MMRD - MII management read completion.
93160 + *
93161 + * %DTSEC_IEVENT_MMWR - MII management write completion.
93162 + *
93163 + * %DTSEC_IEVENT_GRSC - Graceful receive stop complete. It allows the user to
93164 + * know if the system has completed the stop and it is safe to write to receive
93165 + * registers (status, control or configuration registers) that are used by the
93166 + * system during normal operation.
93167 + *
93168 + * %DTSEC_IEVENT_TDPE - Internal data error on transmit. This bit indicates
93169 + * that the dTSEC has detected a parity error on its stored transmit data, which
93170 + * is likely to compromise the validity of recently transferred frames.
93171 + *
93172 + * %DTSEC_IEVENT_RDPE - Internal data error on receive. This bit indicates that
93173 + * the dTSEC has detected a parity error on its stored receive data, which is
93174 + * likely to compromise the validity of recently transferred frames.
93175 + */
93176 +/* Interrupt Mask Register (IMASK) */
93177 +#define DTSEC_IMASK_BREN 0x80000000
93178 +#define DTSEC_IMASK_RXCEN 0x40000000
93179 +#define DTSEC_IMASK_MSROEN 0x04000000
93180 +#define DTSEC_IMASK_GTSCEN 0x02000000
93181 +#define DTSEC_IMASK_BTEN 0x01000000
93182 +#define DTSEC_IMASK_TXCEN 0x00800000
93183 +#define DTSEC_IMASK_TXEEN 0x00400000
93184 +#define DTSEC_IMASK_LCEN 0x00040000
93185 +#define DTSEC_IMASK_CRLEN 0x00020000
93186 +#define DTSEC_IMASK_XFUNEN 0x00010000
93187 +#define DTSEC_IMASK_ABRTEN 0x00008000
93188 +#define DTSEC_IMASK_IFERREN 0x00004000
93189 +#define DTSEC_IMASK_MAGEN 0x00000800
93190 +#define DTSEC_IMASK_MMRDEN 0x00000400
93191 +#define DTSEC_IMASK_MMWREN 0x00000200
93192 +#define DTSEC_IMASK_GRSCEN 0x00000100
93193 +#define DTSEC_IMASK_TDPEEN 0x00000002
93194 +#define DTSEC_IMASK_RDPEEN 0x00000001
93195 +
93196 +#define DTSEC_EVENTS_MASK \
93197 + ((uint32_t)(DTSEC_IMASK_BREN | \
93198 + DTSEC_IMASK_RXCEN | \
93199 + DTSEC_IMASK_BTEN | \
93200 + DTSEC_IMASK_TXCEN | \
93201 + DTSEC_IMASK_TXEEN | \
93202 + DTSEC_IMASK_ABRTEN | \
93203 + DTSEC_IMASK_LCEN | \
93204 + DTSEC_IMASK_CRLEN | \
93205 + DTSEC_IMASK_XFUNEN | \
93206 + DTSEC_IMASK_IFERREN | \
93207 + DTSEC_IMASK_MAGEN | \
93208 + DTSEC_IMASK_TDPEEN | \
93209 + DTSEC_IMASK_RDPEEN))
93210 +
93211 +/* dtsec timestamp event bits */
93212 +#define TMR_PEMASK_TSREEN 0x00010000
93213 +#define TMR_PEVENT_TSRE 0x00010000
93214 +
93215 +/* Group address bit indication */
93216 +#define MAC_GROUP_ADDRESS 0x0000010000000000ULL
93217 +/* size in bytes of L2 address */
93218 +#define MAC_ADDRLEN 6
93219 +
93220 +#define DEFAULT_HALFDUP_ON FALSE
93221 +#define DEFAULT_HALFDUP_RETRANSMIT 0xf
93222 +#define DEFAULT_HALFDUP_COLL_WINDOW 0x37
93223 +#define DEFAULT_HALFDUP_EXCESS_DEFER TRUE
93224 +#define DEFAULT_HALFDUP_NO_BACKOFF FALSE
93225 +#define DEFAULT_HALFDUP_BP_NO_BACKOFF FALSE
93226 +#define DEFAULT_HALFDUP_ALT_BACKOFF_VAL 0x0A
93227 +#define DEFAULT_HALFDUP_ALT_BACKOFF_EN FALSE
93228 +#define DEFAULT_RX_DROP_BCAST FALSE
93229 +#define DEFAULT_RX_SHORT_FRM TRUE
93230 +#define DEFAULT_RX_LEN_CHECK FALSE
93231 +#define DEFAULT_TX_PAD_CRC TRUE
93232 +#define DEFAULT_TX_CRC FALSE
93233 +#define DEFAULT_RX_CTRL_ACC FALSE
93234 +#define DEFAULT_TX_PAUSE_TIME 0xf000
93235 +#define DEFAULT_TBIPA 5
93236 +#define DEFAULT_RX_PREPEND 0
93237 +#define DEFAULT_PTP_TSU_EN TRUE
93238 +#define DEFAULT_PTP_EXCEPTION_EN TRUE
93239 +#define DEFAULT_PREAMBLE_LEN 7
93240 +#define DEFAULT_RX_PREAMBLE FALSE
93241 +#define DEFAULT_TX_PREAMBLE FALSE
93242 +#define DEFAULT_LOOPBACK FALSE
93243 +#define DEFAULT_RX_TIME_STAMP_EN FALSE
93244 +#define DEFAULT_TX_TIME_STAMP_EN FALSE
93245 +#define DEFAULT_RX_FLOW TRUE
93246 +#define DEFAULT_TX_FLOW TRUE
93247 +#define DEFAULT_RX_GROUP_HASH_EXD FALSE
93248 +#define DEFAULT_TX_PAUSE_TIME_EXTD 0
93249 +#define DEFAULT_RX_PROMISC FALSE
93250 +#define DEFAULT_NON_BACK_TO_BACK_IPG1 0x40
93251 +#define DEFAULT_NON_BACK_TO_BACK_IPG2 0x60
93252 +#define DEFAULT_MIN_IFG_ENFORCEMENT 0x50
93253 +#define DEFAULT_BACK_TO_BACK_IPG 0x60
93254 +#define DEFAULT_MAXIMUM_FRAME 0x600
93255 +#define DEFAULT_TBI_PHY_ADDR 5
93256 +#define DEFAULT_WAKE_ON_LAN FALSE
93257 +
93258 +/* register related defines (bits, field offsets..) */
93259 +#define DTSEC_ID1_ID 0xffff0000
93260 +#define DTSEC_ID1_REV_MJ 0x0000FF00
93261 +#define DTSEC_ID1_REV_MN 0x000000ff
93262 +
93263 +#define DTSEC_ID2_INT_REDUCED_OFF 0x00010000
93264 +#define DTSEC_ID2_INT_NORMAL_OFF 0x00020000
93265 +
93266 +#define DTSEC_ECNTRL_CLRCNT 0x00004000
93267 +#define DTSEC_ECNTRL_AUTOZ 0x00002000
93268 +#define DTSEC_ECNTRL_STEN 0x00001000
93269 +#define DTSEC_ECNTRL_CFG_RO 0x80000000
93270 +#define DTSEC_ECNTRL_GMIIM 0x00000040
93271 +#define DTSEC_ECNTRL_TBIM 0x00000020
93272 +#define DTSEC_ECNTRL_SGMIIM 0x00000002
93273 +#define DTSEC_ECNTRL_RPM 0x00000010
93274 +#define DTSEC_ECNTRL_R100M 0x00000008
93275 +#define DTSEC_ECNTRL_RMM 0x00000004
93276 +#define DTSEC_ECNTRL_QSGMIIM 0x00000001
93277 +
93278 +#define DTSEC_TCTRL_THDF 0x00000800
93279 +#define DTSEC_TCTRL_TTSE 0x00000040
93280 +#define DTSEC_TCTRL_GTS 0x00000020
93281 +#define DTSEC_TCTRL_TFC_PAUSE 0x00000010
93282 +
93283 +/* PTV offsets */
93284 +#define PTV_PTE_OFST 16
93285 +
93286 +#define RCTRL_CFA 0x00008000
93287 +#define RCTRL_GHTX 0x00000400
93288 +#define RCTRL_RTSE 0x00000040
93289 +#define RCTRL_GRS 0x00000020
93290 +#define RCTRL_BC_REJ 0x00000010
93291 +#define RCTRL_MPROM 0x00000008
93292 +#define RCTRL_RSF 0x00000004
93293 +#define RCTRL_UPROM 0x00000001
93294 +#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM)
93295 +
93296 +#define TMR_CTL_ESFDP 0x00000800
93297 +#define TMR_CTL_ESFDE 0x00000400
93298 +
93299 +#define MACCFG1_SOFT_RESET 0x80000000
93300 +#define MACCFG1_LOOPBACK 0x00000100
93301 +#define MACCFG1_RX_FLOW 0x00000020
93302 +#define MACCFG1_TX_FLOW 0x00000010
93303 +#define MACCFG1_TX_EN 0x00000001
93304 +#define MACCFG1_RX_EN 0x00000004
93305 +#define MACCFG1_RESET_RxMC 0x00080000
93306 +#define MACCFG1_RESET_TxMC 0x00040000
93307 +#define MACCFG1_RESET_RxFUN 0x00020000
93308 +#define MACCFG1_RESET_TxFUN 0x00010000
93309 +
93310 +#define MACCFG2_NIBBLE_MODE 0x00000100
93311 +#define MACCFG2_BYTE_MODE 0x00000200
93312 +#define MACCFG2_PRE_AM_Rx_EN 0x00000080
93313 +#define MACCFG2_PRE_AM_Tx_EN 0x00000040
93314 +#define MACCFG2_LENGTH_CHECK 0x00000010
93315 +#define MACCFG2_MAGIC_PACKET_EN 0x00000008
93316 +#define MACCFG2_PAD_CRC_EN 0x00000004
93317 +#define MACCFG2_CRC_EN 0x00000002
93318 +#define MACCFG2_FULL_DUPLEX 0x00000001
93319 +
93320 +#define PREAMBLE_LENGTH_SHIFT 12
93321 +
93322 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24
93323 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16
93324 +#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8
93325 +
93326 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000
93327 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000
93328 +#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00
93329 +#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F
93330 +
93331 +#define HAFDUP_ALT_BEB 0x00080000
93332 +#define HAFDUP_BP_NO_BACKOFF 0x00040000
93333 +#define HAFDUP_NO_BACKOFF 0x00020000
93334 +#define HAFDUP_EXCESS_DEFER 0x00010000
93335 +#define HAFDUP_COLLISION_WINDOW 0x000003ff
93336 +
93337 +#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20
93338 +#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12
93339 +#define HAFDUP_RETRANSMISSION_MAX 0x0000f000
93340 +
93341 +#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */
93342 +
93343 +/* CAR1/2 bits */
93344 +#define DTSEC_CAR1_TR64 0x80000000
93345 +#define DTSEC_CAR1_TR127 0x40000000
93346 +#define DTSEC_CAR1_TR255 0x20000000
93347 +#define DTSEC_CAR1_TR511 0x10000000
93348 +#define DTSEC_CAR1_TRK1 0x08000000
93349 +#define DTSEC_CAR1_TRMAX 0x04000000
93350 +#define DTSEC_CAR1_TRMGV 0x02000000
93351 +
93352 +#define DTSEC_CAR1_RBYT 0x00010000
93353 +#define DTSEC_CAR1_RPKT 0x00008000
93354 +#define DTSEC_CAR1_RFCS 0x00004000
93355 +#define DTSEC_CAR1_RMCA 0x00002000
93356 +#define DTSEC_CAR1_RBCA 0x00001000
93357 +#define DTSEC_CAR1_RXCF 0x00000800
93358 +#define DTSEC_CAR1_RXPF 0x00000400
93359 +#define DTSEC_CAR1_RXUO 0x00000200
93360 +#define DTSEC_CAR1_RALN 0x00000100
93361 +#define DTSEC_CAR1_RFLR 0x00000080
93362 +#define DTSEC_CAR1_RCDE 0x00000040
93363 +#define DTSEC_CAR1_RCSE 0x00000020
93364 +#define DTSEC_CAR1_RUND 0x00000010
93365 +#define DTSEC_CAR1_ROVR 0x00000008
93366 +#define DTSEC_CAR1_RFRG 0x00000004
93367 +#define DTSEC_CAR1_RJBR 0x00000002
93368 +#define DTSEC_CAR1_RDRP 0x00000001
93369 +
93370 +#define DTSEC_CAR2_TJBR 0x00080000
93371 +#define DTSEC_CAR2_TFCS 0x00040000
93372 +#define DTSEC_CAR2_TXCF 0x00020000
93373 +#define DTSEC_CAR2_TOVR 0x00010000
93374 +#define DTSEC_CAR2_TUND 0x00008000
93375 +#define DTSEC_CAR2_TFRG 0x00004000
93376 +#define DTSEC_CAR2_TBYT 0x00002000
93377 +#define DTSEC_CAR2_TPKT 0x00001000
93378 +#define DTSEC_CAR2_TMCA 0x00000800
93379 +#define DTSEC_CAR2_TBCA 0x00000400
93380 +#define DTSEC_CAR2_TXPF 0x00000200
93381 +#define DTSEC_CAR2_TDFR 0x00000100
93382 +#define DTSEC_CAR2_TEDF 0x00000080
93383 +#define DTSEC_CAR2_TSCL 0x00000040
93384 +#define DTSEC_CAR2_TMCL 0x00000020
93385 +#define DTSEC_CAR2_TLCL 0x00000010
93386 +#define DTSEC_CAR2_TXCL 0x00000008
93387 +#define DTSEC_CAR2_TNCL 0x00000004
93388 +#define DTSEC_CAR2_TDRP 0x00000001
93389 +
93390 +#define CAM1_ERRORS_ONLY \
93391 + (DTSEC_CAR1_RXPF | DTSEC_CAR1_RALN | DTSEC_CAR1_RFLR \
93392 + | DTSEC_CAR1_RCDE | DTSEC_CAR1_RCSE | DTSEC_CAR1_RUND \
93393 + | DTSEC_CAR1_ROVR | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93394 + | DTSEC_CAR1_RDRP)
93395 +
93396 +#define CAM2_ERRORS_ONLY (DTSEC_CAR2_TFCS | DTSEC_CAR2_TXPF | DTSEC_CAR2_TDRP)
93397 +
93398 +/*
93399 + * Group of dTSEC specific counters relating to the standard RMON MIB Group 1
93400 + * (or Ethernet) statistics.
93401 + */
93402 +#define CAM1_MIB_GRP_1 \
93403 + (DTSEC_CAR1_RDRP | DTSEC_CAR1_RBYT | DTSEC_CAR1_RPKT | DTSEC_CAR1_RMCA\
93404 + | DTSEC_CAR1_RBCA | DTSEC_CAR1_RALN | DTSEC_CAR1_RUND | DTSEC_CAR1_ROVR\
93405 + | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93406 + | DTSEC_CAR1_TR64 | DTSEC_CAR1_TR127 | DTSEC_CAR1_TR255 \
93407 + | DTSEC_CAR1_TR511 | DTSEC_CAR1_TRMAX)
93408 +
93409 +#define CAM2_MIB_GRP_1 (DTSEC_CAR2_TNCL | DTSEC_CAR2_TDRP)
93410 +
93411 +/* memory map */
93412 +
93413 +struct dtsec_regs {
93414 + /* dTSEC General Control and Status Registers */
93415 + uint32_t tsec_id; /* 0x000 ETSEC_ID register */
93416 + uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */
93417 + uint32_t ievent; /* 0x008 Interrupt event register */
93418 + uint32_t imask; /* 0x00C Interrupt mask register */
93419 + uint32_t reserved0010[1];
93420 + uint32_t ecntrl; /* 0x014 E control register */
93421 + uint32_t ptv; /* 0x018 Pause time value register */
93422 + uint32_t tbipa; /* 0x01C TBI PHY address register */
93423 + uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */
93424 + uint32_t tmr_pevent; /* 0x024 Time-stamp event register */
93425 + uint32_t tmr_pemask; /* 0x028 Timer event mask register */
93426 + uint32_t reserved002c[5];
93427 + uint32_t tctrl; /* 0x040 Transmit control register */
93428 + uint32_t reserved0044[3];
93429 + uint32_t rctrl; /* 0x050 Receive control register */
93430 + uint32_t reserved0054[11];
93431 + uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address */
93432 + uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */
93433 + uint32_t reserved00c0[16];
93434 + uint32_t maccfg1; /* 0x100 MAC configuration #1 */
93435 + uint32_t maccfg2; /* 0x104 MAC configuration #2 */
93436 + uint32_t ipgifg; /* 0x108 IPG/IFG */
93437 + uint32_t hafdup; /* 0x10C Half-duplex */
93438 + uint32_t maxfrm; /* 0x110 Maximum frame */
93439 + uint32_t reserved0114[10];
93440 + uint32_t ifstat; /* 0x13C Interface status */
93441 + uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */
93442 + uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */
93443 + struct {
93444 + uint32_t exact_match1; /* octets 1-4 */
93445 + uint32_t exact_match2; /* octets 5-6 */
93446 + } macaddr[15]; /* 0x148-0x1BC mac exact match addresses 1-15 */
93447 + uint32_t reserved01c0[16];
93448 + uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */
93449 + uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame
93450 + * counter */
93451 + uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame
93452 + * counter */
93453 + uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame
93454 + * counter */
93455 + uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame
93456 + * counter */
93457 + uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame
93458 + * counter */
93459 + uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good
93460 + * VLAN frame count */
93461 + uint32_t rbyt; /* 0x21C receive byte counter */
93462 + uint32_t rpkt; /* 0x220 receive packet counter */
93463 + uint32_t rfcs; /* 0x224 receive FCS error counter */
93464 + uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */
93465 + uint32_t rbca; /* 0x22C receive broadcast packet counter */
93466 + uint32_t rxcf; /* 0x230 receive control frame packet counter */
93467 + uint32_t rxpf; /* 0x234 receive pause frame packet counter */
93468 + uint32_t rxuo; /* 0x238 receive unknown OP code counter */
93469 + uint32_t raln; /* 0x23C receive alignment error counter */
93470 + uint32_t rflr; /* 0x240 receive frame length error counter */
93471 + uint32_t rcde; /* 0x244 receive code error counter */
93472 + uint32_t rcse; /* 0x248 receive carrier sense error counter */
93473 + uint32_t rund; /* 0x24C receive undersize packet counter */
93474 + uint32_t rovr; /* 0x250 receive oversize packet counter */
93475 + uint32_t rfrg; /* 0x254 receive fragments counter */
93476 + uint32_t rjbr; /* 0x258 receive jabber counter */
93477 + uint32_t rdrp; /* 0x25C receive drop */
93478 + uint32_t tbyt; /* 0x260 transmit byte counter */
93479 + uint32_t tpkt; /* 0x264 transmit packet counter */
93480 + uint32_t tmca; /* 0x268 transmit multicast packet counter */
93481 + uint32_t tbca; /* 0x26C transmit broadcast packet counter */
93482 + uint32_t txpf; /* 0x270 transmit pause control frame counter */
93483 + uint32_t tdfr; /* 0x274 transmit deferral packet counter */
93484 + uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */
93485 + uint32_t tscl; /* 0x27C transmit single collision packet counter */
93486 + uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */
93487 + uint32_t tlcl; /* 0x284 transmit late collision packet counter */
93488 + uint32_t txcl; /* 0x288 transmit excessive collision packet counter */
93489 + uint32_t tncl; /* 0x28C transmit total collision counter */
93490 + uint32_t reserved0290[1];
93491 + uint32_t tdrp; /* 0x294 transmit drop frame counter */
93492 + uint32_t tjbr; /* 0x298 transmit jabber frame counter */
93493 + uint32_t tfcs; /* 0x29C transmit FCS error counter */
93494 + uint32_t txcf; /* 0x2A0 transmit control frame counter */
93495 + uint32_t tovr; /* 0x2A4 transmit oversize frame counter */
93496 + uint32_t tund; /* 0x2A8 transmit undersize frame counter */
93497 + uint32_t tfrg; /* 0x2AC transmit fragments frame counter */
93498 + uint32_t car1; /* 0x2B0 carry register one register* */
93499 + uint32_t car2; /* 0x2B4 carry register two register* */
93500 + uint32_t cam1; /* 0x2B8 carry register one mask register */
93501 + uint32_t cam2; /* 0x2BC carry register two mask register */
93502 + uint32_t reserved02c0[848];
93503 +};
93504 +
93505 +/**
93506 + * struct dtsec_mib_grp_1_counters - MIB counter overflows
93507 + *
93508 + * @tr64: Transmit and Receive 64 byte frame count. Increment for each
93509 + * good or bad frame, of any type, transmitted or received, which
93510 + * is 64 bytes in length.
93511 + * @tr127: Transmit and Receive 65 to 127 byte frame count. Increments for
93512 + * each good or bad frame of any type, transmitted or received,
93513 + * which is 65-127 bytes in length.
93514 + * @tr255: Transmit and Receive 128 to 255 byte frame count. Increments
93515 + * for each good or bad frame, of any type, transmitted or
93516 + * received, which is 128-255 bytes in length.
93517 + * @tr511: Transmit and Receive 256 to 511 byte frame count. Increments
93518 + * for each good or bad frame, of any type, transmitted or
93519 + * received, which is 256-511 bytes in length.
93520 + * @tr1k: Transmit and Receive 512 to 1023 byte frame count. Increments
93521 + * for each good or bad frame, of any type, transmitted or
93522 + * received, which is 512-1023 bytes in length.
93523 + * @trmax: Transmit and Receive 1024 to 1518 byte frame count. Increments
93524 + * for each good or bad frame, of any type, transmitted or
93525 + * received, which is 1024-1518 bytes in length.
93526 + * @rfrg: Receive fragments count. Increments for each received frame
93527 + * which is less than 64 bytes in length and contains an invalid
93528 + * FCS. This includes integral and non-integral lengths.
93529 + * @rjbr: Receive jabber count. Increments for received frames which
93530 + * exceed 1518 (non VLAN) or 1522 (VLAN) bytes and contain an
93531 + * invalid FCS. This includes alignment errors.
93532 + * @rdrp: Receive dropped packets count. Increments for received frames
93533 + * which are streamed to system but are later dropped due to lack
93534 + * of system resources. Does not increment for frames rejected due
93535 + * to address filtering.
93536 + * @raln: Receive alignment error count. Increments for each received
93537 + * frame from 64 to 1518 (non VLAN) or 1522 (VLAN) which contains
93538 + * an invalid FCS and is not an integral number of bytes.
93539 + * @rund: Receive undersize packet count. Increments each time a frame is
93540 + * received which is less than 64 bytes in length and contains a
93541 + * valid FCS and is otherwise well formed. This count does not
93542 + * include range length errors.
93543 + * @rovr: Receive oversize packet count. Increments each time a frame is
93544 + * received which exceeded 1518 (non VLAN) or 1522 (VLAN) and
93545 + * contains a valid FCS and is otherwise well formed.
93546 + * @rbyt: Receive byte count. Increments by the byte count of frames
93547 + * received, including those in bad packets, excluding preamble and
93548 + * SFD but including FCS bytes.
93549 + * @rpkt: Receive packet count. Increments for each received frame
93550 + * (including bad packets, all unicast, broadcast, and multicast
93551 + * packets).
93552 + * @rmca: Receive multicast packet count. Increments for each multicast
93553 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93554 + * 1522 (VLAN), excluding broadcast frames. This count does not
93555 + * include range/length errors.
93556 + * @rbca: Receive broadcast packet count. Increments for each broadcast
93557 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93558 + * 1522 (VLAN), excluding multicast frames. Does not include
93559 + * range/length errors.
93560 + * @tdrp: Transmit drop frame count. Increments each time a memory error
93561 + * or an underrun has occurred.
93562 + * @tncl: Transmit total collision counter. Increments by the number of
93563 + * collisions experienced during the transmission of a frame. Does
93564 + * not increment for aborted frames.
93565 + *
93566 + * The structure contains a group of dTSEC HW specific counters relating to the
93567 + * standard RMON MIB Group 1 (or Ethernet statistics) counters. This structure
93568 + * is counting only the carry events of the corresponding HW counters.
93569 + *
93570 + * tr64 to trmax notes: Frame sizes specified are considered excluding preamble
93571 + * and SFD but including FCS bytes.
93572 + */
93573 +struct dtsec_mib_grp_1_counters {
93574 + uint64_t rdrp;
93575 + uint64_t tdrp;
93576 + uint64_t rbyt;
93577 + uint64_t rpkt;
93578 + uint64_t rbca;
93579 + uint64_t rmca;
93580 + uint64_t raln;
93581 + uint64_t rund;
93582 + uint64_t rovr;
93583 + uint64_t rfrg;
93584 + uint64_t rjbr;
93585 + uint64_t tncl;
93586 + uint64_t tr64;
93587 + uint64_t tr127;
93588 + uint64_t tr255;
93589 + uint64_t tr511;
93590 + uint64_t tr1k;
93591 + uint64_t trmax;
93592 +};
93593 +
93594 +enum dtsec_stat_counters {
93595 + E_DTSEC_STAT_TR64,
93596 + E_DTSEC_STAT_TR127,
93597 + E_DTSEC_STAT_TR255,
93598 + E_DTSEC_STAT_TR511,
93599 + E_DTSEC_STAT_TR1K,
93600 + E_DTSEC_STAT_TRMAX,
93601 + E_DTSEC_STAT_TRMGV,
93602 + E_DTSEC_STAT_RBYT,
93603 + E_DTSEC_STAT_RPKT,
93604 + E_DTSEC_STAT_RMCA,
93605 + E_DTSEC_STAT_RBCA,
93606 + E_DTSEC_STAT_RXPF,
93607 + E_DTSEC_STAT_RALN,
93608 + E_DTSEC_STAT_RFLR,
93609 + E_DTSEC_STAT_RCDE,
93610 + E_DTSEC_STAT_RCSE,
93611 + E_DTSEC_STAT_RUND,
93612 + E_DTSEC_STAT_ROVR,
93613 + E_DTSEC_STAT_RFRG,
93614 + E_DTSEC_STAT_RJBR,
93615 + E_DTSEC_STAT_RDRP,
93616 + E_DTSEC_STAT_TFCS,
93617 + E_DTSEC_STAT_TBYT,
93618 + E_DTSEC_STAT_TPKT,
93619 + E_DTSEC_STAT_TMCA,
93620 + E_DTSEC_STAT_TBCA,
93621 + E_DTSEC_STAT_TXPF,
93622 + E_DTSEC_STAT_TNCL,
93623 + E_DTSEC_STAT_TDRP
93624 +};
93625 +
93626 +enum dtsec_stat_level {
93627 + /* No statistics */
93628 + E_MAC_STAT_NONE = 0,
93629 + /* Only RMON MIB group 1 (ether stats). Optimized for performance */
93630 + E_MAC_STAT_MIB_GRP1,
93631 + /* Only error counters are available. Optimized for performance */
93632 + E_MAC_STAT_PARTIAL,
93633 + /* All counters available. Not optimized for performance */
93634 + E_MAC_STAT_FULL
93635 +};
93636 +
93637 +
93638 +/**
93639 + * struct dtsec_cfg - dTSEC configuration
93640 + *
93641 + * @halfdup_on: Transmit half-duplex flow control, under software
93642 + * control for 10/100-Mbps half-duplex media. If set,
93643 + * back pressure is applied to media by raising carrier.
93644 + * @halfdup_retransmit: Number of retransmission attempts following a collision.
93645 + * If this is exceeded dTSEC aborts transmission due to
93646 + * excessive collisions. The standard specifies the
93647 + * attempt limit to be 15.
93648 + * @halfdup_coll_window:The number of bytes of the frame during which
93649 + * collisions may occur. The default value of 55
93650 + * corresponds to the frame byte at the end of the
93651 + * standard 512-bit slot time window. If collisions are
93652 + * detected after this byte, the late collision event is
93653 + * asserted and transmission of current frame is aborted.
93654 + * @rx_drop_bcast: Discard broadcast frames. If set, all broadcast frames
93655 + * will be discarded by dTSEC.
93656 + * @rx_short_frm: Accept short frames. If set, dTSEC will accept frames
93657 + * of length 14..63 bytes.
93658 + * @rx_len_check: Length check for received frames. If set, the MAC
93659 + * checks the frame's length field on receive to ensure it
93660 + * matches the actual data field length. This only works
93661 + * for received frames with length field less than 1500.
93662 + * No check is performed for larger frames.
93663 + * @tx_pad_crc: Pad and append CRC. If set, the MAC pads all
93664 + * transmitted short frames and appends a CRC to every
93665 + * frame regardless of padding requirement.
93666 + * @tx_crc: Transmission CRC enable. If set, the MAC appends a CRC
93667 + * to all frames. If frames presented to the MAC have a
93668 + * valid length and contain a valid CRC, @tx_crc should be
93669 + * reset.
93670 + * This field is ignored if @tx_pad_crc is set.
93671 + * @rx_ctrl_acc: Control frame accept. If set, this overrides 802.3
93672 + * standard control frame behavior, and all Ethernet frames
93673 + * that have an ethertype of 0x8808 are treated as normal
93674 + * Ethernet frames and passed up to the packet interface on
93675 + * a DA match. Received pause control frames are passed to
93676 + * the packet interface only if Rx flow control is also
93677 + * disabled. See fman_dtsec_handle_rx_pause() function.
93678 + * @tx_pause_time: Transmit pause time value. This pause value is used as
93679 + * part of the pause frame to be sent when a transmit pause
93680 + * frame is initiated. If set to 0 this disables
93681 + * transmission of pause frames.
93682 + * @rx_preamble: Receive preamble enable. If set, the MAC recovers the
93683 + * received Ethernet 7-byte preamble and passes it to the
93684 + * packet interface at the start of each received frame.
93685 + * This field should be reset for internal MAC loop-back
93686 + * mode.
93687 + * @tx_preamble: User defined preamble enable for transmitted frames.
93688 + * If set, a user-defined preamble must passed to the MAC
93689 + * and it is transmitted instead of the standard preamble.
93690 + * @preamble_len: Length, in bytes, of the preamble field preceding each
93691 + * Ethernet start-of-frame delimiter byte. The default
93692 + * value of 0x7 should be used in order to guarantee
93693 + * reliable operation with IEEE 802.3 compliant hardware.
93694 + * @rx_prepend: Packet alignment padding length. The specified number
93695 + * of bytes (1-31) of zero padding are inserted before the
93696 + * start of each received frame. For Ethernet, where
93697 + * optional preamble extraction is enabled, the padding
93698 + * appears before the preamble, otherwise the padding
93699 + * precedes the layer 2 header.
93700 + *
93701 + * This structure contains basic dTSEC configuration and must be passed to
93702 + * fman_dtsec_init() function. A default set of configuration values can be
93703 + * obtained by calling fman_dtsec_defconfig().
93704 + */
93705 +struct dtsec_cfg {
93706 + bool halfdup_on;
93707 + bool halfdup_alt_backoff_en;
93708 + bool halfdup_excess_defer;
93709 + bool halfdup_no_backoff;
93710 + bool halfdup_bp_no_backoff;
93711 + uint8_t halfdup_alt_backoff_val;
93712 + uint16_t halfdup_retransmit;
93713 + uint16_t halfdup_coll_window;
93714 + bool rx_drop_bcast;
93715 + bool rx_short_frm;
93716 + bool rx_len_check;
93717 + bool tx_pad_crc;
93718 + bool tx_crc;
93719 + bool rx_ctrl_acc;
93720 + unsigned short tx_pause_time;
93721 + unsigned short tbipa;
93722 + bool ptp_tsu_en;
93723 + bool ptp_exception_en;
93724 + bool rx_preamble;
93725 + bool tx_preamble;
93726 + unsigned char preamble_len;
93727 + unsigned char rx_prepend;
93728 + bool loopback;
93729 + bool rx_time_stamp_en;
93730 + bool tx_time_stamp_en;
93731 + bool rx_flow;
93732 + bool tx_flow;
93733 + bool rx_group_hash_exd;
93734 + bool rx_promisc;
93735 + uint8_t tbi_phy_addr;
93736 + uint16_t tx_pause_time_extd;
93737 + uint16_t maximum_frame;
93738 + uint32_t non_back_to_back_ipg1;
93739 + uint32_t non_back_to_back_ipg2;
93740 + uint32_t min_ifg_enforcement;
93741 + uint32_t back_to_back_ipg;
93742 + bool wake_on_lan;
93743 +};
93744 +
93745 +
93746 +/**
93747 + * fman_dtsec_defconfig() - Get default dTSEC configuration
93748 + * @cfg: pointer to configuration structure.
93749 + *
93750 + * Call this function to obtain a default set of configuration values for
93751 + * initializing dTSEC. The user can overwrite any of the values before calling
93752 + * fman_dtsec_init(), if specific configuration needs to be applied.
93753 + */
93754 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg);
93755 +
93756 +/**
93757 + * fman_dtsec_init() - Init dTSEC hardware block
93758 + * @regs: Pointer to dTSEC register block
93759 + * @cfg: dTSEC configuration data
93760 + * @iface_mode: dTSEC interface mode, the type of MAC - PHY interface.
93761 + * @iface_speed: 1G or 10G
93762 + * @macaddr: MAC station address to be assigned to the device
93763 + * @fm_rev_maj: major rev number
93764 + * @fm_rev_min: minor rev number
93765 + * @exceptions_mask: initial exceptions mask
93766 + *
93767 + * This function initializes dTSEC and applies basic configuration.
93768 + *
93769 + * dTSEC initialization sequence:
93770 + * Before enabling Rx/Tx call dtsec_set_address() to set MAC address,
93771 + * fman_dtsec_adjust_link() to configure interface speed and duplex and finally
93772 + * dtsec_enable_tx()/dtsec_enable_rx() to start transmission and reception.
93773 + *
93774 + * Returns: 0 if successful, an error code otherwise.
93775 + */
93776 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
93777 + enum enet_interface iface_mode,
93778 + enum enet_speed iface_speed,
93779 + uint8_t *macaddr, uint8_t fm_rev_maj,
93780 + uint8_t fm_rev_min,
93781 + uint32_t exception_mask);
93782 +
93783 +/**
93784 + * fman_dtsec_enable() - Enable dTSEC Tx and Tx
93785 + * @regs: Pointer to dTSEC register block
93786 + * @apply_rx: enable rx side
93787 + * @apply_tx: enable tx side
93788 + *
93789 + * This function resets Tx and Rx graceful stop bit and enables dTSEC Tx and Rx.
93790 + */
93791 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
93792 +
93793 +/**
93794 + * fman_dtsec_disable() - Disable dTSEC Tx and Rx
93795 + * @regs: Pointer to dTSEC register block
93796 + * @apply_rx: disable rx side
93797 + * @apply_tx: disable tx side
93798 + *
93799 + * This function disables Tx and Rx in dTSEC.
93800 + */
93801 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
93802 +
93803 +/**
93804 + * fman_dtsec_get_revision() - Get dTSEC hardware revision
93805 + * @regs: Pointer to dTSEC register block
93806 + *
93807 + * Returns dtsec_id content
93808 + *
93809 + * Call this function to obtain the dTSEC hardware version.
93810 + */
93811 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs);
93812 +
93813 +/**
93814 + * fman_dtsec_set_mac_address() - Set MAC station address
93815 + * @regs: Pointer to dTSEC register block
93816 + * @macaddr: MAC address array
93817 + *
93818 + * This function sets MAC station address. To enable unicast reception call
93819 + * this after fman_dtsec_init(). While promiscuous mode is disabled dTSEC will
93820 + * match the destination address of received unicast frames against this
93821 + * address.
93822 + */
93823 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
93824 +
93825 +/**
93826 + * fman_dtsec_get_mac_address() - Query MAC station address
93827 + * @regs: Pointer to dTSEC register block
93828 + * @macaddr: MAC address array
93829 + */
93830 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
93831 +
93832 +/**
93833 + * fman_dtsec_set_uc_promisc() - Sets unicast promiscuous mode
93834 + * @regs: Pointer to dTSEC register block
93835 + * @enable: Enable unicast promiscuous mode
93836 + *
93837 + * Use this function to enable/disable dTSEC L2 address filtering. If the
93838 + * address filtering is disabled all unicast packets are accepted.
93839 + * To set dTSEC in promiscuous mode call both fman_dtsec_set_uc_promisc() and
93840 + * fman_dtsec_set_mc_promisc() to disable filtering for both unicast and
93841 + * multicast addresses.
93842 + */
93843 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable);
93844 +
93845 +/**
93846 + * fman_dtsec_set_wol() - Enable/Disable wake on lan
93847 + * (magic packet support)
93848 + * @regs: Pointer to dTSEC register block
93849 + * @en: Enable Wake On Lan support in dTSEC
93850 + *
93851 + */
93852 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en);
93853 +
93854 +/**
93855 + * fman_dtsec_adjust_link() - Adjust dTSEC speed/duplex settings
93856 + * @regs: Pointer to dTSEC register block
93857 + * @iface_mode: dTSEC interface mode
93858 + * @speed: Link speed
93859 + * @full_dx: True for full-duplex, false for half-duplex.
93860 + *
93861 + * This function configures the MAC to function and the desired rates. Use it
93862 + * to configure dTSEC after fman_dtsec_init() and whenever the link speed
93863 + * changes (for instance following PHY auto-negociation).
93864 + *
93865 + * Returns: 0 if successful, an error code otherwise.
93866 + */
93867 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
93868 + enum enet_interface iface_mode,
93869 + enum enet_speed speed, bool full_dx);
93870 +
93871 +/**
93872 + * fman_dtsec_set_tbi_phy_addr() - Updates TBI address field
93873 + * @regs: Pointer to dTSEC register block
93874 + * @address: Valid PHY address in the range of 1 to 31. 0 is reserved.
93875 + *
93876 + * In SGMII mode, the dTSEC's TBIPA field must contain a valid TBI PHY address
93877 + * so that the associated TBI PHY (i.e. the link) may be initialized.
93878 + *
93879 + * Returns: 0 if successful, an error code otherwise.
93880 + */
93881 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
93882 + uint8_t addr);
93883 +
93884 +/**
93885 + * fman_dtsec_set_max_frame_len() - Set max frame length
93886 + * @regs: Pointer to dTSEC register block
93887 + * @length: Max frame length.
93888 + *
93889 + * Sets maximum frame length for received and transmitted frames. Frames that
93890 + * exceeds this length are truncated.
93891 + */
93892 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length);
93893 +
93894 +/**
93895 + * fman_dtsec_get_max_frame_len() - Query max frame length
93896 + * @regs: Pointer to dTSEC register block
93897 + *
93898 + * Returns: the current value of the maximum frame length.
93899 + */
93900 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs);
93901 +
93902 +/**
93903 + * fman_dtsec_handle_rx_pause() - Configure pause frame handling
93904 + * @regs: Pointer to dTSEC register block
93905 + * @en: Enable pause frame handling in dTSEC
93906 + *
93907 + * If enabled, dTSEC will handle pause frames internally. This must be disabled
93908 + * if dTSEC is set in half-duplex mode.
93909 + * If pause frame handling is disabled and &dtsec_cfg.rx_ctrl_acc is set, pause
93910 + * frames will be transferred to the packet interface just like regular Ethernet
93911 + * frames.
93912 + */
93913 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en);
93914 +
93915 +/**
93916 + * fman_dtsec_set_tx_pause_frames() - Configure Tx pause time
93917 + * @regs: Pointer to dTSEC register block
93918 + * @time: Time value included in pause frames
93919 + *
93920 + * Call this function to set the time value used in transmitted pause frames.
93921 + * If time is 0, transmission of pause frames is disabled
93922 + */
93923 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time);
93924 +
93925 +/**
93926 + * fman_dtsec_ack_event() - Acknowledge handled events
93927 + * @regs: Pointer to dTSEC register block
93928 + * @ev_mask: Events to acknowledge
93929 + *
93930 + * After handling events signaled by dTSEC in either polling or interrupt mode,
93931 + * call this function to reset the associated status bits in dTSEC event
93932 + * register.
93933 + */
93934 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask);
93935 +
93936 +/**
93937 + * fman_dtsec_get_event() - Returns currently asserted events
93938 + * @regs: Pointer to dTSEC register block
93939 + * @ev_mask: Mask of relevant events
93940 + *
93941 + * Call this function to obtain a bit-mask of events that are currently asserted
93942 + * in dTSEC, taken from IEVENT register.
93943 + *
93944 + * Returns: a bit-mask of events asserted in dTSEC.
93945 + */
93946 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask);
93947 +
93948 +/**
93949 + * fman_dtsec_get_interrupt_mask() - Returns a bit-mask of enabled interrupts
93950 + * @regs: Pointer to dTSEC register block
93951 + *
93952 + * Call this function to obtain a bit-mask of enabled interrupts
93953 + * in dTSEC, taken from IMASK register.
93954 + *
93955 + * Returns: a bit-mask of enabled interrupts in dTSEC.
93956 + */
93957 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs);
93958 +
93959 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs,
93960 + uint8_t paddr_num);
93961 +
93962 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
93963 + uint64_t addr,
93964 + uint8_t paddr_num);
93965 +
93966 +void fman_dtsec_enable_tmr_interrupt (struct dtsec_regs *regs);
93967 +
93968 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs);
93969 +
93970 +/**
93971 + * fman_dtsec_disable_interrupt() - Disables interrupts for the specified events
93972 + * @regs: Pointer to dTSEC register block
93973 + * @ev_mask: Mask of relevant events
93974 + *
93975 + * Call this function to disable interrupts in dTSEC for the specified events.
93976 + * To enable interrupts use fman_dtsec_enable_interrupt().
93977 + */
93978 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
93979 +
93980 +/**
93981 + * fman_dtsec_enable_interrupt() - Enable interrupts for the specified events
93982 + * @regs: Pointer to dTSEC register block
93983 + * @ev_mask: Mask of relevant events
93984 + *
93985 + * Call this function to enable interrupts in dTSEC for the specified events.
93986 + * To disable interrupts use fman_dtsec_disable_interrupt().
93987 + */
93988 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
93989 +
93990 +/**
93991 + * fman_dtsec_set_ts() - Enables dTSEC timestamps
93992 + * @regs: Pointer to dTSEC register block
93993 + * @en: true to enable timestamps, false to disable them
93994 + *
93995 + * Call this function to enable/disable dTSEC timestamps. This affects both
93996 + * Tx and Rx.
93997 + */
93998 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en);
93999 +
94000 +/**
94001 + * fman_dtsec_set_bucket() - Enables/disables a filter bucket
94002 + * @regs: Pointer to dTSEC register block
94003 + * @bucket: Bucket index
94004 + * @enable: true/false to enable/disable this bucket
94005 + *
94006 + * This function enables or disables the specified bucket. Enabling a bucket
94007 + * associated with an address configures dTSEC to accept received packets
94008 + * with that destination address.
94009 + * Multiple addresses may be associated with the same bucket. Disabling a
94010 + * bucket will affect all addresses associated with that bucket. A bucket that
94011 + * is enabled requires further filtering and verification in the upper layers
94012 + *
94013 + */
94014 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable);
94015 +
94016 +/**
94017 + * dtsec_set_hash_table() - insert a crc code into thr filter table
94018 + * @regs: Pointer to dTSEC register block
94019 + * @crc: crc to insert
94020 + * @mcast: true is this is a multicast address
94021 + * @ghtx: true if we are in ghtx mode
94022 + *
94023 + * This function inserts a crc code into the filter table.
94024 + */
94025 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc,
94026 + bool mcast, bool ghtx);
94027 +
94028 +/**
94029 + * fman_dtsec_reset_filter_table() - Resets the address filtering table
94030 + * @regs: Pointer to dTSEC register block
94031 + * @mcast: Reset multicast entries
94032 + * @ucast: Reset unicast entries
94033 + *
94034 + * Resets all entries in L2 address filter table. After calling this function
94035 + * all buckets enabled using fman_dtsec_set_bucket() will be disabled.
94036 + * If dtsec_init_filter_table() was called with @unicast_hash set to false,
94037 + * @ucast argument is ignored.
94038 + * This does not affect the primary nor the 15 additional addresses configured
94039 + * using dtsec_set_address() or dtsec_set_match_address().
94040 + */
94041 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast,
94042 + bool ucast);
94043 +
94044 +/**
94045 + * fman_dtsec_set_mc_promisc() - Set multicast promiscuous mode
94046 + * @regs: Pointer to dTSEC register block
94047 + * @enable: Enable multicast promiscuous mode
94048 + *
94049 + * Call this to enable/disable L2 address filtering for multicast packets.
94050 + */
94051 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable);
94052 +
94053 +/* statistics APIs */
94054 +
94055 +/**
94056 + * fman_dtsec_set_stat_level() - Enable a group of MIB statistics counters
94057 + * @regs: Pointer to dTSEC register block
94058 + * @level: Specifies a certain group of dTSEC MIB HW counters or _all_,
94059 + * to specify all the existing counters.
94060 + * If set to _none_, it disables all the counters.
94061 + *
94062 + * Enables the MIB statistics hw counters and sets up the carry interrupt
94063 + * masks for the counters corresponding to the @level input parameter.
94064 + *
94065 + * Returns: error if invalid @level value given.
94066 + */
94067 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs,
94068 + enum dtsec_stat_level level);
94069 +
94070 +/**
94071 + * fman_dtsec_reset_stat() - Completely resets all dTSEC HW counters
94072 + * @regs: Pointer to dTSEC register block
94073 + */
94074 +void fman_dtsec_reset_stat(struct dtsec_regs *regs);
94075 +
94076 +/**
94077 + * fman_dtsec_get_clear_carry_regs() - Read and clear carry bits (CAR1-2 registers)
94078 + * @regs: Pointer to dTSEC register block
94079 + * @car1: car1 register value
94080 + * @car2: car2 register value
94081 + *
94082 + * When set, the carry bits signal that an overflow occurred on the
94083 + * corresponding counters.
94084 + * Note that the carry bits (CAR1-2 registers) will assert the
94085 + * %DTSEC_IEVENT_MSRO interrupt if unmasked (via CAM1-2 regs).
94086 + *
94087 + * Returns: true if overflow occurred, otherwise - false
94088 + */
94089 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
94090 + uint32_t *car1, uint32_t *car2);
94091 +
94092 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs);
94093 +
94094 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
94095 + enum dtsec_stat_counters reg_name);
94096 +
94097 +void fman_dtsec_start_tx(struct dtsec_regs *regs);
94098 +void fman_dtsec_start_rx(struct dtsec_regs *regs);
94099 +void fman_dtsec_stop_tx(struct dtsec_regs *regs);
94100 +void fman_dtsec_stop_rx(struct dtsec_regs *regs);
94101 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs);
94102 +
94103 +
94104 +#endif /* __FSL_FMAN_DTSEC_H */
94105 --- /dev/null
94106 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
94107 @@ -0,0 +1,107 @@
94108 +/*
94109 + * Copyright 2008-2013 Freescale Semiconductor Inc.
94110 + *
94111 + * Redistribution and use in source and binary forms, with or without
94112 + * modification, are permitted provided that the following conditions are met:
94113 + * * Redistributions of source code must retain the above copyright
94114 + * notice, this list of conditions and the following disclaimer.
94115 + * * Redistributions in binary form must reproduce the above copyright
94116 + * notice, this list of conditions and the following disclaimer in the
94117 + * documentation and/or other materials provided with the distribution.
94118 + * * Neither the name of Freescale Semiconductor nor the
94119 + * names of its contributors may be used to endorse or promote products
94120 + * derived from this software without specific prior written permission.
94121 + *
94122 + *
94123 + * ALTERNATIVELY, this software may be distributed under the terms of the
94124 + * GNU General Public License ("GPL") as published by the Free Software
94125 + * Foundation, either version 2 of that License or (at your option) any
94126 + * later version.
94127 + *
94128 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94129 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94130 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94131 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94132 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94133 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94134 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94135 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94136 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94137 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94138 + */
94139 +
94140 +#ifndef __FSL_FMAN_DTSEC_MII_ACC_H
94141 +#define __FSL_FMAN_DTSEC_MII_ACC_H
94142 +
94143 +#include "common/general.h"
94144 +
94145 +
94146 +/* MII Management Configuration Register */
94147 +#define MIIMCFG_RESET_MGMT 0x80000000
94148 +#define MIIMCFG_MGNTCLK_MASK 0x00000007
94149 +#define MIIMCFG_MGNTCLK_SHIFT 0
94150 +
94151 +/* MII Management Command Register */
94152 +#define MIIMCOM_SCAN_CYCLE 0x00000002
94153 +#define MIIMCOM_READ_CYCLE 0x00000001
94154 +
94155 +/* MII Management Address Register */
94156 +#define MIIMADD_PHY_ADDR_SHIFT 8
94157 +#define MIIMADD_PHY_ADDR_MASK 0x00001f00
94158 +
94159 +#define MIIMADD_REG_ADDR_SHIFT 0
94160 +#define MIIMADD_REG_ADDR_MASK 0x0000001f
94161 +
94162 +/* MII Management Indicator Register */
94163 +#define MIIMIND_BUSY 0x00000001
94164 +
94165 +
94166 +/* PHY Control Register */
94167 +#define PHY_CR_PHY_RESET 0x8000
94168 +#define PHY_CR_LOOPBACK 0x4000
94169 +#define PHY_CR_SPEED0 0x2000
94170 +#define PHY_CR_ANE 0x1000
94171 +#define PHY_CR_RESET_AN 0x0200
94172 +#define PHY_CR_FULLDUPLEX 0x0100
94173 +#define PHY_CR_SPEED1 0x0040
94174 +
94175 +#define PHY_TBICON_SRESET 0x8000
94176 +#define PHY_TBICON_SPEED2 0x0020
94177 +#define PHY_TBICON_CLK_SEL 0x0020
94178 +#define PHY_TBIANA_SGMII 0x4001
94179 +#define PHY_TBIANA_1000X 0x01a0
94180 +/* register map */
94181 +
94182 +/* MII Configuration Control Memory Map Registers */
94183 +struct dtsec_mii_reg {
94184 + uint32_t reserved1[72];
94185 + uint32_t miimcfg; /* MII Mgmt:configuration */
94186 + uint32_t miimcom; /* MII Mgmt:command */
94187 + uint32_t miimadd; /* MII Mgmt:address */
94188 + uint32_t miimcon; /* MII Mgmt:control 3 */
94189 + uint32_t miimstat; /* MII Mgmt:status */
94190 + uint32_t miimind; /* MII Mgmt:indicators */
94191 +};
94192 +
94193 +/* dTSEC MII API */
94194 +
94195 +/* functions to access the mii registers for phy configuration.
94196 + * this functionality may not be available for all dtsecs in the system.
94197 + * consult the reference manual for details */
94198 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs);
94199 +/* frequency is in MHz.
94200 + * note that dtsec clock is 1/2 of fman clock */
94201 +void fman_dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq);
94202 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs,
94203 + uint8_t addr,
94204 + uint8_t reg,
94205 + uint16_t data,
94206 + uint16_t dtsec_freq);
94207 +
94208 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs,
94209 + uint8_t addr,
94210 + uint8_t reg,
94211 + uint16_t *data,
94212 + uint16_t dtsec_freq);
94213 +
94214 +#endif /* __FSL_FMAN_DTSEC_MII_ACC_H */
94215 --- /dev/null
94216 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
94217 @@ -0,0 +1,514 @@
94218 +/*
94219 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94220 + *
94221 + * Redistribution and use in source and binary forms, with or without
94222 + * modification, are permitted provided that the following conditions are met:
94223 + * * Redistributions of source code must retain the above copyright
94224 + * notice, this list of conditions and the following disclaimer.
94225 + * * Redistributions in binary form must reproduce the above copyright
94226 + * notice, this list of conditions and the following disclaimer in the
94227 + * documentation and/or other materials provided with the distribution.
94228 + * * Neither the name of Freescale Semiconductor nor the
94229 + * names of its contributors may be used to endorse or promote products
94230 + * derived from this software without specific prior written permission.
94231 + *
94232 + *
94233 + * ALTERNATIVELY, this software may be distributed under the terms of the
94234 + * GNU General Public License ("GPL") as published by the Free Software
94235 + * Foundation, either version 2 of that License or (at your option) any
94236 + * later version.
94237 + *
94238 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94239 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94240 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94241 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94242 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94243 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94244 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94245 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94246 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94247 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94248 + */
94249 +
94250 +#ifndef __FSL_FMAN_KG_H
94251 +#define __FSL_FMAN_KG_H
94252 +
94253 +#include "common/general.h"
94254 +
94255 +#define FM_KG_NUM_OF_GENERIC_REGS 8 /**< Num of generic KeyGen regs */
94256 +#define FMAN_MAX_NUM_OF_HW_PORTS 64
94257 +/**< Total num of masks allowed on KG extractions */
94258 +#define FM_KG_EXTRACT_MASKS_NUM 4
94259 +#define FM_KG_NUM_CLS_PLAN_ENTR 8 /**< Num of class. plan regs */
94260 +#define FM_KG_CLS_PLAN_GRPS_NUM 32 /**< Max num of class. groups */
94261 +
94262 +struct fman_kg_regs {
94263 + uint32_t fmkg_gcr;
94264 + uint32_t res004;
94265 + uint32_t res008;
94266 + uint32_t fmkg_eer;
94267 + uint32_t fmkg_eeer;
94268 + uint32_t res014;
94269 + uint32_t res018;
94270 + uint32_t fmkg_seer;
94271 + uint32_t fmkg_seeer;
94272 + uint32_t fmkg_gsr;
94273 + uint32_t fmkg_tpc;
94274 + uint32_t fmkg_serc;
94275 + uint32_t res030[4];
94276 + uint32_t fmkg_fdor;
94277 + uint32_t fmkg_gdv0r;
94278 + uint32_t fmkg_gdv1r;
94279 + uint32_t res04c[6];
94280 + uint32_t fmkg_feer;
94281 + uint32_t res068[38];
94282 + uint32_t fmkg_indirect[63];
94283 + uint32_t fmkg_ar;
94284 +};
94285 +
94286 +struct fman_kg_scheme_regs {
94287 + uint32_t kgse_mode; /**< MODE */
94288 + uint32_t kgse_ekfc; /**< Extract Known Fields Command */
94289 + uint32_t kgse_ekdv; /**< Extract Known Default Value */
94290 + uint32_t kgse_bmch; /**< Bit Mask Command High */
94291 + uint32_t kgse_bmcl; /**< Bit Mask Command Low */
94292 + uint32_t kgse_fqb; /**< Frame Queue Base */
94293 + uint32_t kgse_hc; /**< Hash Command */
94294 + uint32_t kgse_ppc; /**< Policer Profile Command */
94295 + uint32_t kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
94296 + /**< Generic Extract Command */
94297 + uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */
94298 + uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */
94299 + uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */
94300 + uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/
94301 + uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */
94302 + uint32_t kgse_om; /**< KeyGen Scheme Entry Operation Mode bits */
94303 + uint32_t kgse_vsp; /**< KeyGen Scheme Entry Virtual Storage Profile */
94304 +};
94305 +
94306 +struct fman_kg_pe_regs{
94307 + uint32_t fmkg_pe_sp;
94308 + uint32_t fmkg_pe_cpp;
94309 +};
94310 +
94311 +struct fman_kg_cp_regs {
94312 + uint32_t kgcpe[FM_KG_NUM_CLS_PLAN_ENTR];
94313 +};
94314 +
94315 +
94316 +#define FM_KG_KGAR_GO 0x80000000
94317 +#define FM_KG_KGAR_READ 0x40000000
94318 +#define FM_KG_KGAR_WRITE 0x00000000
94319 +#define FM_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000
94320 +#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT 0x00008000
94321 +
94322 +#define KG_SCH_PP_SHIFT_HIGH 0x80000000
94323 +#define KG_SCH_PP_NO_GEN 0x10000000
94324 +#define KG_SCH_PP_SHIFT_LOW 0x0000F000
94325 +#define KG_SCH_MODE_NIA_PLCR 0x40000000
94326 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94327 +#define KG_SCH_BITMASK_MASK 0x000000FF
94328 +#define KG_SCH_GEN_VALID 0x80000000
94329 +#define KG_SCH_GEN_MASK 0x00FF0000
94330 +#define FM_PCD_KG_KGAR_ERR 0x20000000
94331 +#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000
94332 +#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000
94333 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000
94334 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000
94335 +#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00
94336 +#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000
94337 +#define KG_SCH_HASH_CONFIG_SYM 0x40000000
94338 +
94339 +#define FM_EX_KG_DOUBLE_ECC 0x80000000
94340 +#define FM_EX_KG_KEYSIZE_OVERFLOW 0x40000000
94341 +
94342 +/* ECC capture register */
94343 +#define KG_FMKG_SERC_CAP 0x80000000
94344 +#define KG_FMKG_SERC_CET 0x40000000
94345 +#define KG_FMKG_SERC_CNT_MSK 0x00FF0000
94346 +#define KG_FMKG_SERC_CNT_SHIFT 16
94347 +#define KG_FMKG_SERC_ADDR_MSK 0x000003FF
94348 +
94349 +/* Masks */
94350 +#define FM_KG_KGGCR_EN 0x80000000
94351 +#define KG_SCH_GEN_VALID 0x80000000
94352 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94353 +#define KG_ERR_TYPE_DOUBLE 0x40000000
94354 +#define KG_ERR_ADDR_MASK 0x00000FFF
94355 +#define KG_SCH_MODE_EN 0x80000000
94356 +
94357 +/* shifts */
94358 +#define FM_KG_KGAR_NUM_SHIFT 16
94359 +#define FM_KG_PE_CPP_MASK_SHIFT 16
94360 +#define FM_KG_KGAR_WSEL_SHIFT 8
94361 +
94362 +#define FM_KG_SCH_GEN_HT_INVALID 0
94363 +
94364 +#define FM_KG_MASK_SEL_GEN_BASE 0x20
94365 +
94366 +#define KG_GET_MASK_SEL_SHIFT(shift, i) \
94367 +switch (i) \
94368 +{ \
94369 + case 0: (shift) = 26; break; \
94370 + case 1: (shift) = 20; break; \
94371 + case 2: (shift) = 10; break; \
94372 + case 3: (shift) = 4; break; \
94373 + default: (shift) = 0; \
94374 +}
94375 +
94376 +#define KG_GET_MASK_OFFSET_SHIFT(shift, i) \
94377 +switch (i) \
94378 +{ \
94379 + case 0: (shift) = 16; break; \
94380 + case 1: (shift) = 0; break; \
94381 + case 2: (shift) = 28; break; \
94382 + case 3: (shift) = 24; break; \
94383 + default: (shift) = 0; \
94384 +}
94385 +
94386 +#define KG_GET_MASK_SHIFT(shift, i) \
94387 +switch (i) \
94388 +{ \
94389 + case 0: shift = 24; break; \
94390 + case 1: shift = 16; break; \
94391 + case 2: shift = 8; break; \
94392 + case 3: shift = 0; break; \
94393 + default: shift = 0; \
94394 +}
94395 +
94396 +/* Port entry CPP register */
94397 +#define FMAN_KG_PE_CPP_MASK_SHIFT 16
94398 +
94399 +/* Scheme registers */
94400 +#define FMAN_KG_SCH_MODE_EN 0x80000000
94401 +#define FMAN_KG_SCH_MODE_NIA_PLCR 0x40000000
94402 +#define FMAN_KG_SCH_MODE_CCOBASE_SHIFT 24
94403 +
94404 +#define FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT 30
94405 +#define FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT 28
94406 +#define FMAN_KG_SCH_DEF_ETYPE_SHIFT 26
94407 +#define FMAN_KG_SCH_DEF_PPP_SID_SHIFT 24
94408 +#define FMAN_KG_SCH_DEF_PPP_PID_SHIFT 22
94409 +#define FMAN_KG_SCH_DEF_MPLS_SHIFT 20
94410 +#define FMAN_KG_SCH_DEF_IP_ADDR_SHIFT 18
94411 +#define FMAN_KG_SCH_DEF_PTYPE_SHIFT 16
94412 +#define FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT 14
94413 +#define FMAN_KG_SCH_DEF_IPv6_FL_SHIFT 12
94414 +#define FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT 10
94415 +#define FMAN_KG_SCH_DEF_L4_PORT_SHIFT 8
94416 +#define FMAN_KG_SCH_DEF_TCP_FLG_SHIFT 6
94417 +
94418 +#define FMAN_KG_SCH_GEN_VALID 0x80000000
94419 +#define FMAN_KG_SCH_GEN_SIZE_MAX 16
94420 +#define FMAN_KG_SCH_GEN_OR 0x00008000
94421 +
94422 +#define FMAN_KG_SCH_GEN_DEF_SHIFT 29
94423 +#define FMAN_KG_SCH_GEN_SIZE_SHIFT 24
94424 +#define FMAN_KG_SCH_GEN_MASK_SHIFT 16
94425 +#define FMAN_KG_SCH_GEN_HT_SHIFT 8
94426 +
94427 +#define FMAN_KG_SCH_HASH_HSHIFT_SHIFT 24
94428 +#define FMAN_KG_SCH_HASH_HSHIFT_MAX 0x28
94429 +#define FMAN_KG_SCH_HASH_SYM 0x40000000
94430 +#define FMAN_KG_SCH_HASH_NO_FQID_GEN 0x80000000
94431 +
94432 +#define FMAN_KG_SCH_PP_SH_SHIFT 27
94433 +#define FMAN_KG_SCH_PP_SL_SHIFT 12
94434 +#define FMAN_KG_SCH_PP_SH_MASK 0x80000000
94435 +#define FMAN_KG_SCH_PP_SL_MASK 0x0000F000
94436 +#define FMAN_KG_SCH_PP_SHIFT_MAX 0x17
94437 +#define FMAN_KG_SCH_PP_MASK_SHIFT 16
94438 +#define FMAN_KG_SCH_PP_NO_GEN 0x10000000
94439 +
94440 +enum fman_kg_gen_extract_src {
94441 + E_FMAN_KG_GEN_EXTRACT_ETH,
94442 + E_FMAN_KG_GEN_EXTRACT_ETYPE,
94443 + E_FMAN_KG_GEN_EXTRACT_SNAP,
94444 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1,
94445 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N,
94446 + E_FMAN_KG_GEN_EXTRACT_PPPoE,
94447 + E_FMAN_KG_GEN_EXTRACT_MPLS_1,
94448 + E_FMAN_KG_GEN_EXTRACT_MPLS_2,
94449 + E_FMAN_KG_GEN_EXTRACT_MPLS_3,
94450 + E_FMAN_KG_GEN_EXTRACT_MPLS_N,
94451 + E_FMAN_KG_GEN_EXTRACT_IPv4_1,
94452 + E_FMAN_KG_GEN_EXTRACT_IPv6_1,
94453 + E_FMAN_KG_GEN_EXTRACT_IPv4_2,
94454 + E_FMAN_KG_GEN_EXTRACT_IPv6_2,
94455 + E_FMAN_KG_GEN_EXTRACT_MINENCAP,
94456 + E_FMAN_KG_GEN_EXTRACT_IP_PID,
94457 + E_FMAN_KG_GEN_EXTRACT_GRE,
94458 + E_FMAN_KG_GEN_EXTRACT_TCP,
94459 + E_FMAN_KG_GEN_EXTRACT_UDP,
94460 + E_FMAN_KG_GEN_EXTRACT_SCTP,
94461 + E_FMAN_KG_GEN_EXTRACT_DCCP,
94462 + E_FMAN_KG_GEN_EXTRACT_IPSEC_AH,
94463 + E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP,
94464 + E_FMAN_KG_GEN_EXTRACT_SHIM_1,
94465 + E_FMAN_KG_GEN_EXTRACT_SHIM_2,
94466 + E_FMAN_KG_GEN_EXTRACT_FROM_DFLT,
94467 + E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START,
94468 + E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT,
94469 + E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE,
94470 + E_FMAN_KG_GEN_EXTRACT_FROM_FQID
94471 +};
94472 +
94473 +struct fman_kg_ex_ecc_attr
94474 +{
94475 + bool valid;
94476 + bool double_ecc;
94477 + uint16_t addr;
94478 + uint8_t single_ecc_count;
94479 +};
94480 +
94481 +enum fman_kg_def_select
94482 +{
94483 + E_FMAN_KG_DEF_GLOBAL_0,
94484 + E_FMAN_KG_DEF_GLOBAL_1,
94485 + E_FMAN_KG_DEF_SCHEME_0,
94486 + E_FMAN_KG_DEF_SCHEME_1
94487 +};
94488 +
94489 +struct fman_kg_extract_def
94490 +{
94491 + enum fman_kg_def_select mac_addr;
94492 + enum fman_kg_def_select vlan_tci;
94493 + enum fman_kg_def_select etype;
94494 + enum fman_kg_def_select ppp_sid;
94495 + enum fman_kg_def_select ppp_pid;
94496 + enum fman_kg_def_select mpls;
94497 + enum fman_kg_def_select ip_addr;
94498 + enum fman_kg_def_select ptype;
94499 + enum fman_kg_def_select ip_tos_tc;
94500 + enum fman_kg_def_select ipv6_fl;
94501 + enum fman_kg_def_select ipsec_spi;
94502 + enum fman_kg_def_select l4_port;
94503 + enum fman_kg_def_select tcp_flg;
94504 +};
94505 +
94506 +enum fman_kg_gen_extract_type
94507 +{
94508 + E_FMAN_KG_HASH_EXTRACT,
94509 + E_FMAN_KG_OR_EXTRACT
94510 +};
94511 +
94512 +struct fman_kg_gen_extract_params
94513 +{
94514 + /* Hash or Or-ed extract */
94515 + enum fman_kg_gen_extract_type type;
94516 + enum fman_kg_gen_extract_src src;
94517 + bool no_validation;
94518 + /* Extraction offset from the header location specified above */
94519 + uint8_t offset;
94520 + /* Size of extraction for FMAN_KG_HASH_EXTRACT,
94521 + * hash result shift for FMAN_KG_OR_EXTRACT */
94522 + uint8_t extract;
94523 + uint8_t mask;
94524 + /* Default value to use when header specified
94525 + * by fman_kg_gen_extract_src doesn't present */
94526 + enum fman_kg_def_select def_val;
94527 +};
94528 +
94529 +struct fman_kg_extract_mask
94530 +{
94531 + /**< Indication if mask is on known field extraction or
94532 + * on general extraction; TRUE for known field */
94533 + bool is_known;
94534 + /**< One of FMAN_KG_EXTRACT_xxx defines for known fields mask and
94535 + * generic register index for generic extracts mask */
94536 + uint32_t field_or_gen_idx;
94537 + /**< Byte offset from start of the extracted data specified
94538 + * by field_or_gen_idx */
94539 + uint8_t offset;
94540 + /**< Byte mask (selected bits will be used) */
94541 + uint8_t mask;
94542 +};
94543 +
94544 +struct fman_kg_extract_params
94545 +{
94546 + /* Or-ed mask of FMAN_KG_EXTRACT_xxx defines */
94547 + uint32_t known_fields;
94548 + struct fman_kg_extract_def known_fields_def;
94549 + /* Number of entries in gen_extract */
94550 + uint8_t gen_extract_num;
94551 + struct fman_kg_gen_extract_params gen_extract[FM_KG_NUM_OF_GENERIC_REGS];
94552 + /* Number of entries in masks */
94553 + uint8_t masks_num;
94554 + struct fman_kg_extract_mask masks[FM_KG_EXTRACT_MASKS_NUM];
94555 + uint32_t def_scheme_0;
94556 + uint32_t def_scheme_1;
94557 +};
94558 +
94559 +struct fman_kg_hash_params
94560 +{
94561 + bool use_hash;
94562 + uint8_t shift_r;
94563 + uint32_t mask; /**< 24-bit mask */
94564 + bool sym; /**< Symmetric hash for src and dest pairs */
94565 +};
94566 +
94567 +struct fman_kg_pp_params
94568 +{
94569 + uint8_t base;
94570 + uint8_t shift;
94571 + uint8_t mask;
94572 + bool bypass_pp_gen;
94573 +};
94574 +
94575 +struct fman_kg_cc_params
94576 +{
94577 + uint8_t base_offset;
94578 + uint32_t qlcv_bits_sel;
94579 +};
94580 +
94581 +enum fman_pcd_engine
94582 +{
94583 + E_FMAN_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/
94584 + E_FMAN_PCD_DONE, /**< No PCD Engine indicated */
94585 + E_FMAN_PCD_KG, /**< Keygen indicated */
94586 + E_FMAN_PCD_CC, /**< Coarse classification indicated */
94587 + E_FMAN_PCD_PLCR, /**< Policer indicated */
94588 + E_FMAN_PCD_PRS /**< Parser indicated */
94589 +};
94590 +
94591 +struct fman_kg_cls_plan_params
94592 +{
94593 + uint8_t entries_mask;
94594 + uint32_t mask_vector[FM_KG_NUM_CLS_PLAN_ENTR];
94595 +};
94596 +
94597 +struct fman_kg_scheme_params
94598 +{
94599 + uint32_t match_vector;
94600 + struct fman_kg_extract_params extract_params;
94601 + struct fman_kg_hash_params hash_params;
94602 + uint32_t base_fqid;
94603 + /* What we do w/features supported per FM version ?? */
94604 + bool bypass_fqid_gen;
94605 + struct fman_kg_pp_params policer_params;
94606 + struct fman_kg_cc_params cc_params;
94607 + bool update_counter;
94608 + /**< counter_value: Set scheme counter to the specified value;
94609 + * relevant only when update_counter = TRUE. */
94610 + uint32_t counter_value;
94611 + enum fman_pcd_engine next_engine;
94612 + /**< Next engine action code */
94613 + uint32_t next_engine_action;
94614 +};
94615 +
94616 +
94617 +
94618 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar);
94619 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add);
94620 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp);
94621 +void fman_kg_get_event(struct fman_kg_regs *regs,
94622 + uint32_t *event,
94623 + uint32_t *scheme_idx);
94624 +void fman_kg_init(struct fman_kg_regs *regs,
94625 + uint32_t exceptions,
94626 + uint32_t dflt_nia);
94627 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs);
94628 +void fman_kg_enable(struct fman_kg_regs *regs);
94629 +void fman_kg_disable(struct fman_kg_regs *regs);
94630 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
94631 + uint8_t hwport_id,
94632 + uint32_t bind_cls_plans);
94633 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
94634 + uint8_t grp_mask,
94635 + uint32_t *bind_cls_plans);
94636 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
94637 + uint8_t hwport_id,
94638 + uint32_t schemes);
94639 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
94640 + uint8_t grp_id,
94641 + uint8_t entries_mask,
94642 + uint8_t hwport_id,
94643 + struct fman_kg_cp_regs *cls_plan_regs);
94644 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
94645 + struct fman_kg_cp_regs *cls_plan_regs);
94646 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs);
94647 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
94648 + uint8_t scheme_id,
94649 + uint8_t hwport_id,
94650 + uint32_t counter);
94651 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
94652 + uint8_t scheme_id,
94653 + uint8_t hwport_id,
94654 + uint32_t *counter);
94655 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
94656 + uint8_t scheme_id,
94657 + uint8_t hwport_id);
94658 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
94659 + uint8_t scheme_id,
94660 + uint8_t hwport_id,
94661 + struct fman_kg_scheme_regs *scheme_regs,
94662 + bool update_counter);
94663 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
94664 + struct fman_kg_scheme_regs *scheme_regs);
94665 +void fman_kg_get_capture(struct fman_kg_regs *regs,
94666 + struct fman_kg_ex_ecc_attr *ecc_attr,
94667 + bool clear);
94668 +void fman_kg_get_exception(struct fman_kg_regs *regs,
94669 + uint32_t *events,
94670 + uint32_t *scheme_ids,
94671 + bool clear);
94672 +void fman_kg_set_exception(struct fman_kg_regs *regs,
94673 + uint32_t exception,
94674 + bool enable);
94675 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
94676 + uint8_t def_id,
94677 + uint32_t val);
94678 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset);
94679 +
94680 +
94681 +
94682 +/**************************************************************************//**
94683 + @Description NIA Description
94684 +*//***************************************************************************/
94685 +#define KG_NIA_ORDER_RESTOR 0x00800000
94686 +#define KG_NIA_ENG_FM_CTL 0x00000000
94687 +#define KG_NIA_ENG_PRS 0x00440000
94688 +#define KG_NIA_ENG_KG 0x00480000
94689 +#define KG_NIA_ENG_PLCR 0x004C0000
94690 +#define KG_NIA_ENG_BMI 0x00500000
94691 +#define KG_NIA_ENG_QMI_ENQ 0x00540000
94692 +#define KG_NIA_ENG_QMI_DEQ 0x00580000
94693 +#define KG_NIA_ENG_MASK 0x007C0000
94694 +
94695 +#define KG_NIA_AC_MASK 0x0003FFFF
94696 +
94697 +#define KG_NIA_INVALID 0xFFFFFFFF
94698 +
94699 +static __inline__ uint32_t fm_kg_build_nia(enum fman_pcd_engine next_engine,
94700 + uint32_t next_engine_action)
94701 +{
94702 + uint32_t nia;
94703 +
94704 + if (next_engine_action & ~KG_NIA_AC_MASK)
94705 + return KG_NIA_INVALID;
94706 +
94707 + switch (next_engine) {
94708 + case E_FMAN_PCD_DONE:
94709 + nia = KG_NIA_ENG_BMI | next_engine_action;
94710 + break;
94711 +
94712 + case E_FMAN_PCD_KG:
94713 + nia = KG_NIA_ENG_KG | next_engine_action;
94714 + break;
94715 +
94716 + case E_FMAN_PCD_CC:
94717 + nia = KG_NIA_ENG_FM_CTL | next_engine_action;
94718 + break;
94719 +
94720 + case E_FMAN_PCD_PLCR:
94721 + nia = KG_NIA_ENG_PLCR | next_engine_action;
94722 + break;
94723 +
94724 + default:
94725 + nia = KG_NIA_INVALID;
94726 + }
94727 +
94728 + return nia;
94729 +}
94730 +
94731 +#endif /* __FSL_FMAN_KG_H */
94732 --- /dev/null
94733 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
94734 @@ -0,0 +1,434 @@
94735 +/*
94736 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94737 + *
94738 + * Redistribution and use in source and binary forms, with or without
94739 + * modification, are permitted provided that the following conditions are met:
94740 + * * Redistributions of source code must retain the above copyright
94741 + * notice, this list of conditions and the following disclaimer.
94742 + * * Redistributions in binary form must reproduce the above copyright
94743 + * notice, this list of conditions and the following disclaimer in the
94744 + * documentation and/or other materials provided with the distribution.
94745 + * * Neither the name of Freescale Semiconductor nor the
94746 + * names of its contributors may be used to endorse or promote products
94747 + * derived from this software without specific prior written permission.
94748 + *
94749 + *
94750 + * ALTERNATIVELY, this software may be distributed under the terms of the
94751 + * GNU General Public License ("GPL") as published by the Free Software
94752 + * Foundation, either version 2 of that License or (at your option) any
94753 + * later version.
94754 + *
94755 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94756 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94757 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94758 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94759 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94760 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94761 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94762 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94763 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94764 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94765 + */
94766 +
94767 +
94768 +#ifndef __FSL_FMAN_MEMAC_H
94769 +#define __FSL_FMAN_MEMAC_H
94770 +
94771 +#include "common/general.h"
94772 +#include "fsl_enet.h"
94773 +
94774 +
94775 +#define MEMAC_NUM_OF_PADDRS 7 /* Num of additional exact match MAC adr regs */
94776 +
94777 +/* Control and Configuration Register (COMMAND_CONFIG) */
94778 +#define CMD_CFG_MG 0x80000000 /* 00 Magic Packet detection */
94779 +#define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */
94780 +#define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */
94781 +#define CMD_CFG_SFD_ANY 0x00200000 /* 10 Disable SFD check */
94782 +#define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */
94783 +#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */
94784 +#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 Force idle generation */
94785 +#define CMD_CFG_CNT_FRM_EN 0x00002000 /* 18 Control frame rx enable */
94786 +#define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */
94787 +#define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */
94788 +#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 XGMII/GMII loopback enable */
94789 +#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 Tx source MAC addr insertion */
94790 +#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */
94791 +#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 Terminate/frwd Pause frames */
94792 +#define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */
94793 +#define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */
94794 +#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */
94795 +#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN mode enable */
94796 +#define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */
94797 +#define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */
94798 +
94799 +/* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */
94800 +#define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000
94801 +#define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF
94802 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000
94803 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000
94804 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G 0x00360000
94805 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G 0x00040000
94806 +#define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019
94807 +#define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020
94808 +#define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060
94809 +
94810 +#define GET_TX_EMPTY_DEFAULT_VALUE(_val) \
94811 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
94812 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
94813 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) : \
94814 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G));
94815 +
94816 +#define GET_TX_EMPTY_PFC_VALUE(_val) \
94817 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
94818 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
94819 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G) : \
94820 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G));
94821 +
94822 +/* Interface Mode Register (IF_MODE) */
94823 +#define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */
94824 +#define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */
94825 +#define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */
94826 +#define IF_MODE_RGMII 0x00000004
94827 +#define IF_MODE_RGMII_AUTO 0x00008000
94828 +#define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */
94829 +#define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */
94830 +#define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */
94831 +#define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */
94832 +#define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */
94833 +#define IF_MODE_HD 0x00000040 /* Half duplex operation */
94834 +
94835 +/* Hash table Control Register (HASHTABLE_CTRL) */
94836 +#define HASH_CTRL_MCAST_SHIFT 26
94837 +#define HASH_CTRL_MCAST_EN 0x00000100 /* 23 Mcast frame rx for hash */
94838 +#define HASH_CTRL_ADDR_MASK 0x0000003F /* 26-31 Hash table address code */
94839 +
94840 +#define GROUP_ADDRESS 0x0000010000000000LL /* MAC mcast indication */
94841 +#define HASH_TABLE_SIZE 64 /* Hash tbl size */
94842 +
94843 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
94844 +#define MEMAC_TX_IPG_LENGTH_MASK 0x0000003F
94845 +
94846 +/* Statistics Configuration Register (STATN_CONFIG) */
94847 +#define STATS_CFG_CLR 0x00000004 /* 29 Reset all counters */
94848 +#define STATS_CFG_CLR_ON_RD 0x00000002 /* 30 Clear on read */
94849 +#define STATS_CFG_SATURATE 0x00000001 /* 31 Saturate at the maximum val */
94850 +
94851 +/* Interrupt Mask Register (IMASK) */
94852 +#define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */
94853 +#define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */
94854 +#define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */
94855 +#define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */
94856 +
94857 +#define MEMAC_ALL_ERRS_IMASK \
94858 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | \
94859 + MEMAC_IMASK_TECC_ER | \
94860 + MEMAC_IMASK_RECC_ER | \
94861 + MEMAC_IMASK_MGI))
94862 +
94863 +#define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */
94864 +#define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */
94865 +#define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */
94866 +#define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */
94867 +#define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error */
94868 +#define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */
94869 +#define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */
94870 +#define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */
94871 +#define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */
94872 +#define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */
94873 +#define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */
94874 +#define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */
94875 +#define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */
94876 +#define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */
94877 +#define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */
94878 +#define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */
94879 +#define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */
94880 +
94881 +enum memac_counters {
94882 + E_MEMAC_COUNTER_R64,
94883 + E_MEMAC_COUNTER_T64,
94884 + E_MEMAC_COUNTER_R127,
94885 + E_MEMAC_COUNTER_T127,
94886 + E_MEMAC_COUNTER_R255,
94887 + E_MEMAC_COUNTER_T255,
94888 + E_MEMAC_COUNTER_R511,
94889 + E_MEMAC_COUNTER_T511,
94890 + E_MEMAC_COUNTER_R1023,
94891 + E_MEMAC_COUNTER_T1023,
94892 + E_MEMAC_COUNTER_R1518,
94893 + E_MEMAC_COUNTER_T1518,
94894 + E_MEMAC_COUNTER_R1519X,
94895 + E_MEMAC_COUNTER_T1519X,
94896 + E_MEMAC_COUNTER_RFRG,
94897 + E_MEMAC_COUNTER_RJBR,
94898 + E_MEMAC_COUNTER_RDRP,
94899 + E_MEMAC_COUNTER_RALN,
94900 + E_MEMAC_COUNTER_TUND,
94901 + E_MEMAC_COUNTER_ROVR,
94902 + E_MEMAC_COUNTER_RXPF,
94903 + E_MEMAC_COUNTER_TXPF,
94904 + E_MEMAC_COUNTER_ROCT,
94905 + E_MEMAC_COUNTER_RMCA,
94906 + E_MEMAC_COUNTER_RBCA,
94907 + E_MEMAC_COUNTER_RPKT,
94908 + E_MEMAC_COUNTER_RUCA,
94909 + E_MEMAC_COUNTER_RERR,
94910 + E_MEMAC_COUNTER_TOCT,
94911 + E_MEMAC_COUNTER_TMCA,
94912 + E_MEMAC_COUNTER_TBCA,
94913 + E_MEMAC_COUNTER_TUCA,
94914 + E_MEMAC_COUNTER_TERR
94915 +};
94916 +
94917 +#define DEFAULT_PAUSE_QUANTA 0xf000
94918 +#define DEFAULT_FRAME_LENGTH 0x600
94919 +#define DEFAULT_TX_IPG_LENGTH 12
94920 +
94921 +/*
94922 + * memory map
94923 + */
94924 +
94925 +struct mac_addr {
94926 + uint32_t mac_addr_l; /* Lower 32 bits of 48-bit MAC address */
94927 + uint32_t mac_addr_u; /* Upper 16 bits of 48-bit MAC address */
94928 +};
94929 +
94930 +struct memac_regs {
94931 + /* General Control and Status */
94932 + uint32_t res0000[2];
94933 + uint32_t command_config; /* 0x008 Ctrl and cfg */
94934 + struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */
94935 + uint32_t maxfrm; /* 0x014 Max frame length */
94936 + uint32_t res0018[1];
94937 + uint32_t rx_fifo_sections; /* Receive FIFO configuration reg */
94938 + uint32_t tx_fifo_sections; /* Transmit FIFO configuration reg */
94939 + uint32_t res0024[2];
94940 + uint32_t hashtable_ctrl; /* 0x02C Hash table control */
94941 + uint32_t res0030[4];
94942 + uint32_t ievent; /* 0x040 Interrupt event */
94943 + uint32_t tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */
94944 + uint32_t res0048;
94945 + uint32_t imask; /* 0x04C Interrupt mask */
94946 + uint32_t res0050;
94947 + uint32_t pause_quanta[4]; /* 0x054 Pause quanta */
94948 + uint32_t pause_thresh[4]; /* 0x064 Pause quanta threshold */
94949 + uint32_t rx_pause_status; /* 0x074 Receive pause status */
94950 + uint32_t res0078[2];
94951 + struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS]; /* 0x80-0x0B4 mac padr */
94952 + uint32_t lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */
94953 + uint32_t sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */
94954 + uint32_t res00c0[8];
94955 + uint32_t statn_config; /* 0x0E0 Statistics configuration */
94956 + uint32_t res00e4[7];
94957 + /* Rx Statistics Counter */
94958 + uint32_t reoct_l;
94959 + uint32_t reoct_u;
94960 + uint32_t roct_l;
94961 + uint32_t roct_u;
94962 + uint32_t raln_l;
94963 + uint32_t raln_u;
94964 + uint32_t rxpf_l;
94965 + uint32_t rxpf_u;
94966 + uint32_t rfrm_l;
94967 + uint32_t rfrm_u;
94968 + uint32_t rfcs_l;
94969 + uint32_t rfcs_u;
94970 + uint32_t rvlan_l;
94971 + uint32_t rvlan_u;
94972 + uint32_t rerr_l;
94973 + uint32_t rerr_u;
94974 + uint32_t ruca_l;
94975 + uint32_t ruca_u;
94976 + uint32_t rmca_l;
94977 + uint32_t rmca_u;
94978 + uint32_t rbca_l;
94979 + uint32_t rbca_u;
94980 + uint32_t rdrp_l;
94981 + uint32_t rdrp_u;
94982 + uint32_t rpkt_l;
94983 + uint32_t rpkt_u;
94984 + uint32_t rund_l;
94985 + uint32_t rund_u;
94986 + uint32_t r64_l;
94987 + uint32_t r64_u;
94988 + uint32_t r127_l;
94989 + uint32_t r127_u;
94990 + uint32_t r255_l;
94991 + uint32_t r255_u;
94992 + uint32_t r511_l;
94993 + uint32_t r511_u;
94994 + uint32_t r1023_l;
94995 + uint32_t r1023_u;
94996 + uint32_t r1518_l;
94997 + uint32_t r1518_u;
94998 + uint32_t r1519x_l;
94999 + uint32_t r1519x_u;
95000 + uint32_t rovr_l;
95001 + uint32_t rovr_u;
95002 + uint32_t rjbr_l;
95003 + uint32_t rjbr_u;
95004 + uint32_t rfrg_l;
95005 + uint32_t rfrg_u;
95006 + uint32_t rcnp_l;
95007 + uint32_t rcnp_u;
95008 + uint32_t rdrntp_l;
95009 + uint32_t rdrntp_u;
95010 + uint32_t res01d0[12];
95011 + /* Tx Statistics Counter */
95012 + uint32_t teoct_l;
95013 + uint32_t teoct_u;
95014 + uint32_t toct_l;
95015 + uint32_t toct_u;
95016 + uint32_t res0210[2];
95017 + uint32_t txpf_l;
95018 + uint32_t txpf_u;
95019 + uint32_t tfrm_l;
95020 + uint32_t tfrm_u;
95021 + uint32_t tfcs_l;
95022 + uint32_t tfcs_u;
95023 + uint32_t tvlan_l;
95024 + uint32_t tvlan_u;
95025 + uint32_t terr_l;
95026 + uint32_t terr_u;
95027 + uint32_t tuca_l;
95028 + uint32_t tuca_u;
95029 + uint32_t tmca_l;
95030 + uint32_t tmca_u;
95031 + uint32_t tbca_l;
95032 + uint32_t tbca_u;
95033 + uint32_t res0258[2];
95034 + uint32_t tpkt_l;
95035 + uint32_t tpkt_u;
95036 + uint32_t tund_l;
95037 + uint32_t tund_u;
95038 + uint32_t t64_l;
95039 + uint32_t t64_u;
95040 + uint32_t t127_l;
95041 + uint32_t t127_u;
95042 + uint32_t t255_l;
95043 + uint32_t t255_u;
95044 + uint32_t t511_l;
95045 + uint32_t t511_u;
95046 + uint32_t t1023_l;
95047 + uint32_t t1023_u;
95048 + uint32_t t1518_l;
95049 + uint32_t t1518_u;
95050 + uint32_t t1519x_l;
95051 + uint32_t t1519x_u;
95052 + uint32_t res02a8[6];
95053 + uint32_t tcnp_l;
95054 + uint32_t tcnp_u;
95055 + uint32_t res02c8[14];
95056 + /* Line Interface Control */
95057 + uint32_t if_mode; /* 0x300 Interface Mode Control */
95058 + uint32_t if_status; /* 0x304 Interface Status */
95059 + uint32_t res0308[14];
95060 + /* HiGig/2 */
95061 + uint32_t hg_config; /* 0x340 Control and cfg */
95062 + uint32_t res0344[3];
95063 + uint32_t hg_pause_quanta; /* 0x350 Pause quanta */
95064 + uint32_t res0354[3];
95065 + uint32_t hg_pause_thresh; /* 0x360 Pause quanta threshold */
95066 + uint32_t res0364[3];
95067 + uint32_t hgrx_pause_status; /* 0x370 Receive pause status */
95068 + uint32_t hg_fifos_status; /* 0x374 fifos status */
95069 + uint32_t rhm; /* 0x378 rx messages counter */
95070 + uint32_t thm; /* 0x37C tx messages counter */
95071 +};
95072 +
95073 +struct memac_cfg {
95074 + bool reset_on_init;
95075 + bool rx_error_discard;
95076 + bool pause_ignore;
95077 + bool pause_forward_enable;
95078 + bool no_length_check_enable;
95079 + bool cmd_frame_enable;
95080 + bool send_idle_enable;
95081 + bool wan_mode_enable;
95082 + bool promiscuous_mode_enable;
95083 + bool tx_addr_ins_enable;
95084 + bool loopback_enable;
95085 + bool lgth_check_nostdr;
95086 + bool time_stamp_enable;
95087 + bool pad_enable;
95088 + bool phy_tx_ena_on;
95089 + bool rx_sfd_any;
95090 + bool rx_pbl_fwd;
95091 + bool tx_pbl_fwd;
95092 + bool debug_mode;
95093 + bool wake_on_lan;
95094 + uint16_t max_frame_length;
95095 + uint16_t pause_quanta;
95096 + uint32_t tx_ipg_length;
95097 +};
95098 +
95099 +
95100 +/**
95101 + * fman_memac_defconfig() - Get default MEMAC configuration
95102 + * @cfg: pointer to configuration structure.
95103 + *
95104 + * Call this function to obtain a default set of configuration values for
95105 + * initializing MEMAC. The user can overwrite any of the values before calling
95106 + * fman_memac_init(), if specific configuration needs to be applied.
95107 + */
95108 +void fman_memac_defconfig(struct memac_cfg *cfg);
95109 +
95110 +int fman_memac_init(struct memac_regs *regs,
95111 + struct memac_cfg *cfg,
95112 + enum enet_interface enet_interface,
95113 + enum enet_speed enet_speed,
95114 + bool slow_10g_if,
95115 + uint32_t exceptions);
95116 +
95117 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
95118 +
95119 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
95120 +
95121 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val);
95122 +
95123 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
95124 + uint8_t *adr,
95125 + uint8_t paddr_num);
95126 +
95127 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
95128 + uint8_t paddr_num);
95129 +
95130 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
95131 + enum memac_counters reg_name);
95132 +
95133 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
95134 + uint8_t priority, uint16_t pauseTime, uint16_t threshTime);
95135 +
95136 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs);
95137 +
95138 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val,
95139 + bool enable);
95140 +
95141 +void fman_memac_reset_stat(struct memac_regs *regs);
95142 +
95143 +void fman_memac_reset(struct memac_regs *regs);
95144 +
95145 +void fman_memac_reset_filter_table(struct memac_regs *regs);
95146 +
95147 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc);
95148 +
95149 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val);
95150 +
95151 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,
95152 + bool enable);
95153 +
95154 +void fman_memac_set_wol(struct memac_regs *regs, bool enable);
95155 +
95156 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask);
95157 +
95158 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask);
95159 +
95160 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs);
95161 +
95162 +void fman_memac_adjust_link(struct memac_regs *regs,
95163 + enum enet_interface iface_mode,
95164 + enum enet_speed speed, bool full_dx);
95165 +
95166 +
95167 +
95168 +#endif /*__FSL_FMAN_MEMAC_H*/
95169 --- /dev/null
95170 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
95171 @@ -0,0 +1,78 @@
95172 +/*
95173 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95174 + *
95175 + * Redistribution and use in source and binary forms, with or without
95176 + * modification, are permitted provided that the following conditions are met:
95177 + * * Redistributions of source code must retain the above copyright
95178 + * notice, this list of conditions and the following disclaimer.
95179 + * * Redistributions in binary form must reproduce the above copyright
95180 + * notice, this list of conditions and the following disclaimer in the
95181 + * documentation and/or other materials provided with the distribution.
95182 + * * Neither the name of Freescale Semiconductor nor the
95183 + * names of its contributors may be used to endorse or promote products
95184 + * derived from this software without specific prior written permission.
95185 + *
95186 + *
95187 + * ALTERNATIVELY, this software may be distributed under the terms of the
95188 + * GNU General Public License ("GPL") as published by the Free Software
95189 + * Foundation, either version 2 of that License or (at your option) any
95190 + * later version.
95191 + *
95192 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95193 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95194 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95195 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95196 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95197 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95198 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95199 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95200 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95201 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95202 + */
95203 +
95204 +#ifndef __FSL_FMAN_MEMAC_MII_ACC_H
95205 +#define __FSL_FMAN_MEMAC_MII_ACC_H
95206 +
95207 +#include "common/general.h"
95208 +#include "fsl_enet.h"
95209 +/* MII Management Registers */
95210 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
95211 +#define MDIO_CFG_CLK_DIV_SHIFT 7
95212 +#define MDIO_CFG_HOLD_MASK 0x0000001c
95213 +#define MDIO_CFG_ENC45 0x00000040
95214 +#define MDIO_CFG_READ_ERR 0x00000002
95215 +#define MDIO_CFG_BSY 0x00000001
95216 +
95217 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
95218 +#define MDIO_CTL_READ 0x00008000
95219 +
95220 +#define MDIO_DATA_BSY 0x80000000
95221 +
95222 +/*MEMAC Internal PHY Registers - SGMII */
95223 +#define PHY_SGMII_CR_PHY_RESET 0x8000
95224 +#define PHY_SGMII_CR_RESET_AN 0x0200
95225 +#define PHY_SGMII_CR_DEF_VAL 0x1140
95226 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
95227 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
95228 +#define PHY_SGMII_IF_MODE_AN 0x0002
95229 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
95230 +#define PHY_SGMII_IF_MODE_1000X 0x0000
95231 +
95232 +/*----------------------------------------------------*/
95233 +/* MII Configuration Control Memory Map Registers */
95234 +/*----------------------------------------------------*/
95235 +struct memac_mii_access_mem_map {
95236 + uint32_t mdio_cfg; /* 0x030 */
95237 + uint32_t mdio_ctrl; /* 0x034 */
95238 + uint32_t mdio_data; /* 0x038 */
95239 + uint32_t mdio_addr; /* 0x03c */
95240 +};
95241 +
95242 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95243 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
95244 + enum enet_speed enet_speed);
95245 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95246 + uint8_t phy_addr, uint8_t reg, uint16_t data,
95247 + enum enet_speed enet_speed);
95248 +
95249 +#endif /* __MAC_API_MEMAC_MII_ACC_H */
95250 --- /dev/null
95251 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
95252 @@ -0,0 +1,593 @@
95253 +/*
95254 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95255 + *
95256 + * Redistribution and use in source and binary forms, with or without
95257 + * modification, are permitted provided that the following conditions are met:
95258 + * * Redistributions of source code must retain the above copyright
95259 + * notice, this list of conditions and the following disclaimer.
95260 + * * Redistributions in binary form must reproduce the above copyright
95261 + * notice, this list of conditions and the following disclaimer in the
95262 + * documentation and/or other materials provided with the distribution.
95263 + * * Neither the name of Freescale Semiconductor nor the
95264 + * names of its contributors may be used to endorse or promote products
95265 + * derived from this software without specific prior written permission.
95266 + *
95267 + *
95268 + * ALTERNATIVELY, this software may be distributed under the terms of the
95269 + * GNU General Public License ("GPL") as published by the Free Software
95270 + * Foundation, either version 2 of that License or (at your option) any
95271 + * later version.
95272 + *
95273 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95274 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95275 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95276 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95277 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95278 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95279 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95280 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95281 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95282 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95283 + */
95284 +
95285 +#ifndef __FSL_FMAN_PORT_H
95286 +#define __FSL_FMAN_PORT_H
95287 +
95288 +#include "fsl_fman_sp.h"
95289 +
95290 +/** @Collection Registers bit fields */
95291 +
95292 +/** @Description BMI defines */
95293 +#define BMI_EBD_EN 0x80000000
95294 +
95295 +#define BMI_PORT_CFG_EN 0x80000000
95296 +#define BMI_PORT_CFG_FDOVR 0x02000000
95297 +#define BMI_PORT_CFG_IM 0x01000000
95298 +
95299 +#define BMI_PORT_STATUS_BSY 0x80000000
95300 +
95301 +#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT
95302 +#define BMI_DMA_ATTR_IC_STASH_ON 0x10000000
95303 +#define BMI_DMA_ATTR_HDR_STASH_ON 0x04000000
95304 +#define BMI_DMA_ATTR_SG_STASH_ON 0x01000000
95305 +#define BMI_DMA_ATTR_WRITE_OPTIMIZE FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE
95306 +
95307 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
95308 +#define BMI_RX_FIFO_THRESHOLD_ETHE 0x80000000
95309 +
95310 +#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24
95311 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
95312 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
95313 +
95314 +#define BMI_IC_TO_EXT_SHIFT FMAN_SP_IC_TO_EXT_SHIFT
95315 +#define BMI_IC_FROM_INT_SHIFT FMAN_SP_IC_FROM_INT_SHIFT
95316 +
95317 +#define BMI_INT_BUF_MARG_SHIFT 28
95318 +#define BMI_EXT_BUF_MARG_START_SHIFT FMAN_SP_EXT_BUF_MARG_START_SHIFT
95319 +
95320 +#define BMI_CMD_MR_LEAC 0x00200000
95321 +#define BMI_CMD_MR_SLEAC 0x00100000
95322 +#define BMI_CMD_MR_MA 0x00080000
95323 +#define BMI_CMD_MR_DEAS 0x00040000
95324 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
95325 + BMI_CMD_MR_SLEAC | \
95326 + BMI_CMD_MR_MA | \
95327 + BMI_CMD_MR_DEAS)
95328 +#define BMI_CMD_TX_MR_DEF 0
95329 +#define BMI_CMD_OP_MR_DEF (BMI_CMD_MR_DEAS | \
95330 + BMI_CMD_MR_MA)
95331 +
95332 +#define BMI_CMD_ATTR_ORDER 0x80000000
95333 +#define BMI_CMD_ATTR_SYNC 0x02000000
95334 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
95335 +
95336 +#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12
95337 +#define BMI_NEXT_ENG_FD_BITS_SHIFT 24
95338 +#define BMI_FRAME_END_CS_IGNORE_SHIFT 24
95339 +
95340 +#define BMI_COUNTERS_EN 0x80000000
95341 +
95342 +#define BMI_EXT_BUF_POOL_VALID FMAN_SP_EXT_BUF_POOL_VALID
95343 +#define BMI_EXT_BUF_POOL_EN_COUNTER FMAN_SP_EXT_BUF_POOL_EN_COUNTER
95344 +#define BMI_EXT_BUF_POOL_BACKUP FMAN_SP_EXT_BUF_POOL_BACKUP
95345 +#define BMI_EXT_BUF_POOL_ID_SHIFT 16
95346 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
95347 +#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16
95348 +
95349 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
95350 +#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12
95351 +
95352 +#define MAX_PERFORMANCE_TASK_COMP 64
95353 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
95354 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
95355 +#define MAX_PERFORMANCE_DMA_COMP 16
95356 +#define MAX_PERFORMANCE_FIFO_COMP 1024
95357 +
95358 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
95359 +#define BMI_PERFORMANCE_QUEUE_COMP_SHIFT 16
95360 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
95361 +
95362 +#define BMI_RATE_LIMIT_GRAN_TX 16000 /* In Kbps */
95363 +#define BMI_RATE_LIMIT_GRAN_OP 10000 /* In frames */
95364 +#define BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS 1024
95365 +#define BMI_RATE_LIMIT_MAX_BURST_SIZE 1024 /* In KBytes */
95366 +#define BMI_RATE_LIMIT_MAX_BURST_SHIFT 16
95367 +#define BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN 0x80000000
95368 +#define BMI_RATE_LIMIT_SCALE_TSBS_SHIFT 16
95369 +#define BMI_RATE_LIMIT_SCALE_EN 0x80000000
95370 +#define BMI_SG_DISABLE FMAN_SP_SG_DISABLE
95371 +
95372 +/** @Description QMI defines */
95373 +#define QMI_PORT_CFG_EN 0x80000000
95374 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
95375 +
95376 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
95377 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
95378 +
95379 +#define QMI_DEQ_CFG_PRI 0x80000000
95380 +#define QMI_DEQ_CFG_TYPE1 0x10000000
95381 +#define QMI_DEQ_CFG_TYPE2 0x20000000
95382 +#define QMI_DEQ_CFG_TYPE3 0x30000000
95383 +#define QMI_DEQ_CFG_PREFETCH_PARTIAL 0x01000000
95384 +#define QMI_DEQ_CFG_PREFETCH_FULL 0x03000000
95385 +#define QMI_DEQ_CFG_SP_MASK 0xf
95386 +#define QMI_DEQ_CFG_SP_SHIFT 20
95387 +
95388 +
95389 +/** @Description General port defines */
95390 +#define FMAN_PORT_EXT_POOLS_NUM(fm_rev_maj) \
95391 + (((fm_rev_maj) == 4) ? 4 : 8)
95392 +#define FMAN_PORT_MAX_EXT_POOLS_NUM 8
95393 +#define FMAN_PORT_OBS_EXT_POOLS_NUM 2
95394 +#define FMAN_PORT_CG_MAP_NUM 8
95395 +#define FMAN_PORT_PRS_RESULT_WORDS_NUM 8
95396 +#define FMAN_PORT_BMI_FIFO_UNITS 0x100
95397 +#define FMAN_PORT_IC_OFFSET_UNITS 0x10
95398 +
95399 +
95400 +/** @Collection FM Port Register Map */
95401 +
95402 +/** @Description BMI Rx port register map */
95403 +struct fman_port_rx_bmi_regs {
95404 + uint32_t fmbm_rcfg; /**< Rx Configuration */
95405 + uint32_t fmbm_rst; /**< Rx Status */
95406 + uint32_t fmbm_rda; /**< Rx DMA attributes*/
95407 + uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
95408 + uint32_t fmbm_rfed; /**< Rx Frame End Data*/
95409 + uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
95410 + uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
95411 + uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
95412 + uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
95413 + uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
95414 + uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
95415 + uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
95416 + uint32_t fmbm_rpp; /**< Rx Policer Profile */
95417 + uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
95418 + uint32_t fmbm_reth; /**< Rx Excessive Threshold */
95419 + uint32_t reserved003c[1]; /**< (0x03C 0x03F) */
95420 + uint32_t fmbm_rprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95421 + /**< Rx Parse Results Array Init*/
95422 + uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
95423 + uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
95424 + uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
95425 + uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
95426 + uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
95427 + uint32_t reserved0074[0x2]; /**< (0x074-0x07C) */
95428 + uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
95429 + uint32_t reserved0080[0x20];/**< (0x080 0x0FF) */
95430 + uint32_t fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM];
95431 + /**< Buffer Manager pool Information-*/
95432 + uint32_t fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM];
95433 + /**< Allocate Counter-*/
95434 + uint32_t reserved0130[8];
95435 + /**< 0x130/0x140 - 0x15F reserved -*/
95436 + uint32_t fmbm_rcgm[FMAN_PORT_CG_MAP_NUM];
95437 + /**< Congestion Group Map*/
95438 + uint32_t fmbm_mpd; /**< BM Pool Depletion */
95439 + uint32_t reserved0184[0x1F]; /**< (0x184 0x1FF) */
95440 + uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
95441 + uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
95442 + uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
95443 + uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
95444 + uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
95445 + uint32_t fmbm_rfdc; /**< Rx Frame Discard Counter*/
95446 + uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
95447 + uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard nntr*/
95448 + uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/
95449 + uint32_t reserved0224[0x17]; /**< (0x224 0x27F) */
95450 + uint32_t fmbm_rpc; /**< Rx Performance Counters*/
95451 + uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
95452 + uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
95453 + uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
95454 + uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization cntr*/
95455 + uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
95456 + uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
95457 + uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
95458 + uint32_t reserved02a0[0x18]; /**< (0x2A0 0x2FF) */
95459 + uint32_t fmbm_rdbg; /**< Rx Debug-*/
95460 +};
95461 +
95462 +/** @Description BMI Tx port register map */
95463 +struct fman_port_tx_bmi_regs {
95464 + uint32_t fmbm_tcfg; /**< Tx Configuration */
95465 + uint32_t fmbm_tst; /**< Tx Status */
95466 + uint32_t fmbm_tda; /**< Tx DMA attributes */
95467 + uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
95468 + uint32_t fmbm_tfed; /**< Tx Frame End Data */
95469 + uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
95470 + uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
95471 + uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
95472 + uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
95473 + uint32_t fmbm_tefqid; /**< Tx Frame Error Queue ID */
95474 + uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
95475 + uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
95476 + uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
95477 + uint32_t reserved0034[0x0e]; /**< (0x034-0x6c) */
95478 + uint32_t fmbm_tccb; /**< Tx Coarse Classification base */
95479 + uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
95480 + uint32_t fmbm_tpfcm[0x02]; /**< Tx Priority based Flow Control (PFC) Mapping */
95481 + uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
95482 + uint32_t reserved0080[0x60]; /**< (0x080-0x200) */
95483 + uint32_t fmbm_tstc; /**< Tx Statistics Counters */
95484 + uint32_t fmbm_tfrc; /**< Tx Frame Counter */
95485 + uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
95486 + uint32_t fmbm_tfledc; /**< Tx Frame len error discard cntr */
95487 + uint32_t fmbm_tfufdc; /**< Tx Frame unsprt frmt discard cntr*/
95488 + uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
95489 + uint32_t reserved0218[0x1A]; /**< (0x218-0x280) */
95490 + uint32_t fmbm_tpc; /**< Tx Performance Counters*/
95491 + uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
95492 + uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
95493 + uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
95494 + uint32_t fmbm_ttcquc; /**< Tx Transmit conf Q util Counter*/
95495 + uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
95496 + uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
95497 +};
95498 +
95499 +/** @Description BMI O/H port register map */
95500 +struct fman_port_oh_bmi_regs {
95501 + uint32_t fmbm_ocfg; /**< O/H Configuration */
95502 + uint32_t fmbm_ost; /**< O/H Status */
95503 + uint32_t fmbm_oda; /**< O/H DMA attributes */
95504 + uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
95505 + uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
95506 + uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
95507 + uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
95508 + uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
95509 + uint32_t fmbm_opso; /**< O/H Parse Start Offset */
95510 + uint32_t fmbm_opp; /**< O/H Policer Profile */
95511 + uint32_t fmbm_occb; /**< O/H Coarse Classification base */
95512 + uint32_t fmbm_oim; /**< O/H Internal margins*/
95513 + uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
95514 + uint32_t fmbm_ofed; /**< O/H Frame End Data*/
95515 + uint32_t reserved0030[2]; /**< (0x038 - 0x03F) */
95516 + uint32_t fmbm_oprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95517 + /**< O/H Parse Results Array Initialization */
95518 + uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
95519 + uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
95520 + uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
95521 + uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
95522 + uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
95523 + uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
95524 + uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
95525 + uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
95526 + uint32_t reserved0080[0x20]; /**< 0x080 - 0x0FF Reserved */
95527 + uint32_t fmbm_oebmpi[2]; /**< Buf Mngr Observed Pool Info */
95528 + uint32_t reserved0108[0x16]; /**< 0x108 - 0x15F Reserved */
95529 + uint32_t fmbm_ocgm[FMAN_PORT_CG_MAP_NUM]; /**< Observed Congestion Group Map */
95530 + uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
95531 + uint32_t reserved0184[0x1F]; /**< 0x184 - 0x1FF Reserved */
95532 + uint32_t fmbm_ostc; /**< O/H Statistics Counters */
95533 + uint32_t fmbm_ofrc; /**< O/H Frame Counter */
95534 + uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
95535 + uint32_t fmbm_ofledc; /**< O/H Frames Len Err Discard Cntr */
95536 + uint32_t fmbm_ofufdc; /**< O/H Frames Unsprtd Discard Cutr */
95537 + uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
95538 + uint32_t fmbm_ofwdc; /**< Rx Frames WRED Discard Counter */
95539 + uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Cntr */
95540 + uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
95541 + uint32_t reserved0218[0x17]; /**< (0x218 - 0x27F) */
95542 + uint32_t fmbm_opc; /**< O/H Performance Counters */
95543 + uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
95544 + uint32_t fmbm_occn; /**< O/H Cycle Counter */
95545 + uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
95546 + uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
95547 + uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
95548 +};
95549 +
95550 +/** @Description BMI port register map */
95551 +union fman_port_bmi_regs {
95552 + struct fman_port_rx_bmi_regs rx;
95553 + struct fman_port_tx_bmi_regs tx;
95554 + struct fman_port_oh_bmi_regs oh;
95555 +};
95556 +
95557 +/** @Description QMI port register map */
95558 +struct fman_port_qmi_regs {
95559 + uint32_t fmqm_pnc; /**< PortID n Configuration Register */
95560 + uint32_t fmqm_pns; /**< PortID n Status Register */
95561 + uint32_t fmqm_pnts; /**< PortID n Task Status Register */
95562 + uint32_t reserved00c[4]; /**< 0xn00C - 0xn01B */
95563 + uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
95564 + uint32_t fmqm_pnetfc; /**< PortID n Enq Total Frame Counter */
95565 + uint32_t reserved024[2]; /**< 0xn024 - 0x02B */
95566 + uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
95567 + uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
95568 + uint32_t fmqm_pndtfc; /**< PortID n Dequeue tot Frame cntr */
95569 + uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID Dflt Cntr */
95570 + uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
95571 +};
95572 +
95573 +
95574 +enum fman_port_dma_swap {
95575 + E_FMAN_PORT_DMA_NO_SWAP, /**< No swap, transfer data as is */
95576 + E_FMAN_PORT_DMA_SWAP_LE,
95577 + /**< The transferred data should be swapped in PPC Little Endian mode */
95578 + E_FMAN_PORT_DMA_SWAP_BE
95579 + /**< The transferred data should be swapped in Big Endian mode */
95580 +};
95581 +
95582 +/* Default port color */
95583 +enum fman_port_color {
95584 + E_FMAN_PORT_COLOR_GREEN, /**< Default port color is green */
95585 + E_FMAN_PORT_COLOR_YELLOW, /**< Default port color is yellow */
95586 + E_FMAN_PORT_COLOR_RED, /**< Default port color is red */
95587 + E_FMAN_PORT_COLOR_OVERRIDE /**< Ignore color */
95588 +};
95589 +
95590 +/* QMI dequeue from the SP channel - types */
95591 +enum fman_port_deq_type {
95592 + E_FMAN_PORT_DEQ_BY_PRI,
95593 + /**< Priority precedence and Intra-Class scheduling */
95594 + E_FMAN_PORT_DEQ_ACTIVE_FQ,
95595 + /**< Active FQ precedence and Intra-Class scheduling */
95596 + E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS
95597 + /**< Active FQ precedence and override Intra-Class scheduling */
95598 +};
95599 +
95600 +/* QMI dequeue prefetch modes */
95601 +enum fman_port_deq_prefetch {
95602 + E_FMAN_PORT_DEQ_NO_PREFETCH, /**< No prefetch mode */
95603 + E_FMAN_PORT_DEQ_PART_PREFETCH, /**< Partial prefetch mode */
95604 + E_FMAN_PORT_DEQ_FULL_PREFETCH /**< Full prefetch mode */
95605 +};
95606 +
95607 +/* Parameters for defining performance counters behavior */
95608 +struct fman_port_perf_cnt_params {
95609 + uint8_t task_val; /**< Task compare value */
95610 + uint8_t queue_val;
95611 + /**< Rx or Tx conf queue compare value (unused for O/H ports) */
95612 + uint8_t dma_val; /**< Dma compare value */
95613 + uint32_t fifo_val; /**< Fifo compare value (in bytes) */
95614 +};
95615 +
95616 +/** @Description FM Port configuration structure, used at init */
95617 +struct fman_port_cfg {
95618 + struct fman_port_perf_cnt_params perf_cnt_params;
95619 + /* BMI parameters */
95620 + enum fman_port_dma_swap dma_swap_data;
95621 + bool dma_ic_stash_on;
95622 + bool dma_header_stash_on;
95623 + bool dma_sg_stash_on;
95624 + bool dma_write_optimize;
95625 + uint16_t ic_ext_offset;
95626 + uint8_t ic_int_offset;
95627 + uint16_t ic_size;
95628 + enum fman_port_color color;
95629 + bool sync_req;
95630 + bool discard_override;
95631 + uint8_t checksum_bytes_ignore;
95632 + uint8_t rx_cut_end_bytes;
95633 + uint32_t rx_pri_elevation;
95634 + uint32_t rx_fifo_thr;
95635 + uint8_t rx_fd_bits;
95636 + uint8_t int_buf_start_margin;
95637 + uint16_t ext_buf_start_margin;
95638 + uint16_t ext_buf_end_margin;
95639 + uint32_t tx_fifo_min_level;
95640 + uint32_t tx_fifo_low_comf_level;
95641 + uint8_t tx_fifo_deq_pipeline_depth;
95642 + bool stats_counters_enable;
95643 + bool perf_counters_enable;
95644 + /* QMI parameters */
95645 + bool deq_high_pri;
95646 + enum fman_port_deq_type deq_type;
95647 + enum fman_port_deq_prefetch deq_prefetch_opt;
95648 + uint16_t deq_byte_cnt;
95649 + bool queue_counters_enable;
95650 + bool no_scatter_gather;
95651 + int errata_A006675;
95652 + int errata_A006320;
95653 + int excessive_threshold_register;
95654 + int fmbm_rebm_has_sgd;
95655 + int fmbm_tfne_has_features;
95656 + int qmi_deq_options_support;
95657 +};
95658 +
95659 +enum fman_port_type {
95660 + E_FMAN_PORT_TYPE_OP = 0,
95661 + /**< Offline parsing port, shares id-s with
95662 + * host command, so must have exclusive id-s */
95663 + E_FMAN_PORT_TYPE_RX, /**< 1G Rx port */
95664 + E_FMAN_PORT_TYPE_RX_10G, /**< 10G Rx port */
95665 + E_FMAN_PORT_TYPE_TX, /**< 1G Tx port */
95666 + E_FMAN_PORT_TYPE_TX_10G, /**< 10G Tx port */
95667 + E_FMAN_PORT_TYPE_DUMMY,
95668 + E_FMAN_PORT_TYPE_HC = E_FMAN_PORT_TYPE_DUMMY
95669 + /**< Host command port, shares id-s with
95670 + * offline parsing ports, so must have exclusive id-s */
95671 +};
95672 +
95673 +struct fman_port_params {
95674 + uint32_t discard_mask;
95675 + uint32_t err_mask;
95676 + uint32_t dflt_fqid;
95677 + uint32_t err_fqid;
95678 + uint8_t deq_sp;
95679 + bool dont_release_buf;
95680 +};
95681 +
95682 +/* Port context - used by most API functions */
95683 +struct fman_port {
95684 + enum fman_port_type type;
95685 + uint8_t fm_rev_maj;
95686 + uint8_t fm_rev_min;
95687 + union fman_port_bmi_regs *bmi_regs;
95688 + struct fman_port_qmi_regs *qmi_regs;
95689 + bool im_en;
95690 + uint8_t ext_pools_num;
95691 +};
95692 +
95693 +/** @Description External buffer pools configuration */
95694 +struct fman_port_bpools {
95695 + uint8_t count; /**< Num of pools to set up */
95696 + bool counters_enable; /**< Enable allocate counters */
95697 + uint8_t grp_bp_depleted_num;
95698 + /**< Number of depleted pools - if reached the BMI indicates
95699 + * the MAC to send a pause frame */
95700 + struct {
95701 + uint8_t bpid; /**< BM pool ID */
95702 + uint16_t size;
95703 + /**< Pool's size - must be in ascending order */
95704 + bool is_backup;
95705 + /**< If this is a backup pool */
95706 + bool grp_bp_depleted;
95707 + /**< Consider this buffer in multiple pools depletion criteria*/
95708 + bool single_bp_depleted;
95709 + /**< Consider this buffer in single pool depletion criteria */
95710 + bool pfc_priorities_en;
95711 + } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM];
95712 +};
95713 +
95714 +enum fman_port_rate_limiter_scale_down {
95715 + E_FMAN_PORT_RATE_DOWN_NONE,
95716 + E_FMAN_PORT_RATE_DOWN_BY_2,
95717 + E_FMAN_PORT_RATE_DOWN_BY_4,
95718 + E_FMAN_PORT_RATE_DOWN_BY_8
95719 +};
95720 +
95721 +/* Rate limiter configuration */
95722 +struct fman_port_rate_limiter {
95723 + uint8_t count_1micro_bit;
95724 + bool high_burst_size_gran;
95725 + /**< Defines burst_size granularity for OP ports; when TRUE,
95726 + * burst_size below counts in frames, otherwise in 10^3 frames */
95727 + uint16_t burst_size;
95728 + /**< Max burst size, in KBytes for Tx port, according to
95729 + * high_burst_size_gran definition for OP port */
95730 + uint32_t rate;
95731 + /**< In Kbps for Tx port, in frames/sec for OP port */
95732 + enum fman_port_rate_limiter_scale_down rate_factor;
95733 +};
95734 +
95735 +/* BMI statistics counters */
95736 +enum fman_port_stats_counters {
95737 + E_FMAN_PORT_STATS_CNT_FRAME,
95738 + /**< Number of processed frames; valid for all ports */
95739 + E_FMAN_PORT_STATS_CNT_DISCARD,
95740 + /**< For Rx ports - frames discarded by QMAN, for Tx or O/H ports -
95741 + * frames discarded due to DMA error; valid for all ports */
95742 + E_FMAN_PORT_STATS_CNT_DEALLOC_BUF,
95743 + /**< Number of buffer deallocate operations; valid for all ports */
95744 + E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME,
95745 + /**< Number of bad Rx frames, like CRC error, Rx FIFO overflow etc;
95746 + * valid for Rx ports only */
95747 + E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME,
95748 + /**< Number of Rx oversized frames, that is frames exceeding max frame
95749 + * size configured for the corresponding ETH controller;
95750 + * valid for Rx ports only */
95751 + E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF,
95752 + /**< Frames discarded due to lack of external buffers; valid for
95753 + * Rx ports only */
95754 + E_FMAN_PORT_STATS_CNT_LEN_ERR,
95755 + /**< Frames discarded due to frame length error; valid for Tx and
95756 + * O/H ports only */
95757 + E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT,
95758 + /**< Frames discarded due to unsupported FD format; valid for Tx
95759 + * and O/H ports only */
95760 + E_FMAN_PORT_STATS_CNT_FILTERED_FRAME,
95761 + /**< Number of frames filtered out by PCD module; valid for
95762 + * Rx and OP ports only */
95763 + E_FMAN_PORT_STATS_CNT_DMA_ERR,
95764 + /**< Frames rejected by QMAN that were not able to release their
95765 + * buffers due to DMA error; valid for Rx and O/H ports only */
95766 + E_FMAN_PORT_STATS_CNT_WRED_DISCARD
95767 + /**< Frames going through O/H port that were not able to to enter the
95768 + * return queue due to WRED algorithm; valid for O/H ports only */
95769 +};
95770 +
95771 +/* BMI performance counters */
95772 +enum fman_port_perf_counters {
95773 + E_FMAN_PORT_PERF_CNT_CYCLE, /**< Cycle counter */
95774 + E_FMAN_PORT_PERF_CNT_TASK_UTIL, /**< Tasks utilization counter */
95775 + E_FMAN_PORT_PERF_CNT_QUEUE_UTIL,
95776 + /**< For Rx ports - Rx queue utilization, for Tx ports - Tx conf queue
95777 + * utilization; not valid for O/H ports */
95778 + E_FMAN_PORT_PERF_CNT_DMA_UTIL, /**< DMA utilization counter */
95779 + E_FMAN_PORT_PERF_CNT_FIFO_UTIL, /**< FIFO utilization counter */
95780 + E_FMAN_PORT_PERF_CNT_RX_PAUSE
95781 + /**< Number of cycles in which Rx pause activation control is on;
95782 + * valid for Rx ports only */
95783 +};
95784 +
95785 +/* QMI counters */
95786 +enum fman_port_qmi_counters {
95787 + E_FMAN_PORT_ENQ_TOTAL, /**< EnQ tot frame cntr */
95788 + E_FMAN_PORT_DEQ_TOTAL, /**< DeQ tot frame cntr; invalid for Rx ports */
95789 + E_FMAN_PORT_DEQ_FROM_DFLT,
95790 + /**< Dequeue from default FQID counter not valid for Rx ports */
95791 + E_FMAN_PORT_DEQ_CONFIRM /**< DeQ confirm cntr invalid for Rx ports */
95792 +};
95793 +
95794 +
95795 +/** @Collection FM Port API */
95796 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type);
95797 +int fman_port_init(struct fman_port *port,
95798 + struct fman_port_cfg *cfg,
95799 + struct fman_port_params *params);
95800 +int fman_port_enable(struct fman_port *port);
95801 +int fman_port_disable(const struct fman_port *port);
95802 +int fman_port_set_bpools(const struct fman_port *port,
95803 + const struct fman_port_bpools *bp);
95804 +int fman_port_set_rate_limiter(struct fman_port *port,
95805 + struct fman_port_rate_limiter *rate_limiter);
95806 +int fman_port_delete_rate_limiter(struct fman_port *port);
95807 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask);
95808 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask);
95809 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
95810 + uint8_t rx_fd_bits,
95811 + bool add);
95812 +int fman_port_set_perf_cnt_params(struct fman_port *port,
95813 + struct fman_port_perf_cnt_params *params);
95814 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable);
95815 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable);
95816 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable);
95817 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
95818 + uint8_t bpid,
95819 + bool enable);
95820 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
95821 + enum fman_port_stats_counters counter);
95822 +void fman_port_set_stats_counter(struct fman_port *port,
95823 + enum fman_port_stats_counters counter,
95824 + uint32_t value);
95825 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
95826 + enum fman_port_perf_counters counter);
95827 +void fman_port_set_perf_counter(struct fman_port *port,
95828 + enum fman_port_perf_counters counter,
95829 + uint32_t value);
95830 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
95831 + enum fman_port_qmi_counters counter);
95832 +void fman_port_set_qmi_counter(struct fman_port *port,
95833 + enum fman_port_qmi_counters counter,
95834 + uint32_t value);
95835 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid);
95836 +void fman_port_set_bpool_counter(struct fman_port *port,
95837 + uint8_t bpid,
95838 + uint32_t value);
95839 +int fman_port_add_congestion_grps(struct fman_port *port,
95840 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
95841 +int fman_port_remove_congestion_grps(struct fman_port *port,
95842 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
95843 +
95844 +
95845 +#endif /* __FSL_FMAN_PORT_H */
95846 --- /dev/null
95847 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
95848 @@ -0,0 +1,102 @@
95849 +/*
95850 + * Copyright 2008-2012 Freescale Semiconductor Inc.
95851 + *
95852 + * Redistribution and use in source and binary forms, with or without
95853 + * modification, are permitted provided that the following conditions are met:
95854 + * * Redistributions of source code must retain the above copyright
95855 + * notice, this list of conditions and the following disclaimer.
95856 + * * Redistributions in binary form must reproduce the above copyright
95857 + * notice, this list of conditions and the following disclaimer in the
95858 + * documentation and/or other materials provided with the distribution.
95859 + * * Neither the name of Freescale Semiconductor nor the
95860 + * names of its contributors may be used to endorse or promote products
95861 + * derived from this software without specific prior written permission.
95862 + *
95863 + *
95864 + * ALTERNATIVELY, this software may be distributed under the terms of the
95865 + * GNU General Public License ("GPL") as published by the Free Software
95866 + * Foundation, either version 2 of that License or (at your option) any
95867 + * later version.
95868 + *
95869 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95870 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95871 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95872 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95873 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95874 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95875 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95876 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95877 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95878 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95879 + */
95880 +
95881 +#ifndef __FSL_FMAN_PRS_H
95882 +#define __FSL_FMAN_PRS_H
95883 +
95884 +#include "common/general.h"
95885 +
95886 +#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000
95887 +#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000
95888 +
95889 +#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000
95890 +#define FM_PCD_PRS_RPIMAC_EN 0x00000001
95891 +#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000
95892 +#define FM_PCD_PRS_SINGLE_ECC 0x00004000
95893 +#define FM_PCD_PRS_DOUBLE_ECC 0x00004000
95894 +#define PRS_MAX_CYCLE_LIMIT 8191
95895 +
95896 +#define DEFAULT_MAX_PRS_CYC_LIM 0
95897 +
95898 +struct fman_prs_regs {
95899 + uint32_t fmpr_rpclim;
95900 + uint32_t fmpr_rpimac;
95901 + uint32_t pmeec;
95902 + uint32_t res00c[5];
95903 + uint32_t fmpr_pevr;
95904 + uint32_t fmpr_pever;
95905 + uint32_t res028;
95906 + uint32_t fmpr_perr;
95907 + uint32_t fmpr_perer;
95908 + uint32_t res034;
95909 + uint32_t res038[10];
95910 + uint32_t fmpr_ppsc;
95911 + uint32_t res064;
95912 + uint32_t fmpr_pds;
95913 + uint32_t fmpr_l2rrs;
95914 + uint32_t fmpr_l3rrs;
95915 + uint32_t fmpr_l4rrs;
95916 + uint32_t fmpr_srrs;
95917 + uint32_t fmpr_l2rres;
95918 + uint32_t fmpr_l3rres;
95919 + uint32_t fmpr_l4rres;
95920 + uint32_t fmpr_srres;
95921 + uint32_t fmpr_spcs;
95922 + uint32_t fmpr_spscs;
95923 + uint32_t fmpr_hxscs;
95924 + uint32_t fmpr_mrcs;
95925 + uint32_t fmpr_mwcs;
95926 + uint32_t fmpr_mrscs;
95927 + uint32_t fmpr_mwscs;
95928 + uint32_t fmpr_fcscs;
95929 +};
95930 +
95931 +struct fman_prs_cfg {
95932 + uint32_t port_id_stat;
95933 + uint16_t max_prs_cyc_lim;
95934 + uint32_t prs_exceptions;
95935 +};
95936 +
95937 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask);
95938 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs);
95939 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event);
95940 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask);
95941 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs);
95942 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event);
95943 +void fman_prs_defconfig(struct fman_prs_cfg *cfg);
95944 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg);
95945 +void fman_prs_enable(struct fman_prs_regs *regs);
95946 +void fman_prs_disable(struct fman_prs_regs *regs);
95947 +int fman_prs_is_enabled(struct fman_prs_regs *regs);
95948 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk);
95949 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable);
95950 +#endif /* __FSL_FMAN_PRS_H */
95951 --- /dev/null
95952 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
95953 @@ -0,0 +1,449 @@
95954 +/*
95955 + * Copyright 2013 Freescale Semiconductor Inc.
95956 + *
95957 + * Redistribution and use in source and binary forms, with or without
95958 + * modification, are permitted provided that the following conditions are met:
95959 + * * Redistributions of source code must retain the above copyright
95960 + * notice, this list of conditions and the following disclaimer.
95961 + * * Redistributions in binary form must reproduce the above copyright
95962 + * notice, this list of conditions and the following disclaimer in the
95963 + * documentation and/or other materials provided with the distribution.
95964 + * * Neither the name of Freescale Semiconductor nor the
95965 + * names of its contributors may be used to endorse or promote products
95966 + * derived from this software without specific prior written permission.
95967 + *
95968 + *
95969 + * ALTERNATIVELY, this software may be distributed under the terms of the
95970 + * GNU General Public License ("GPL") as published by the Free Software
95971 + * Foundation, either version 2 of that License or (at your option) any
95972 + * later version.
95973 + *
95974 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95975 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95976 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95977 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95978 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95979 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95980 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95981 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95982 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95983 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95984 + */
95985 +
95986 +#ifndef __FSL_FMAN_RTC_H
95987 +#define __FSL_FMAN_RTC_H
95988 +
95989 +#include "common/general.h"
95990 +
95991 +/* FM RTC Registers definitions */
95992 +#define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000
95993 +#define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000
95994 +#define FMAN_RTC_TMR_CTRL_FS 0x10000000
95995 +#define FMAN_RTC_TMR_CTRL_PP1L 0x08000000
95996 +#define FMAN_RTC_TMR_CTRL_PP2L 0x04000000
95997 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000
95998 +#define FMAN_RTC_TMR_CTRL_FRD 0x00004000
95999 +#define FMAN_RTC_TMR_CTRL_SLV 0x00002000
96000 +#define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100
96001 +#define FMAN_RTC_TMR_CTRL_COPH 0x00000080
96002 +#define FMAN_RTC_TMR_CTRL_CIPH 0x00000040
96003 +#define FMAN_RTC_TMR_CTRL_TMSR 0x00000020
96004 +#define FMAN_RTC_TMR_CTRL_DBG 0x00000010
96005 +#define FMAN_RTC_TMR_CTRL_BYP 0x00000008
96006 +#define FMAN_RTC_TMR_CTRL_TE 0x00000004
96007 +#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003
96008 +#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001
96009 +#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000
96010 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16
96011 +
96012 +#define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000
96013 +#define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000
96014 +#define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000
96015 +#define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000
96016 +#define FMAN_RTC_TMR_TEVENT_PP1 0x00000080
96017 +#define FMAN_RTC_TMR_TEVENT_PP2 0x00000040
96018 +#define FMAN_RTC_TMR_TEVENT_PP3 0x00000020
96019 +#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\
96020 + FMAN_RTC_TMR_TEVENT_ETS1 |\
96021 + FMAN_RTC_TMR_TEVENT_ALM2 |\
96022 + FMAN_RTC_TMR_TEVENT_ALM1 |\
96023 + FMAN_RTC_TMR_TEVENT_PP1 |\
96024 + FMAN_RTC_TMR_TEVENT_PP2 |\
96025 + FMAN_RTC_TMR_TEVENT_PP3)
96026 +
96027 +#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF
96028 +
96029 +/**************************************************************************//**
96030 + @Description FM RTC Alarm Polarity Options.
96031 +*//***************************************************************************/
96032 +enum fman_rtc_alarm_polarity {
96033 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
96034 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
96035 +};
96036 +
96037 +/**************************************************************************//**
96038 + @Description FM RTC Trigger Polarity Options.
96039 +*//***************************************************************************/
96040 +enum fman_rtc_trigger_polarity {
96041 + E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
96042 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
96043 +};
96044 +
96045 +/**************************************************************************//**
96046 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
96047 +*//***************************************************************************/
96048 +enum fman_src_clock {
96049 + E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer
96050 + reference clock */
96051 + E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
96052 + E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
96053 +};
96054 +
96055 +/* RTC default values */
96056 +#define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM
96057 +#define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE
96058 +#define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE
96059 +#define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH
96060 +#define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE
96061 +#define DEFAULT_PULSE_REALIGN FALSE
96062 +
96063 +#define FMAN_RTC_MAX_NUM_OF_ALARMS 3
96064 +#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4
96065 +#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3
96066 +
96067 +/**************************************************************************//**
96068 + @Description FM RTC timer alarm
96069 +*//***************************************************************************/
96070 +struct t_tmr_alarm{
96071 + uint32_t tmr_alarm_h; /**< */
96072 + uint32_t tmr_alarm_l; /**< */
96073 +};
96074 +
96075 +/**************************************************************************//**
96076 + @Description FM RTC timer Ex trigger
96077 +*//***************************************************************************/
96078 +struct t_tmr_ext_trigger{
96079 + uint32_t tmr_etts_h; /**< */
96080 + uint32_t tmr_etts_l; /**< */
96081 +};
96082 +
96083 +struct rtc_regs {
96084 + uint32_t tmr_id; /* 0x000 Module ID register */
96085 + uint32_t tmr_id2; /* 0x004 Controller ID register */
96086 + uint32_t reserved0008[30];
96087 + uint32_t tmr_ctrl; /* 0x0080 timer control register */
96088 + uint32_t tmr_tevent; /* 0x0084 timer event register */
96089 + uint32_t tmr_temask; /* 0x0088 timer event mask register */
96090 + uint32_t reserved008c[3];
96091 + uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */
96092 + uint32_t tmr_cnt_l; /* 0x009c timer counter low register */
96093 + uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */
96094 + uint32_t tmr_acc; /* 0x00a4 timer accumulator register */
96095 + uint32_t tmr_prsc; /* 0x00a8 timer prescale */
96096 + uint32_t reserved00ac;
96097 + uint32_t tmr_off_h; /* 0x00b0 timer offset high */
96098 + uint32_t tmr_off_l; /* 0x00b4 timer offset low */
96099 + struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer
96100 + alarm */
96101 + uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer
96102 + fixed period interval */
96103 + struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
96104 + /* 0x00e0 time stamp general purpose external */
96105 + uint32_t reserved00f0[4];
96106 +};
96107 +
96108 +struct rtc_cfg {
96109 + enum fman_src_clock src_clk;
96110 + uint32_t ext_src_clk_freq;
96111 + uint32_t rtc_freq_hz;
96112 + bool timer_slave_mode;
96113 + bool invert_input_clk_phase;
96114 + bool invert_output_clk_phase;
96115 + uint32_t events_mask;
96116 + bool bypass; /**< Indicates if frequency compensation
96117 + is bypassed */
96118 + bool pulse_realign;
96119 + enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS];
96120 + enum fman_rtc_trigger_polarity trigger_polarity
96121 + [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
96122 +};
96123 +
96124 +/**
96125 + * fman_rtc_defconfig() - Get default RTC configuration
96126 + * @cfg: pointer to configuration structure.
96127 + *
96128 + * Call this function to obtain a default set of configuration values for
96129 + * initializing RTC. The user can overwrite any of the values before calling
96130 + * fman_rtc_init(), if specific configuration needs to be applied.
96131 + */
96132 +void fman_rtc_defconfig(struct rtc_cfg *cfg);
96133 +
96134 +/**
96135 + * fman_rtc_get_events() - Get the events
96136 + * @regs: Pointer to RTC register block
96137 + *
96138 + * Returns: The events
96139 + */
96140 +uint32_t fman_rtc_get_events(struct rtc_regs *regs);
96141 +
96142 +/**
96143 + * fman_rtc_get_interrupt_mask() - Get the events mask
96144 + * @regs: Pointer to RTC register block
96145 + *
96146 + * Returns: The events mask
96147 + */
96148 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs);
96149 +
96150 +
96151 +/**
96152 + * fman_rtc_set_interrupt_mask() - Set the events mask
96153 + * @regs: Pointer to RTC register block
96154 + * @mask: The mask to set
96155 + */
96156 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask);
96157 +
96158 +/**
96159 + * fman_rtc_get_event() - Check if specific events occurred
96160 + * @regs: Pointer to RTC register block
96161 + * @ev_mask: a mask of the events to check
96162 + *
96163 + * Returns: 0 if the events did not occur. Non zero if one of the events occurred
96164 + */
96165 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask);
96166 +
96167 +/**
96168 + * fman_rtc_check_and_clear_event() - Clear events which are on
96169 + * @regs: Pointer to RTC register block
96170 + *
96171 + * Returns: A mask of the events which were cleared
96172 + */
96173 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs);
96174 +
96175 +/**
96176 + * fman_rtc_ack_event() - Clear events
96177 + * @regs: Pointer to RTC register block
96178 + * @events: The events to disable
96179 + */
96180 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events);
96181 +
96182 +/**
96183 + * fman_rtc_enable_interupt() - Enable events interrupts
96184 + * @regs: Pointer to RTC register block
96185 + * @mask: The events to disable
96186 + */
96187 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask);
96188 +
96189 +/**
96190 + * fman_rtc_disable_interupt() - Disable events interrupts
96191 + * @regs: Pointer to RTC register block
96192 + * @mask: The events to disable
96193 + */
96194 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask);
96195 +
96196 +/**
96197 + * fman_rtc_get_timer_ctrl() - Get the control register
96198 + * @regs: Pointer to RTC register block
96199 + *
96200 + * Returns: The control register value
96201 + */
96202 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs);
96203 +
96204 +/**
96205 + * fman_rtc_set_timer_ctrl() - Set timer control register
96206 + * @regs: Pointer to RTC register block
96207 + * @val: The value to set
96208 + */
96209 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val);
96210 +
96211 +/**
96212 + * fman_rtc_get_frequency_compensation() - Get the frequency compensation
96213 + * @regs: Pointer to RTC register block
96214 + *
96215 + * Returns: The timer counter
96216 + */
96217 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs);
96218 +
96219 +/**
96220 + * fman_rtc_set_frequency_compensation() - Set frequency compensation
96221 + * @regs: Pointer to RTC register block
96222 + * @val: The value to set
96223 + */
96224 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val);
96225 +
96226 +/**
96227 + * fman_rtc_get_trigger_stamp() - Get a trigger stamp
96228 + * @regs: Pointer to RTC register block
96229 + * @id: The id of the trigger stamp
96230 + *
96231 + * Returns: The time stamp
96232 + */
96233 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id);
96234 +
96235 +/**
96236 + * fman_rtc_set_timer_alarm_l() - Set timer alarm low register
96237 + * @regs: Pointer to RTC register block
96238 + * @index: The index of alarm to set
96239 + * @val: The value to set
96240 + */
96241 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index,
96242 + uint32_t val);
96243 +
96244 +/**
96245 + * fman_rtc_set_timer_alarm() - Set timer alarm
96246 + * @regs: Pointer to RTC register block
96247 + * @index: The index of alarm to set
96248 + * @val: The value to set
96249 + */
96250 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val);
96251 +
96252 +/**
96253 + * fman_rtc_set_timer_fiper() - Set timer fiper
96254 + * @regs: Pointer to RTC register block
96255 + * @index: The index of fiper to set
96256 + * @val: The value to set
96257 + */
96258 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val);
96259 +
96260 +/**
96261 + * fman_rtc_set_timer_offset() - Set timer offset
96262 + * @regs: Pointer to RTC register block
96263 + * @val: The value to set
96264 + */
96265 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val);
96266 +
96267 +/**
96268 + * fman_rtc_get_timer() - Get the timer counter
96269 + * @regs: Pointer to RTC register block
96270 + *
96271 + * Returns: The timer counter
96272 + */
96273 +static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs)
96274 +{
96275 + uint64_t time;
96276 + /* TMR_CNT_L must be read first to get an accurate value */
96277 + time = (uint64_t)ioread32be(&regs->tmr_cnt_l);
96278 + time |= ((uint64_t)ioread32be(&regs->tmr_cnt_h) << 32);
96279 +
96280 + return time;
96281 +}
96282 +
96283 +/**
96284 + * fman_rtc_set_timer() - Set timer counter
96285 + * @regs: Pointer to RTC register block
96286 + * @val: The value to set
96287 + */
96288 +static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val)
96289 +{
96290 + iowrite32be((uint32_t)val, &regs->tmr_cnt_l);
96291 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_cnt_h);
96292 +}
96293 +
96294 +/**
96295 + * fman_rtc_timers_soft_reset() - Soft reset
96296 + * @regs: Pointer to RTC register block
96297 + *
96298 + * Resets all the timer registers and state machines for the 1588 IP and
96299 + * the attached client 1588
96300 + */
96301 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs);
96302 +
96303 +/**
96304 + * fman_rtc_clear_external_trigger() - Clear an external trigger
96305 + * @regs: Pointer to RTC register block
96306 + * @id: The id of the trigger to clear
96307 + */
96308 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id);
96309 +
96310 +/**
96311 + * fman_rtc_clear_periodic_pulse() - Clear periodic pulse
96312 + * @regs: Pointer to RTC register block
96313 + * @id: The id of the fiper to clear
96314 + */
96315 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id);
96316 +
96317 +/**
96318 + * fman_rtc_enable() - Enable RTC hardware block
96319 + * @regs: Pointer to RTC register block
96320 + */
96321 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock);
96322 +
96323 +/**
96324 + * fman_rtc_is_enabled() - Is RTC hardware block enabled
96325 + * @regs: Pointer to RTC register block
96326 + *
96327 + * Return: TRUE if enabled
96328 + */
96329 +bool fman_rtc_is_enabled(struct rtc_regs *regs);
96330 +
96331 +/**
96332 + * fman_rtc_disable() - Disable RTC hardware block
96333 + * @regs: Pointer to RTC register block
96334 + */
96335 +void fman_rtc_disable(struct rtc_regs *regs);
96336 +
96337 +/**
96338 + * fman_rtc_init() - Init RTC hardware block
96339 + * @cfg: RTC configuration data
96340 + * @regs: Pointer to RTC register block
96341 + * @num_alarms: Number of alarms in RTC
96342 + * @num_fipers: Number of fipers in RTC
96343 + * @num_ext_triggers: Number of external triggers in RTC
96344 + * @freq_compensation: Frequency compensation
96345 + * @output_clock_divisor: Output clock divisor
96346 + *
96347 + * This function initializes RTC and applies basic configuration.
96348 + */
96349 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
96350 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
96351 + uint32_t freq_compensation, uint32_t output_clock_divisor);
96352 +
96353 +/**
96354 + * fman_rtc_set_alarm() - Set an alarm
96355 + * @regs: Pointer to RTC register block
96356 + * @id: id of alarm
96357 + * @val: value to write
96358 + * @enable: should interrupt be enabled
96359 + */
96360 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable);
96361 +
96362 +/**
96363 + * fman_rtc_set_periodic_pulse() - Set an alarm
96364 + * @regs: Pointer to RTC register block
96365 + * @id: id of fiper
96366 + * @val: value to write
96367 + * @enable: should interrupt be enabled
96368 + */
96369 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
96370 + bool enable);
96371 +
96372 +/**
96373 + * fman_rtc_set_ext_trigger() - Set an external trigger
96374 + * @regs: Pointer to RTC register block
96375 + * @id: id of trigger
96376 + * @enable: should interrupt be enabled
96377 + * @use_pulse_as_input: use the pulse as input
96378 + */
96379 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
96380 + bool use_pulse_as_input);
96381 +
96382 +struct fm_rtc_alarm_params {
96383 + uint8_t alarm_id; /**< 0 or 1 */
96384 + uint64_t alarm_time; /**< In nanoseconds, the time when the
96385 + alarm should go off - must be a
96386 + multiple of the RTC period */
96387 + void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will
96388 + be called when RTC reaches alarmTime */
96389 + bool clear_on_expiration; /**< TRUE to turn off the alarm once
96390 + expired.*/
96391 +};
96392 +
96393 +struct fm_rtc_periodic_pulse_params {
96394 + uint8_t periodic_pulse_id; /**< 0 or 1 */
96395 + uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple
96396 + of the RTC period */
96397 + void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This
96398 + routine will be called every
96399 + periodicPulsePeriod. */
96400 +};
96401 +
96402 +#endif /* __FSL_FMAN_RTC_H */
96403 --- /dev/null
96404 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
96405 @@ -0,0 +1,138 @@
96406 +/*
96407 + * Copyright 2013 Freescale Semiconductor Inc.
96408 + *
96409 + * Redistribution and use in source and binary forms, with or without
96410 + * modification, are permitted provided that the following conditions are met:
96411 + * * Redistributions of source code must retain the above copyright
96412 + * notice, this list of conditions and the following disclaimer.
96413 + * * Redistributions in binary form must reproduce the above copyright
96414 + * notice, this list of conditions and the following disclaimer in the
96415 + * documentation and/or other materials provided with the distribution.
96416 + * * Neither the name of Freescale Semiconductor nor the
96417 + * names of its contributors may be used to endorse or promote products
96418 + * derived from this software without specific prior written permission.
96419 + *
96420 + *
96421 + * ALTERNATIVELY, this software may be distributed under the terms of the
96422 + * GNU General Public License ("GPL") as published by the Free Software
96423 + * Foundation, either version 2 of that License or (at your option) any
96424 + * later version.
96425 + *
96426 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96427 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96428 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96429 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96430 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96431 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96432 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96433 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96434 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96435 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96436 + */
96437 +
96438 +#ifndef __FSL_FMAN_SP_H
96439 +#define __FSL_FMAN_SP_H
96440 +
96441 +#include "common/general.h"
96442 +#include "fsl_fman.h"
96443 +
96444 +
96445 +struct fm_pcd_storage_profile_regs{
96446 + uint32_t fm_sp_ebmpi[8];
96447 + /*offset 0 - 0xc*/
96448 + /**< Buffer Manager pool Information */
96449 +
96450 + uint32_t fm_sp_acnt; /*offset 0x20*/
96451 + uint32_t fm_sp_ebm; /*offset 0x24*/
96452 + uint32_t fm_sp_da; /*offset 0x28*/
96453 + uint32_t fm_sp_icp; /*offset 0x2c*/
96454 + uint32_t fm_sp_mpd; /*offset 0x30*/
96455 + uint32_t res1[2]; /*offset 0x34 - 0x38*/
96456 + uint32_t fm_sp_spliodn; /*offset 0x3c*/
96457 +};
96458 +
96459 +/**************************************************************************//**
96460 + @Description structure for defining internal context copying
96461 +*//***************************************************************************/
96462 +struct fman_sp_int_context_data_copy{
96463 + uint16_t ext_buf_offset; /**< Offset in External buffer to which
96464 + internal context is copied to (Rx)
96465 + or taken from (Tx, Op). */
96466 + uint8_t int_context_offset; /**< Offset within internal context to copy
96467 + from (Rx) or to copy to (Tx, Op).*/
96468 + uint16_t size; /**< Internal offset size to be copied */
96469 +};
96470 +
96471 +/**************************************************************************//**
96472 + @Description struct for defining external buffer margins
96473 +*//***************************************************************************/
96474 +struct fman_sp_buf_margins{
96475 + uint16_t start_margins; /**< Number of bytes to be left at the
96476 + beginning of the external buffer (must be
96477 + divisible by 16) */
96478 + uint16_t end_margins; /**< number of bytes to be left at the end of
96479 + the external buffer(must be divisible by 16)*/
96480 +};
96481 +
96482 +struct fm_storage_profile_params {
96483 + struct fman_ext_pools fm_ext_pools;
96484 + struct fman_backup_bm_pools backup_pools;
96485 + struct fman_sp_int_context_data_copy *int_context;
96486 + struct fman_sp_buf_margins *buf_margins;
96487 + enum fman_dma_swap_option dma_swap_data;
96488 + enum fman_dma_cache_option int_context_cache_attr;
96489 + enum fman_dma_cache_option header_cache_attr;
96490 + enum fman_dma_cache_option scatter_gather_cache_attr;
96491 + bool dma_write_optimize;
96492 + uint16_t liodn_offset;
96493 + bool no_scather_gather;
96494 + struct fman_buf_pool_depletion buf_pool_depletion;
96495 +};
96496 +
96497 +/**************************************************************************//**
96498 + @Description Registers bit fields
96499 +*//***************************************************************************/
96500 +#define FMAN_SP_EXT_BUF_POOL_EN_COUNTER 0x40000000
96501 +#define FMAN_SP_EXT_BUF_POOL_VALID 0x80000000
96502 +#define FMAN_SP_EXT_BUF_POOL_BACKUP 0x20000000
96503 +#define FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE 0x00100000
96504 +#define FMAN_SP_SG_DISABLE 0x80000000
96505 +
96506 +/* shifts */
96507 +#define FMAN_SP_EXT_BUF_POOL_ID_SHIFT 16
96508 +#define FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT 16
96509 +#define FMAN_SP_EXT_BUF_MARG_START_SHIFT 16
96510 +#define FMAN_SP_EXT_BUF_MARG_END_SHIFT 0
96511 +#define FMAN_SP_DMA_ATTR_SWP_SHIFT 30
96512 +#define FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT 28
96513 +#define FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT 26
96514 +#define FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT 24
96515 +#define FMAN_SP_IC_TO_EXT_SHIFT 16
96516 +#define FMAN_SP_IC_FROM_INT_SHIFT 8
96517 +#define FMAN_SP_IC_SIZE_SHIFT 0
96518 +
96519 +/**************************************************************************//**
96520 + @Description defaults
96521 +*//***************************************************************************/
96522 +#define DEFAULT_FMAN_SP_DMA_SWAP_DATA FMAN_DMA_NO_SWP
96523 +#define DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR FMAN_DMA_NO_STASH
96524 +#define DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR FMAN_DMA_NO_STASH
96525 +#define DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR FMAN_DMA_NO_STASH
96526 +#define DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE TRUE
96527 +#define DEFAULT_FMAN_SP_NO_SCATTER_GATHER FALSE
96528 +
96529 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg);
96530 +
96531 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
96532 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
96533 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
96534 + int max_num_of_pfc_priorities);
96535 +
96536 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
96537 + uint16_t index);
96538 +
96539 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
96540 + uint16_t index, uint32_t value);
96541 +
96542 +
96543 +#endif /* __FSL_FMAN_SP_H */
96544 --- /dev/null
96545 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
96546 @@ -0,0 +1,479 @@
96547 +/*
96548 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96549 + *
96550 + * Redistribution and use in source and binary forms, with or without
96551 + * modification, are permitted provided that the following conditions are met:
96552 + * * Redistributions of source code must retain the above copyright
96553 + * notice, this list of conditions and the following disclaimer.
96554 + * * Redistributions in binary form must reproduce the above copyright
96555 + * notice, this list of conditions and the following disclaimer in the
96556 + * documentation and/or other materials provided with the distribution.
96557 + * * Neither the name of Freescale Semiconductor nor the
96558 + * names of its contributors may be used to endorse or promote products
96559 + * derived from this software without specific prior written permission.
96560 + *
96561 + *
96562 + * ALTERNATIVELY, this software may be distributed under the terms of the
96563 + * GNU General Public License ("GPL") as published by the Free Software
96564 + * Foundation, either version 2 of that License or (at your option) any
96565 + * later version.
96566 + *
96567 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96568 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96569 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96570 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96571 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96572 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96573 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96574 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96575 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96576 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96577 + */
96578 +
96579 +#ifndef __FSL_FMAN_TGEC_H
96580 +#define __FSL_FMAN_TGEC_H
96581 +
96582 +#include "common/general.h"
96583 +#include "fsl_enet.h"
96584 +
96585 +
96586 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
96587 +#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
96588 +
96589 +enum tgec_counters {
96590 + E_TGEC_COUNTER_R64,
96591 + E_TGEC_COUNTER_R127,
96592 + E_TGEC_COUNTER_R255,
96593 + E_TGEC_COUNTER_R511,
96594 + E_TGEC_COUNTER_R1023,
96595 + E_TGEC_COUNTER_R1518,
96596 + E_TGEC_COUNTER_R1519X,
96597 + E_TGEC_COUNTER_TRFRG,
96598 + E_TGEC_COUNTER_TRJBR,
96599 + E_TGEC_COUNTER_RDRP,
96600 + E_TGEC_COUNTER_RALN,
96601 + E_TGEC_COUNTER_TRUND,
96602 + E_TGEC_COUNTER_TROVR,
96603 + E_TGEC_COUNTER_RXPF,
96604 + E_TGEC_COUNTER_TXPF,
96605 + E_TGEC_COUNTER_ROCT,
96606 + E_TGEC_COUNTER_RMCA,
96607 + E_TGEC_COUNTER_RBCA,
96608 + E_TGEC_COUNTER_RPKT,
96609 + E_TGEC_COUNTER_RUCA,
96610 + E_TGEC_COUNTER_RERR,
96611 + E_TGEC_COUNTER_TOCT,
96612 + E_TGEC_COUNTER_TMCA,
96613 + E_TGEC_COUNTER_TBCA,
96614 + E_TGEC_COUNTER_TUCA,
96615 + E_TGEC_COUNTER_TERR
96616 +};
96617 +
96618 +/* Command and Configuration Register (COMMAND_CONFIG) */
96619 +#define CMD_CFG_EN_TIMESTAMP 0x00100000
96620 +#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000
96621 +#define CMD_CFG_NO_LEN_CHK 0x00020000
96622 +#define CMD_CFG_SEND_IDLE 0x00010000
96623 +#define CMD_CFG_RX_ER_DISC 0x00004000
96624 +#define CMD_CFG_CMD_FRM_EN 0x00002000
96625 +#define CMD_CFG_STAT_CLR 0x00001000
96626 +#define CMD_CFG_LOOPBACK_EN 0x00000400
96627 +#define CMD_CFG_TX_ADDR_INS 0x00000200
96628 +#define CMD_CFG_PAUSE_IGNORE 0x00000100
96629 +#define CMD_CFG_PAUSE_FWD 0x00000080
96630 +#define CMD_CFG_PROMIS_EN 0x00000010
96631 +#define CMD_CFG_WAN_MODE 0x00000008
96632 +#define CMD_CFG_RX_EN 0x00000002
96633 +#define CMD_CFG_TX_EN 0x00000001
96634 +
96635 +/* Interrupt Mask Register (IMASK) */
96636 +#define TGEC_IMASK_MDIO_SCAN_EVENT 0x00010000
96637 +#define TGEC_IMASK_MDIO_CMD_CMPL 0x00008000
96638 +#define TGEC_IMASK_REM_FAULT 0x00004000
96639 +#define TGEC_IMASK_LOC_FAULT 0x00002000
96640 +#define TGEC_IMASK_TX_ECC_ER 0x00001000
96641 +#define TGEC_IMASK_TX_FIFO_UNFL 0x00000800
96642 +#define TGEC_IMASK_TX_FIFO_OVFL 0x00000400
96643 +#define TGEC_IMASK_TX_ER 0x00000200
96644 +#define TGEC_IMASK_RX_FIFO_OVFL 0x00000100
96645 +#define TGEC_IMASK_RX_ECC_ER 0x00000080
96646 +#define TGEC_IMASK_RX_JAB_FRM 0x00000040
96647 +#define TGEC_IMASK_RX_OVRSZ_FRM 0x00000020
96648 +#define TGEC_IMASK_RX_RUNT_FRM 0x00000010
96649 +#define TGEC_IMASK_RX_FRAG_FRM 0x00000008
96650 +#define TGEC_IMASK_RX_LEN_ER 0x00000004
96651 +#define TGEC_IMASK_RX_CRC_ER 0x00000002
96652 +#define TGEC_IMASK_RX_ALIGN_ER 0x00000001
96653 +
96654 +#define TGEC_EVENTS_MASK \
96655 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
96656 + TGEC_IMASK_MDIO_CMD_CMPL | \
96657 + TGEC_IMASK_REM_FAULT | \
96658 + TGEC_IMASK_LOC_FAULT | \
96659 + TGEC_IMASK_TX_ECC_ER | \
96660 + TGEC_IMASK_TX_FIFO_UNFL | \
96661 + TGEC_IMASK_TX_FIFO_OVFL | \
96662 + TGEC_IMASK_TX_ER | \
96663 + TGEC_IMASK_RX_FIFO_OVFL | \
96664 + TGEC_IMASK_RX_ECC_ER | \
96665 + TGEC_IMASK_RX_JAB_FRM | \
96666 + TGEC_IMASK_RX_OVRSZ_FRM | \
96667 + TGEC_IMASK_RX_RUNT_FRM | \
96668 + TGEC_IMASK_RX_FRAG_FRM | \
96669 + TGEC_IMASK_RX_LEN_ER | \
96670 + TGEC_IMASK_RX_CRC_ER | \
96671 + TGEC_IMASK_RX_ALIGN_ER))
96672 +
96673 +/* Hashtable Control Register (HASHTABLE_CTRL) */
96674 +#define TGEC_HASH_MCAST_SHIFT 23
96675 +#define TGEC_HASH_MCAST_EN 0x00000200
96676 +#define TGEC_HASH_ADR_MSK 0x000001ff
96677 +
96678 +#define DEFAULT_WAN_MODE_ENABLE FALSE
96679 +#define DEFAULT_PROMISCUOUS_MODE_ENABLE FALSE
96680 +#define DEFAULT_PAUSE_FORWARD_ENABLE FALSE
96681 +#define DEFAULT_PAUSE_IGNORE FALSE
96682 +#define DEFAULT_TX_ADDR_INS_ENABLE FALSE
96683 +#define DEFAULT_LOOPBACK_ENABLE FALSE
96684 +#define DEFAULT_CMD_FRAME_ENABLE FALSE
96685 +#define DEFAULT_RX_ERROR_DISCARD FALSE
96686 +#define DEFAULT_SEND_IDLE_ENABLE FALSE
96687 +#define DEFAULT_NO_LENGTH_CHECK_ENABLE TRUE
96688 +#define DEFAULT_LGTH_CHECK_NOSTDR FALSE
96689 +#define DEFAULT_TIME_STAMP_ENABLE FALSE
96690 +#define DEFAULT_TX_IPG_LENGTH 12
96691 +#define DEFAULT_MAX_FRAME_LENGTH 0x600
96692 +#define DEFAULT_PAUSE_QUANT 0xf000
96693 +
96694 +/*
96695 + * 10G memory map
96696 + */
96697 +struct tgec_regs {
96698 + uint32_t tgec_id; /* 0x000 Controller ID */
96699 + uint32_t reserved001[1]; /* 0x004 */
96700 + uint32_t command_config; /* 0x008 Control and configuration */
96701 + uint32_t mac_addr_0; /* 0x00c Lower 32 bits of the MAC adr */
96702 + uint32_t mac_addr_1; /* 0x010 Upper 16 bits of the MAC adr */
96703 + uint32_t maxfrm; /* 0x014 Maximum frame length */
96704 + uint32_t pause_quant; /* 0x018 Pause quanta */
96705 + uint32_t rx_fifo_sections; /* 0x01c */
96706 + uint32_t tx_fifo_sections; /* 0x020 */
96707 + uint32_t rx_fifo_almost_f_e; /* 0x024 */
96708 + uint32_t tx_fifo_almost_f_e; /* 0x028 */
96709 + uint32_t hashtable_ctrl; /* 0x02c Hash table control*/
96710 + uint32_t mdio_cfg_status; /* 0x030 */
96711 + uint32_t mdio_command; /* 0x034 */
96712 + uint32_t mdio_data; /* 0x038 */
96713 + uint32_t mdio_regaddr; /* 0x03c */
96714 + uint32_t status; /* 0x040 */
96715 + uint32_t tx_ipg_len; /* 0x044 Transmitter inter-packet-gap */
96716 + uint32_t mac_addr_2; /* 0x048 Lower 32 bits of 2nd MAC adr */
96717 + uint32_t mac_addr_3; /* 0x04c Upper 16 bits of 2nd MAC adr */
96718 + uint32_t rx_fifo_ptr_rd; /* 0x050 */
96719 + uint32_t rx_fifo_ptr_wr; /* 0x054 */
96720 + uint32_t tx_fifo_ptr_rd; /* 0x058 */
96721 + uint32_t tx_fifo_ptr_wr; /* 0x05c */
96722 + uint32_t imask; /* 0x060 Interrupt mask */
96723 + uint32_t ievent; /* 0x064 Interrupt event */
96724 + uint32_t udp_port; /* 0x068 Defines a UDP Port number */
96725 + uint32_t type_1588v2; /* 0x06c Type field for 1588v2 */
96726 + uint32_t reserved070[4]; /* 0x070 */
96727 + /*10Ge Statistics Counter */
96728 + uint32_t tfrm_u; /* 80 aFramesTransmittedOK */
96729 + uint32_t tfrm_l; /* 84 aFramesTransmittedOK */
96730 + uint32_t rfrm_u; /* 88 aFramesReceivedOK */
96731 + uint32_t rfrm_l; /* 8c aFramesReceivedOK */
96732 + uint32_t rfcs_u; /* 90 aFrameCheckSequenceErrors */
96733 + uint32_t rfcs_l; /* 94 aFrameCheckSequenceErrors */
96734 + uint32_t raln_u; /* 98 aAlignmentErrors */
96735 + uint32_t raln_l; /* 9c aAlignmentErrors */
96736 + uint32_t txpf_u; /* A0 aPAUSEMACCtrlFramesTransmitted */
96737 + uint32_t txpf_l; /* A4 aPAUSEMACCtrlFramesTransmitted */
96738 + uint32_t rxpf_u; /* A8 aPAUSEMACCtrlFramesReceived */
96739 + uint32_t rxpf_l; /* Ac aPAUSEMACCtrlFramesReceived */
96740 + uint32_t rlong_u; /* B0 aFrameTooLongErrors */
96741 + uint32_t rlong_l; /* B4 aFrameTooLongErrors */
96742 + uint32_t rflr_u; /* B8 aInRangeLengthErrors */
96743 + uint32_t rflr_l; /* Bc aInRangeLengthErrors */
96744 + uint32_t tvlan_u; /* C0 VLANTransmittedOK */
96745 + uint32_t tvlan_l; /* C4 VLANTransmittedOK */
96746 + uint32_t rvlan_u; /* C8 VLANReceivedOK */
96747 + uint32_t rvlan_l; /* Cc VLANReceivedOK */
96748 + uint32_t toct_u; /* D0 ifOutOctets */
96749 + uint32_t toct_l; /* D4 ifOutOctets */
96750 + uint32_t roct_u; /* D8 ifInOctets */
96751 + uint32_t roct_l; /* Dc ifInOctets */
96752 + uint32_t ruca_u; /* E0 ifInUcastPkts */
96753 + uint32_t ruca_l; /* E4 ifInUcastPkts */
96754 + uint32_t rmca_u; /* E8 ifInMulticastPkts */
96755 + uint32_t rmca_l; /* Ec ifInMulticastPkts */
96756 + uint32_t rbca_u; /* F0 ifInBroadcastPkts */
96757 + uint32_t rbca_l; /* F4 ifInBroadcastPkts */
96758 + uint32_t terr_u; /* F8 ifOutErrors */
96759 + uint32_t terr_l; /* Fc ifOutErrors */
96760 + uint32_t reserved100[2]; /* 100-108*/
96761 + uint32_t tuca_u; /* 108 ifOutUcastPkts */
96762 + uint32_t tuca_l; /* 10c ifOutUcastPkts */
96763 + uint32_t tmca_u; /* 110 ifOutMulticastPkts */
96764 + uint32_t tmca_l; /* 114 ifOutMulticastPkts */
96765 + uint32_t tbca_u; /* 118 ifOutBroadcastPkts */
96766 + uint32_t tbca_l; /* 11c ifOutBroadcastPkts */
96767 + uint32_t rdrp_u; /* 120 etherStatsDropEvents */
96768 + uint32_t rdrp_l; /* 124 etherStatsDropEvents */
96769 + uint32_t reoct_u; /* 128 etherStatsOctets */
96770 + uint32_t reoct_l; /* 12c etherStatsOctets */
96771 + uint32_t rpkt_u; /* 130 etherStatsPkts */
96772 + uint32_t rpkt_l; /* 134 etherStatsPkts */
96773 + uint32_t trund_u; /* 138 etherStatsUndersizePkts */
96774 + uint32_t trund_l; /* 13c etherStatsUndersizePkts */
96775 + uint32_t r64_u; /* 140 etherStatsPkts64Octets */
96776 + uint32_t r64_l; /* 144 etherStatsPkts64Octets */
96777 + uint32_t r127_u; /* 148 etherStatsPkts65to127Octets */
96778 + uint32_t r127_l; /* 14c etherStatsPkts65to127Octets */
96779 + uint32_t r255_u; /* 150 etherStatsPkts128to255Octets */
96780 + uint32_t r255_l; /* 154 etherStatsPkts128to255Octets */
96781 + uint32_t r511_u; /* 158 etherStatsPkts256to511Octets */
96782 + uint32_t r511_l; /* 15c etherStatsPkts256to511Octets */
96783 + uint32_t r1023_u; /* 160 etherStatsPkts512to1023Octets */
96784 + uint32_t r1023_l; /* 164 etherStatsPkts512to1023Octets */
96785 + uint32_t r1518_u; /* 168 etherStatsPkts1024to1518Octets */
96786 + uint32_t r1518_l; /* 16c etherStatsPkts1024to1518Octets */
96787 + uint32_t r1519x_u; /* 170 etherStatsPkts1519toX */
96788 + uint32_t r1519x_l; /* 174 etherStatsPkts1519toX */
96789 + uint32_t trovr_u; /* 178 etherStatsOversizePkts */
96790 + uint32_t trovr_l; /* 17c etherStatsOversizePkts */
96791 + uint32_t trjbr_u; /* 180 etherStatsJabbers */
96792 + uint32_t trjbr_l; /* 184 etherStatsJabbers */
96793 + uint32_t trfrg_u; /* 188 etherStatsFragments */
96794 + uint32_t trfrg_l; /* 18C etherStatsFragments */
96795 + uint32_t rerr_u; /* 190 ifInErrors */
96796 + uint32_t rerr_l; /* 194 ifInErrors */
96797 +};
96798 +
96799 +/**
96800 + * struct tgec_cfg - TGEC configuration
96801 + *
96802 + * @rx_error_discard: Receive Erroneous Frame Discard Enable. When set to 1
96803 + * any frame received with an error is discarded in the
96804 + * Core and not forwarded to the Client interface.
96805 + * When set to 0 (Reset value), erroneous Frames are
96806 + * forwarded to the Client interface with ff_rx_err
96807 + * asserted.
96808 + * @pause_ignore: Ignore Pause Frame Quanta. If set to 1 received pause
96809 + * frames are ignored by the MAC. When set to 0
96810 + * (Reset value) the transmit process is stopped for the
96811 + * amount of time specified in the pause quanta received
96812 + * within a pause frame.
96813 + * @pause_forward_enable:
96814 + * Terminate / Forward Pause Frames. If set to 1 pause
96815 + * frames are forwarded to the user application. When set
96816 + * to 0 (Reset value) pause frames are terminated and
96817 + * discarded within the MAC.
96818 + * @no_length_check_enable:
96819 + * Payload Length Check Disable. When set to 0
96820 + * (Reset value), the Core checks the frame's payload
96821 + * length with the Frame Length/Type field, when set to 1
96822 + * the payload length check is disabled.
96823 + * @cmd_frame_enable: Enables reception of all command frames. When set to 1
96824 + * all Command Frames are accepted, when set to 0
96825 + * (Reset Value) only Pause Frames are accepted and all
96826 + * other Command Frames are rejected.
96827 + * @send_idle_enable: Force Idle Generation. When set to 1, the MAC
96828 + * permanently sends XGMII Idle sequences even when faults
96829 + * are received.
96830 + * @wan_mode_enable: WAN Mode Enable. Sets WAN mode (1) or LAN mode
96831 + * (0, default) of operation.
96832 + * @promiscuous_mode_enable:
96833 + * Enables MAC promiscuous operation. When set to 1, all
96834 + * frames are received without any MAC address filtering,
96835 + * when set to 0 (Reset value) Unicast Frames with a
96836 + * destination address not matching the Core MAC Address
96837 + * (MAC Address programmed in Registers MAC_ADDR_0 and
96838 + * MAC_ADDR_1 or the MAC address programmed in Registers
96839 + * MAC_ADDR_2 and MAC_ADDR_3) are rejected.
96840 + * @tx_addr_ins_enable: Set Source MAC Address on Transmit. If set to 1 the
96841 + * MAC overwrites the source MAC address received from the
96842 + * Client Interface with one of the MAC addresses. If set
96843 + * to 0 (Reset value), the source MAC address from the
96844 + * Client Interface is transmitted unmodified to the line.
96845 + * @loopback_enable: PHY Interface Loopback. When set to 1, the signal
96846 + * loop_ena is set to '1', when set to 0 (Reset value)
96847 + * the signal loop_ena is set to 0.
96848 + * @lgth_check_nostdr: The Core interprets the Length/Type field differently
96849 + * depending on the value of this Bit
96850 + * @time_stamp_enable: This bit selects between enabling and disabling the
96851 + * IEEE 1588 functionality. 1: IEEE 1588 is enabled
96852 + * 0: IEEE 1588 is disabled
96853 + * @max_frame_length: Maximum supported received frame length.
96854 + * The 10GEC MAC supports reception of any frame size up
96855 + * to 16,352 bytes (0x3FE0). Typical settings are
96856 + * 0x05EE (1,518 bytes) for standard frames.
96857 + * Default setting is 0x0600 (1,536 bytes).
96858 + * Received frames that exceed this stated maximum
96859 + * are truncated.
96860 + * @pause_quant: Pause quanta value used with transmitted pause frames.
96861 + * Each quanta represents a 512 bit-times.
96862 + * @tx_ipg_length: Transmit Inter-Packet-Gap (IPG) value. A 6-bit value:
96863 + * Depending on LAN or WAN mode of operation the value has
96864 + * the following meaning: - LAN Mode: Number of octets in
96865 + * steps of 4. Valid values are 8, 12, 16, ... 100. DIC is
96866 + * fully supported (see 10.6.1 page 49) for any setting. A
96867 + * default of 12 (reset value) must be set to conform to
96868 + * IEEE802.3ae. Warning: When set to 8, PCS layers may not
96869 + * be able to perform clock rate compensation. - WAN Mode:
96870 + * Stretch factor. Valid values are 4..15. The stretch
96871 + * factor is calculated as (value+1)*8. A default of 12
96872 + * (reset value) must be set to conform to IEEE 802.3ae
96873 + * (i.e. 13*8=104). A larger value shrinks the IPG
96874 + * (increasing bandwidth).
96875 + *
96876 + * This structure contains basic TGEC configuration and must be passed to
96877 + * fman_tgec_init() function. A default set of configuration values can be
96878 + * obtained by calling fman_tgec_defconfig().
96879 + */
96880 +struct tgec_cfg {
96881 + bool rx_error_discard;
96882 + bool pause_ignore;
96883 + bool pause_forward_enable;
96884 + bool no_length_check_enable;
96885 + bool cmd_frame_enable;
96886 + bool send_idle_enable;
96887 + bool wan_mode_enable;
96888 + bool promiscuous_mode_enable;
96889 + bool tx_addr_ins_enable;
96890 + bool loopback_enable;
96891 + bool lgth_check_nostdr;
96892 + bool time_stamp_enable;
96893 + uint16_t max_frame_length;
96894 + uint16_t pause_quant;
96895 + uint32_t tx_ipg_length;
96896 + bool skip_fman11_workaround;
96897 +};
96898 +
96899 +
96900 +void fman_tgec_defconfig(struct tgec_cfg *cfg);
96901 +
96902 +/**
96903 + * fman_tgec_init() - Init tgec hardware block
96904 + * @regs: Pointer to tgec register block
96905 + * @cfg: tgec configuration data
96906 + * @exceptions_mask: initial exceptions mask
96907 + *
96908 + * This function initializes the tgec controller and applies its
96909 + * basic configuration.
96910 + *
96911 + * Returns: 0 if successful, an error code otherwise.
96912 + */
96913 +
96914 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
96915 + uint32_t exception_mask);
96916 +
96917 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
96918 +
96919 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
96920 +
96921 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs);
96922 +
96923 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *macaddr);
96924 +
96925 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val);
96926 +
96927 +/**
96928 + * fman_tgec_reset_stat() - Completely resets all TGEC HW counters
96929 + * @regs: Pointer to TGEC register block
96930 + */
96931 +void fman_tgec_reset_stat(struct tgec_regs *regs);
96932 +
96933 +/**
96934 + * fman_tgec_get_counter() - Reads TGEC HW counters
96935 + * @regs: Pointer to TGEC register block
96936 + * @reg_name: Counter name according to the appropriate enum
96937 + *
96938 + * Returns: Required counter value
96939 + */
96940 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs,
96941 + enum tgec_counters reg_name);
96942 +
96943 +/**
96944 + * fman_tgec_set_hash_table() - Sets the Hashtable Control Register
96945 + * @regs: Pointer to TGEC register block
96946 + * @value: Value to be written in Hashtable Control Register
96947 + */
96948 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value);
96949 +
96950 +/**
96951 + * fman_tgec_set_tx_pause_frames() - Sets the Pause Quanta Register
96952 + * @regs: Pointer to TGEC register block
96953 + * @pause_time: Pause quanta value used with transmitted pause frames.
96954 + * Each quanta represents a 512 bit-times
96955 + */
96956 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time);
96957 +
96958 +/**
96959 + * fman_tgec_set_rx_ignore_pause_frames() - Changes the policy WRT pause frames
96960 + * @regs: Pointer to TGEC register block
96961 + * @en: Ignore/Respond to pause frame quanta
96962 + *
96963 + * Sets the value of PAUSE_IGNORE field in the COMMAND_CONFIG Register
96964 + * 0 - MAC stops transmit process for the duration specified
96965 + * in the Pause frame quanta of a received Pause frame.
96966 + * 1 - MAC ignores received Pause frames.
96967 + */
96968 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en);
96969 +
96970 +/**
96971 + * fman_tgec_enable_1588_time_stamp() - change timestamp functionality
96972 + * @regs: Pointer to TGEC register block
96973 + * @en: enable/disable timestamp functionality
96974 + *
96975 + * Sets the value of EN_TIMESTAMP field in the COMMAND_CONFIG Register
96976 + * IEEE 1588 timestamp functionality control:
96977 + * 0 disabled, 1 enabled
96978 + */
96979 +
96980 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en);
96981 +
96982 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask);
96983 +
96984 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask);
96985 +
96986 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs);
96987 +
96988 +/**
96989 + * fman_tgec_add_addr_in_paddr() - Sets additional exact match MAC address
96990 + * @regs: Pointer to TGEC register block
96991 + * @addr_ptr: Pointer to 6-byte array containing the MAC address
96992 + *
96993 + * Sets the additional station MAC address
96994 + */
96995 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *addr_ptr);
96996 +
96997 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs);
96998 +
96999 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
97000 +
97001 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
97002 +
97003 +void fman_tgec_reset_filter_table(struct tgec_regs *regs);
97004 +
97005 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc);
97006 +
97007 +
97008 +/**
97009 + * fman_tgec_get_max_frame_len() - Returns the maximum frame length value
97010 + * @regs: Pointer to TGEC register block
97011 + */
97012 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs);
97013 +
97014 +/**
97015 + * fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007() - Initialize the
97016 + * main tgec configuration parameters
97017 + * @regs: Pointer to TGEC register block
97018 + *
97019 + * TODO
97020 + */
97021 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs
97022 + *regs);
97023 +
97024 +
97025 +#endif /* __FSL_FMAN_TGEC_H */
97026 --- /dev/null
97027 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
97028 @@ -0,0 +1,291 @@
97029 +/*
97030 + * Copyright 2012 Freescale Semiconductor Inc.
97031 + *
97032 + * Redistribution and use in source and binary forms, with or without
97033 + * modification, are permitted provided that the following conditions are met:
97034 + * * Redistributions of source code must retain the above copyright
97035 + * notice, this list of conditions and the following disclaimer.
97036 + * * Redistributions in binary form must reproduce the above copyright
97037 + * notice, this list of conditions and the following disclaimer in the
97038 + * documentation and/or other materials provided with the distribution.
97039 + * * Neither the name of Freescale Semiconductor nor the
97040 + * names of its contributors may be used to endorse or promote products
97041 + * derived from this software without specific prior written permission.
97042 + *
97043 + *
97044 + * ALTERNATIVELY, this software may be distributed under the terms of the
97045 + * GNU General Public License ("GPL") as published by the Free Software
97046 + * Foundation, either version 2 of that License or (at your option) any
97047 + * later version.
97048 + *
97049 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97050 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97051 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97052 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97053 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97054 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97055 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97056 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97057 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97058 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97059 + */
97060 +
97061 +/**
97062 +
97063 + @File dpaa_integration_ext.h
97064 +
97065 + @Description T4240 FM external definitions and structures.
97066 +*//***************************************************************************/
97067 +#ifndef __DPAA_INTEGRATION_EXT_H
97068 +#define __DPAA_INTEGRATION_EXT_H
97069 +
97070 +#include "std_ext.h"
97071 +
97072 +
97073 +#define DPAA_VERSION 11
97074 +
97075 +/**************************************************************************//**
97076 + @Description DPAA SW Portals Enumeration.
97077 +*//***************************************************************************/
97078 +typedef enum
97079 +{
97080 + e_DPAA_SWPORTAL0 = 0,
97081 + e_DPAA_SWPORTAL1,
97082 + e_DPAA_SWPORTAL2,
97083 + e_DPAA_SWPORTAL3,
97084 + e_DPAA_SWPORTAL4,
97085 + e_DPAA_SWPORTAL5,
97086 + e_DPAA_SWPORTAL6,
97087 + e_DPAA_SWPORTAL7,
97088 + e_DPAA_SWPORTAL8,
97089 + e_DPAA_SWPORTAL9,
97090 + e_DPAA_SWPORTAL10,
97091 + e_DPAA_SWPORTAL11,
97092 + e_DPAA_SWPORTAL12,
97093 + e_DPAA_SWPORTAL13,
97094 + e_DPAA_SWPORTAL14,
97095 + e_DPAA_SWPORTAL15,
97096 + e_DPAA_SWPORTAL16,
97097 + e_DPAA_SWPORTAL17,
97098 + e_DPAA_SWPORTAL18,
97099 + e_DPAA_SWPORTAL19,
97100 + e_DPAA_SWPORTAL20,
97101 + e_DPAA_SWPORTAL21,
97102 + e_DPAA_SWPORTAL22,
97103 + e_DPAA_SWPORTAL23,
97104 + e_DPAA_SWPORTAL24,
97105 + e_DPAA_SWPORTAL_DUMMY_LAST
97106 +} e_DpaaSwPortal;
97107 +
97108 +/**************************************************************************//**
97109 + @Description DPAA Direct Connect Portals Enumeration.
97110 +*//***************************************************************************/
97111 +typedef enum
97112 +{
97113 + e_DPAA_DCPORTAL0 = 0,
97114 + e_DPAA_DCPORTAL1,
97115 + e_DPAA_DCPORTAL2,
97116 + e_DPAA_DCPORTAL_DUMMY_LAST
97117 +} e_DpaaDcPortal;
97118 +
97119 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
97120 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
97121 +
97122 +/*****************************************************************************
97123 + QMan INTEGRATION-SPECIFIC DEFINITIONS
97124 +******************************************************************************/
97125 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
97126 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
97127 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
97128 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
97129 + /**< FQIDs range - 24 bits */
97130 +
97131 +/**************************************************************************//**
97132 + @Description Work Queue Channel assignments in QMan.
97133 +*//***************************************************************************/
97134 +typedef enum
97135 +{
97136 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
97137 + e_QM_FQ_CHANNEL_SWPORTAL1,
97138 + e_QM_FQ_CHANNEL_SWPORTAL2,
97139 + e_QM_FQ_CHANNEL_SWPORTAL3,
97140 + e_QM_FQ_CHANNEL_SWPORTAL4,
97141 + e_QM_FQ_CHANNEL_SWPORTAL5,
97142 + e_QM_FQ_CHANNEL_SWPORTAL6,
97143 + e_QM_FQ_CHANNEL_SWPORTAL7,
97144 + e_QM_FQ_CHANNEL_SWPORTAL8,
97145 + e_QM_FQ_CHANNEL_SWPORTAL9,
97146 + e_QM_FQ_CHANNEL_SWPORTAL10,
97147 + e_QM_FQ_CHANNEL_SWPORTAL11,
97148 + e_QM_FQ_CHANNEL_SWPORTAL12,
97149 + e_QM_FQ_CHANNEL_SWPORTAL13,
97150 + e_QM_FQ_CHANNEL_SWPORTAL14,
97151 + e_QM_FQ_CHANNEL_SWPORTAL15,
97152 + e_QM_FQ_CHANNEL_SWPORTAL16,
97153 + e_QM_FQ_CHANNEL_SWPORTAL17,
97154 + e_QM_FQ_CHANNEL_SWPORTAL18,
97155 + e_QM_FQ_CHANNEL_SWPORTAL19,
97156 + e_QM_FQ_CHANNEL_SWPORTAL20,
97157 + e_QM_FQ_CHANNEL_SWPORTAL21,
97158 + e_QM_FQ_CHANNEL_SWPORTAL22,
97159 + e_QM_FQ_CHANNEL_SWPORTAL23,
97160 + e_QM_FQ_CHANNEL_SWPORTAL24,
97161 +
97162 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
97163 + e_QM_FQ_CHANNEL_POOL2,
97164 + e_QM_FQ_CHANNEL_POOL3,
97165 + e_QM_FQ_CHANNEL_POOL4,
97166 + e_QM_FQ_CHANNEL_POOL5,
97167 + e_QM_FQ_CHANNEL_POOL6,
97168 + e_QM_FQ_CHANNEL_POOL7,
97169 + e_QM_FQ_CHANNEL_POOL8,
97170 + e_QM_FQ_CHANNEL_POOL9,
97171 + e_QM_FQ_CHANNEL_POOL10,
97172 + e_QM_FQ_CHANNEL_POOL11,
97173 + e_QM_FQ_CHANNEL_POOL12,
97174 + e_QM_FQ_CHANNEL_POOL13,
97175 + e_QM_FQ_CHANNEL_POOL14,
97176 + e_QM_FQ_CHANNEL_POOL15,
97177 +
97178 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
97179 + connected to FMan 0; assigned in incrementing order to
97180 + each sub-portal (SP) in the portal */
97181 + e_QM_FQ_CHANNEL_FMAN0_SP1,
97182 + e_QM_FQ_CHANNEL_FMAN0_SP2,
97183 + e_QM_FQ_CHANNEL_FMAN0_SP3,
97184 + e_QM_FQ_CHANNEL_FMAN0_SP4,
97185 + e_QM_FQ_CHANNEL_FMAN0_SP5,
97186 + e_QM_FQ_CHANNEL_FMAN0_SP6,
97187 + e_QM_FQ_CHANNEL_FMAN0_SP7,
97188 + e_QM_FQ_CHANNEL_FMAN0_SP8,
97189 + e_QM_FQ_CHANNEL_FMAN0_SP9,
97190 + e_QM_FQ_CHANNEL_FMAN0_SP10,
97191 + e_QM_FQ_CHANNEL_FMAN0_SP11,
97192 + e_QM_FQ_CHANNEL_FMAN0_SP12,
97193 + e_QM_FQ_CHANNEL_FMAN0_SP13,
97194 + e_QM_FQ_CHANNEL_FMAN0_SP14,
97195 + e_QM_FQ_CHANNEL_FMAN0_SP15,
97196 +
97197 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
97198 + e_QM_FQ_CHANNEL_RMAN_SP1,
97199 +
97200 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
97201 + connected to SEC */
97202 +} e_QmFQChannel;
97203 +
97204 +/*****************************************************************************
97205 + BMan INTEGRATION-SPECIFIC DEFINITIONS
97206 +******************************************************************************/
97207 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
97208 +
97209 +/*****************************************************************************
97210 + SEC INTEGRATION-SPECIFIC DEFINITIONS
97211 +******************************************************************************/
97212 +#define SEC_NUM_OF_DECOS 3
97213 +#define SEC_ALL_DECOS_MASK 0x00000003
97214 +
97215 +
97216 +/*****************************************************************************
97217 + FM INTEGRATION-SPECIFIC DEFINITIONS
97218 +******************************************************************************/
97219 +#define INTG_MAX_NUM_OF_FM 2
97220 +/* Ports defines */
97221 +#define FM_MAX_NUM_OF_1G_MACS 6
97222 +#define FM_MAX_NUM_OF_10G_MACS 2
97223 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
97224 +#define FM_MAX_NUM_OF_OH_PORTS 6
97225 +
97226 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
97227 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
97228 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
97229 +
97230 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
97231 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
97232 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
97233 +
97234 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
97235 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
97236 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
97237 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
97238 +
97239 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
97240 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
97241 +
97242 +/* RAMs defines */
97243 +#define FM_MURAM_SIZE (384 * KILOBYTE)
97244 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
97245 +#define FM_NUM_OF_CTRL 4
97246 +
97247 +/* PCD defines */
97248 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
97249 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
97250 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
97251 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
97252 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
97253 +
97254 +/* RTC defines */
97255 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
97256 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
97257 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
97258 +
97259 +/* QMI defines */
97260 +#define QMI_MAX_NUM_OF_TNUMS 64
97261 +#define QMI_DEF_TNUMS_THRESH 32
97262 +/* FPM defines */
97263 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
97264 +
97265 +/* DMA defines */
97266 +#define DMA_THRESH_MAX_COMMQ 83
97267 +#define DMA_THRESH_MAX_BUF 127
97268 +
97269 +/* BMI defines */
97270 +#define BMI_MAX_NUM_OF_TASKS 128
97271 +#define BMI_MAX_NUM_OF_DMAS 84
97272 +
97273 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
97274 +#define PORT_MAX_WEIGHT 16
97275 +
97276 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
97277 +
97278 +/* Unique T4240 */
97279 +#define FM_OP_OPEN_DMA_MIN_LIMIT
97280 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
97281 +#define FM_NO_OP_OBSERVED_POOLS
97282 +#define FM_FRAME_END_PARAMS_FOR_OP
97283 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
97284 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
97285 +
97286 +#define FM_NO_GUARANTEED_RESET_VALUES
97287 +
97288 +/* FM errata */
97289 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
97290 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
97291 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
97292 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
97293 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
97294 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
97295 +
97296 +#define FM_BCB_ERRATA_BMI_SW001
97297 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
97298 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
97299 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
97300 +
97301 +/*****************************************************************************
97302 + RMan INTEGRATION-SPECIFIC DEFINITIONS
97303 +******************************************************************************/
97304 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
97305 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
97306 +
97307 +/* RMan erratas */
97308 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
97309 +
97310 +/*****************************************************************************
97311 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
97312 +******************************************************************************/
97313 +#define NUM_OF_RX_SC 16
97314 +#define NUM_OF_TX_SC 16
97315 +
97316 +#define NUM_OF_SA_PER_RX_SC 2
97317 +#define NUM_OF_SA_PER_TX_SC 2
97318 +
97319 +#endif /* __DPAA_INTEGRATION_EXT_H */
97320 --- /dev/null
97321 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
97322 @@ -0,0 +1,71 @@
97323 +/*
97324 + * Copyright 2012 Freescale Semiconductor Inc.
97325 + *
97326 + * Redistribution and use in source and binary forms, with or without
97327 + * modification, are permitted provided that the following conditions are met:
97328 + * * Redistributions of source code must retain the above copyright
97329 + * notice, this list of conditions and the following disclaimer.
97330 + * * Redistributions in binary form must reproduce the above copyright
97331 + * notice, this list of conditions and the following disclaimer in the
97332 + * documentation and/or other materials provided with the distribution.
97333 + * * Neither the name of Freescale Semiconductor nor the
97334 + * names of its contributors may be used to endorse or promote products
97335 + * derived from this software without specific prior written permission.
97336 + *
97337 + *
97338 + * ALTERNATIVELY, this software may be distributed under the terms of the
97339 + * GNU General Public License ("GPL") as published by the Free Software
97340 + * Foundation, either version 2 of that License or (at your option) any
97341 + * later version.
97342 + *
97343 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97344 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97345 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97346 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97347 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97348 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97349 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97350 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97351 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97352 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97353 + */
97354 +
97355 +/**************************************************************************//**
97356 +
97357 + @File part_ext.h
97358 +
97359 + @Description Definitions for the part (integration) module.
97360 +*//***************************************************************************/
97361 +
97362 +#ifndef __PART_EXT_H
97363 +#define __PART_EXT_H
97364 +
97365 +#include "std_ext.h"
97366 +#include "part_integration_ext.h"
97367 +
97368 +#if !(defined(P1023) || \
97369 + defined(P2041) || \
97370 + defined(P3041) || \
97371 + defined(P4080) || \
97372 + defined(P5020) || \
97373 + defined(P5040) || \
97374 + defined(B4860) || \
97375 + defined(T4240))
97376 +#error "unable to proceed without chip-definition"
97377 +#endif
97378 +
97379 +
97380 +/**************************************************************************//*
97381 + @Description Part data structure - must be contained in any integration
97382 + data structure.
97383 +*//***************************************************************************/
97384 +typedef struct t_Part
97385 +{
97386 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
97387 + /**< Returns the address of the module's memory map base. */
97388 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
97389 + /**< Returns the module's ID according to its memory map base. */
97390 +} t_Part;
97391 +
97392 +
97393 +#endif /* __PART_EXT_H */
97394 --- /dev/null
97395 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
97396 @@ -0,0 +1,304 @@
97397 +/*
97398 + * Copyright 2008-2012 Freescale Semiconductor Inc.
97399 + *
97400 + * Redistribution and use in source and binary forms, with or without
97401 + * modification, are permitted provided that the following conditions are met:
97402 + * * Redistributions of source code must retain the above copyright
97403 + * notice, this list of conditions and the following disclaimer.
97404 + * * Redistributions in binary form must reproduce the above copyright
97405 + * notice, this list of conditions and the following disclaimer in the
97406 + * documentation and/or other materials provided with the distribution.
97407 + * * Neither the name of Freescale Semiconductor nor the
97408 + * names of its contributors may be used to endorse or promote products
97409 + * derived from this software without specific prior written permission.
97410 + *
97411 + *
97412 + * ALTERNATIVELY, this software may be distributed under the terms of the
97413 + * GNU General Public License ("GPL") as published by the Free Software
97414 + * Foundation, either version 2 of that License or (at your option) any
97415 + * later version.
97416 + *
97417 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97418 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97419 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97420 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97421 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97422 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97423 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97424 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97425 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97426 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97427 + */
97428 +
97429 +/**
97430 +
97431 + @File part_integration_ext.h
97432 +
97433 + @Description T4240 external definitions and structures.
97434 +*//***************************************************************************/
97435 +#ifndef __PART_INTEGRATION_EXT_H
97436 +#define __PART_INTEGRATION_EXT_H
97437 +
97438 +#include "std_ext.h"
97439 +#include "ddr_std_ext.h"
97440 +#include "enet_ext.h"
97441 +#include "dpaa_integration_ext.h"
97442 +
97443 +
97444 +/**************************************************************************//**
97445 + @Group T4240_chip_id T4240 Application Programming Interface
97446 +
97447 + @Description T4240 Chip functions,definitions and enums.
97448 +
97449 + @{
97450 +*//***************************************************************************/
97451 +
97452 +#define CORE_E6500
97453 +
97454 +#define INTG_MAX_NUM_OF_CORES 24
97455 +
97456 +
97457 +/**************************************************************************//**
97458 + @Description Module types.
97459 +*//***************************************************************************/
97460 +typedef enum e_ModuleId
97461 +{
97462 + e_MODULE_ID_DUART_1 = 0,
97463 + e_MODULE_ID_DUART_2,
97464 + e_MODULE_ID_DUART_3,
97465 + e_MODULE_ID_DUART_4,
97466 + e_MODULE_ID_LAW,
97467 + e_MODULE_ID_IFC,
97468 + e_MODULE_ID_PAMU,
97469 + e_MODULE_ID_QM, /**< Queue manager module */
97470 + e_MODULE_ID_BM, /**< Buffer manager module */
97471 + e_MODULE_ID_QM_CE_PORTAL_0,
97472 + e_MODULE_ID_QM_CI_PORTAL_0,
97473 + e_MODULE_ID_QM_CE_PORTAL_1,
97474 + e_MODULE_ID_QM_CI_PORTAL_1,
97475 + e_MODULE_ID_QM_CE_PORTAL_2,
97476 + e_MODULE_ID_QM_CI_PORTAL_2,
97477 + e_MODULE_ID_QM_CE_PORTAL_3,
97478 + e_MODULE_ID_QM_CI_PORTAL_3,
97479 + e_MODULE_ID_QM_CE_PORTAL_4,
97480 + e_MODULE_ID_QM_CI_PORTAL_4,
97481 + e_MODULE_ID_QM_CE_PORTAL_5,
97482 + e_MODULE_ID_QM_CI_PORTAL_5,
97483 + e_MODULE_ID_QM_CE_PORTAL_6,
97484 + e_MODULE_ID_QM_CI_PORTAL_6,
97485 + e_MODULE_ID_QM_CE_PORTAL_7,
97486 + e_MODULE_ID_QM_CI_PORTAL_7,
97487 + e_MODULE_ID_QM_CE_PORTAL_8,
97488 + e_MODULE_ID_QM_CI_PORTAL_8,
97489 + e_MODULE_ID_QM_CE_PORTAL_9,
97490 + e_MODULE_ID_QM_CI_PORTAL_9,
97491 + e_MODULE_ID_BM_CE_PORTAL_0,
97492 + e_MODULE_ID_BM_CI_PORTAL_0,
97493 + e_MODULE_ID_BM_CE_PORTAL_1,
97494 + e_MODULE_ID_BM_CI_PORTAL_1,
97495 + e_MODULE_ID_BM_CE_PORTAL_2,
97496 + e_MODULE_ID_BM_CI_PORTAL_2,
97497 + e_MODULE_ID_BM_CE_PORTAL_3,
97498 + e_MODULE_ID_BM_CI_PORTAL_3,
97499 + e_MODULE_ID_BM_CE_PORTAL_4,
97500 + e_MODULE_ID_BM_CI_PORTAL_4,
97501 + e_MODULE_ID_BM_CE_PORTAL_5,
97502 + e_MODULE_ID_BM_CI_PORTAL_5,
97503 + e_MODULE_ID_BM_CE_PORTAL_6,
97504 + e_MODULE_ID_BM_CI_PORTAL_6,
97505 + e_MODULE_ID_BM_CE_PORTAL_7,
97506 + e_MODULE_ID_BM_CI_PORTAL_7,
97507 + e_MODULE_ID_BM_CE_PORTAL_8,
97508 + e_MODULE_ID_BM_CI_PORTAL_8,
97509 + e_MODULE_ID_BM_CE_PORTAL_9,
97510 + e_MODULE_ID_BM_CI_PORTAL_9,
97511 + e_MODULE_ID_FM, /**< Frame manager module */
97512 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
97513 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
97514 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
97515 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
97516 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
97517 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
97518 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
97519 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
97520 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
97521 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
97522 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
97523 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
97524 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
97525 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
97526 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
97527 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
97528 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
97529 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
97530 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
97531 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
97532 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
97533 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
97534 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
97535 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
97536 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
97537 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
97538 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
97539 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
97540 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
97541 + e_MODULE_ID_FM_KG, /**< FM Keygen */
97542 + e_MODULE_ID_FM_DMA, /**< FM DMA */
97543 + e_MODULE_ID_FM_FPM, /**< FM FPM */
97544 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
97545 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
97546 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
97547 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
97548 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
97549 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
97550 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
97551 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
97552 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
97553 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
97554 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
97555 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
97556 +
97557 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
97558 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
97559 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
97560 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
97561 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
97562 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
97563 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
97564 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
97565 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
97566 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
97567 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
97568 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
97569 +
97570 + e_MODULE_ID_PIC, /**< PIC */
97571 + e_MODULE_ID_GPIO, /**< GPIO */
97572 + e_MODULE_ID_SERDES, /**< SERDES */
97573 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
97574 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
97575 +
97576 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
97577 +
97578 + e_MODULE_ID_DUMMY_LAST
97579 +} e_ModuleId;
97580 +
97581 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
97582 +
97583 +#if 0 /* using unified values */
97584 +/*****************************************************************************
97585 + INTEGRATION-SPECIFIC MODULE CODES
97586 +******************************************************************************/
97587 +#define MODULE_UNKNOWN 0x00000000
97588 +#define MODULE_MEM 0x00010000
97589 +#define MODULE_MM 0x00020000
97590 +#define MODULE_CORE 0x00030000
97591 +#define MODULE_T4240 0x00040000
97592 +#define MODULE_T4240_PLATFORM 0x00050000
97593 +#define MODULE_PM 0x00060000
97594 +#define MODULE_MMU 0x00070000
97595 +#define MODULE_PIC 0x00080000
97596 +#define MODULE_CPC 0x00090000
97597 +#define MODULE_DUART 0x000a0000
97598 +#define MODULE_SERDES 0x000b0000
97599 +#define MODULE_PIO 0x000c0000
97600 +#define MODULE_QM 0x000d0000
97601 +#define MODULE_BM 0x000e0000
97602 +#define MODULE_SEC 0x000f0000
97603 +#define MODULE_LAW 0x00100000
97604 +#define MODULE_LBC 0x00110000
97605 +#define MODULE_PAMU 0x00120000
97606 +#define MODULE_FM 0x00130000
97607 +#define MODULE_FM_MURAM 0x00140000
97608 +#define MODULE_FM_PCD 0x00150000
97609 +#define MODULE_FM_RTC 0x00160000
97610 +#define MODULE_FM_MAC 0x00170000
97611 +#define MODULE_FM_PORT 0x00180000
97612 +#define MODULE_FM_SP 0x00190000
97613 +#define MODULE_DPA_PORT 0x001a0000
97614 +#define MODULE_MII 0x001b0000
97615 +#define MODULE_I2C 0x001c0000
97616 +#define MODULE_DMA 0x001d0000
97617 +#define MODULE_DDR 0x001e0000
97618 +#define MODULE_ESPI 0x001f0000
97619 +#define MODULE_DPAA_IPSEC 0x00200000
97620 +#endif /* using unified values */
97621 +
97622 +/*****************************************************************************
97623 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
97624 +******************************************************************************/
97625 +#define PAMU_NUM_OF_PARTITIONS 4
97626 +
97627 +/*****************************************************************************
97628 + LAW INTEGRATION-SPECIFIC DEFINITIONS
97629 +******************************************************************************/
97630 +#define LAW_NUM_OF_WINDOWS 32
97631 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
97632 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
97633 +
97634 +
97635 +/*****************************************************************************
97636 + LBC INTEGRATION-SPECIFIC DEFINITIONS
97637 +******************************************************************************/
97638 +/**************************************************************************//**
97639 + @Group lbc_exception_grp LBC Exception Unit
97640 +
97641 + @Description LBC Exception unit API functions, definitions and enums
97642 +
97643 + @{
97644 +*//***************************************************************************/
97645 +
97646 +/**************************************************************************//**
97647 + @Anchor lbc_exbm
97648 +
97649 + @Collection LBC Errors Bit Mask
97650 +
97651 + These errors are reported through the exceptions callback..
97652 + The values can be or'ed in any combination in the errors mask
97653 + parameter of the errors report structure.
97654 +
97655 + These errors can also be passed as a bit-mask to
97656 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
97657 + for enabling or disabling error checking.
97658 + @{
97659 +*//***************************************************************************/
97660 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
97661 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
97662 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
97663 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
97664 +
97665 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
97666 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
97667 + /**< All possible errors */
97668 +/* @} */
97669 +/** @} */ /* end of lbc_exception_grp group */
97670 +
97671 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
97672 +
97673 +#define LBC_NUM_OF_BANKS 8
97674 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
97675 +#define LBC_PARITY_SUPPORT
97676 +#define LBC_ADDRESS_HOLD_TIME_CTRL
97677 +#define LBC_HIGH_CLK_DIVIDERS
97678 +#define LBC_FCM_AVAILABLE
97679 +
97680 +/*****************************************************************************
97681 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
97682 +******************************************************************************/
97683 +#define GPIO_PORT_OFFSET_0x1000
97684 +
97685 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
97686 + Each port contains up to 32 I/O pins. */
97687 +
97688 +#define GPIO_VALID_PIN_MASKS \
97689 + { /* Port A */ 0xFFFFFFFF, \
97690 + /* Port B */ 0xFFFFFFFF, \
97691 + /* Port C */ 0xFFFFFFFF }
97692 +
97693 +#define GPIO_VALID_INTR_MASKS \
97694 + { /* Port A */ 0xFFFFFFFF, \
97695 + /* Port B */ 0xFFFFFFFF, \
97696 + /* Port C */ 0xFFFFFFFF }
97697 +
97698 +
97699 +
97700 +#endif /* __PART_INTEGRATION_EXT_H */
97701 --- /dev/null
97702 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
97703 @@ -0,0 +1,293 @@
97704 +/*
97705 + * Copyright 2012 Freescale Semiconductor Inc.
97706 + *
97707 + * Redistribution and use in source and binary forms, with or without
97708 + * modification, are permitted provided that the following conditions are met:
97709 + * * Redistributions of source code must retain the above copyright
97710 + * notice, this list of conditions and the following disclaimer.
97711 + * * Redistributions in binary form must reproduce the above copyright
97712 + * notice, this list of conditions and the following disclaimer in the
97713 + * documentation and/or other materials provided with the distribution.
97714 + * * Neither the name of Freescale Semiconductor nor the
97715 + * names of its contributors may be used to endorse or promote products
97716 + * derived from this software without specific prior written permission.
97717 + *
97718 + *
97719 + * ALTERNATIVELY, this software may be distributed under the terms of the
97720 + * GNU General Public License ("GPL") as published by the Free Software
97721 + * Foundation, either version 2 of that License or (at your option) any
97722 + * later version.
97723 + *
97724 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97725 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97726 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97727 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97728 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97729 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97730 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97731 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97732 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97733 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97734 + */
97735 +
97736 +/**
97737 +
97738 + @File dpaa_integration_ext.h
97739 +
97740 + @Description T4240 FM external definitions and structures.
97741 +*//***************************************************************************/
97742 +#ifndef __DPAA_INTEGRATION_EXT_H
97743 +#define __DPAA_INTEGRATION_EXT_H
97744 +
97745 +#include "std_ext.h"
97746 +
97747 +
97748 +#define DPAA_VERSION 11
97749 +
97750 +/**************************************************************************//**
97751 + @Description DPAA SW Portals Enumeration.
97752 +*//***************************************************************************/
97753 +typedef enum
97754 +{
97755 + e_DPAA_SWPORTAL0 = 0,
97756 + e_DPAA_SWPORTAL1,
97757 + e_DPAA_SWPORTAL2,
97758 + e_DPAA_SWPORTAL3,
97759 + e_DPAA_SWPORTAL4,
97760 + e_DPAA_SWPORTAL5,
97761 + e_DPAA_SWPORTAL6,
97762 + e_DPAA_SWPORTAL7,
97763 + e_DPAA_SWPORTAL8,
97764 + e_DPAA_SWPORTAL9,
97765 + e_DPAA_SWPORTAL10,
97766 + e_DPAA_SWPORTAL11,
97767 + e_DPAA_SWPORTAL12,
97768 + e_DPAA_SWPORTAL13,
97769 + e_DPAA_SWPORTAL14,
97770 + e_DPAA_SWPORTAL15,
97771 + e_DPAA_SWPORTAL16,
97772 + e_DPAA_SWPORTAL17,
97773 + e_DPAA_SWPORTAL18,
97774 + e_DPAA_SWPORTAL19,
97775 + e_DPAA_SWPORTAL20,
97776 + e_DPAA_SWPORTAL21,
97777 + e_DPAA_SWPORTAL22,
97778 + e_DPAA_SWPORTAL23,
97779 + e_DPAA_SWPORTAL24,
97780 + e_DPAA_SWPORTAL_DUMMY_LAST
97781 +} e_DpaaSwPortal;
97782 +
97783 +/**************************************************************************//**
97784 + @Description DPAA Direct Connect Portals Enumeration.
97785 +*//***************************************************************************/
97786 +typedef enum
97787 +{
97788 + e_DPAA_DCPORTAL0 = 0,
97789 + e_DPAA_DCPORTAL1,
97790 + e_DPAA_DCPORTAL2,
97791 + e_DPAA_DCPORTAL_DUMMY_LAST
97792 +} e_DpaaDcPortal;
97793 +
97794 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
97795 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
97796 +
97797 +/*****************************************************************************
97798 + QMan INTEGRATION-SPECIFIC DEFINITIONS
97799 +******************************************************************************/
97800 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
97801 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
97802 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
97803 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
97804 + /**< FQIDs range - 24 bits */
97805 +
97806 +/**************************************************************************//**
97807 + @Description Work Queue Channel assignments in QMan.
97808 +*//***************************************************************************/
97809 +typedef enum
97810 +{
97811 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
97812 + e_QM_FQ_CHANNEL_SWPORTAL1,
97813 + e_QM_FQ_CHANNEL_SWPORTAL2,
97814 + e_QM_FQ_CHANNEL_SWPORTAL3,
97815 + e_QM_FQ_CHANNEL_SWPORTAL4,
97816 + e_QM_FQ_CHANNEL_SWPORTAL5,
97817 + e_QM_FQ_CHANNEL_SWPORTAL6,
97818 + e_QM_FQ_CHANNEL_SWPORTAL7,
97819 + e_QM_FQ_CHANNEL_SWPORTAL8,
97820 + e_QM_FQ_CHANNEL_SWPORTAL9,
97821 + e_QM_FQ_CHANNEL_SWPORTAL10,
97822 + e_QM_FQ_CHANNEL_SWPORTAL11,
97823 + e_QM_FQ_CHANNEL_SWPORTAL12,
97824 + e_QM_FQ_CHANNEL_SWPORTAL13,
97825 + e_QM_FQ_CHANNEL_SWPORTAL14,
97826 + e_QM_FQ_CHANNEL_SWPORTAL15,
97827 + e_QM_FQ_CHANNEL_SWPORTAL16,
97828 + e_QM_FQ_CHANNEL_SWPORTAL17,
97829 + e_QM_FQ_CHANNEL_SWPORTAL18,
97830 + e_QM_FQ_CHANNEL_SWPORTAL19,
97831 + e_QM_FQ_CHANNEL_SWPORTAL20,
97832 + e_QM_FQ_CHANNEL_SWPORTAL21,
97833 + e_QM_FQ_CHANNEL_SWPORTAL22,
97834 + e_QM_FQ_CHANNEL_SWPORTAL23,
97835 + e_QM_FQ_CHANNEL_SWPORTAL24,
97836 +
97837 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
97838 + e_QM_FQ_CHANNEL_POOL2,
97839 + e_QM_FQ_CHANNEL_POOL3,
97840 + e_QM_FQ_CHANNEL_POOL4,
97841 + e_QM_FQ_CHANNEL_POOL5,
97842 + e_QM_FQ_CHANNEL_POOL6,
97843 + e_QM_FQ_CHANNEL_POOL7,
97844 + e_QM_FQ_CHANNEL_POOL8,
97845 + e_QM_FQ_CHANNEL_POOL9,
97846 + e_QM_FQ_CHANNEL_POOL10,
97847 + e_QM_FQ_CHANNEL_POOL11,
97848 + e_QM_FQ_CHANNEL_POOL12,
97849 + e_QM_FQ_CHANNEL_POOL13,
97850 + e_QM_FQ_CHANNEL_POOL14,
97851 + e_QM_FQ_CHANNEL_POOL15,
97852 +
97853 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
97854 + connected to FMan 0; assigned in incrementing order to
97855 + each sub-portal (SP) in the portal */
97856 + e_QM_FQ_CHANNEL_FMAN0_SP1,
97857 + e_QM_FQ_CHANNEL_FMAN0_SP2,
97858 + e_QM_FQ_CHANNEL_FMAN0_SP3,
97859 + e_QM_FQ_CHANNEL_FMAN0_SP4,
97860 + e_QM_FQ_CHANNEL_FMAN0_SP5,
97861 + e_QM_FQ_CHANNEL_FMAN0_SP6,
97862 + e_QM_FQ_CHANNEL_FMAN0_SP7,
97863 + e_QM_FQ_CHANNEL_FMAN0_SP8,
97864 + e_QM_FQ_CHANNEL_FMAN0_SP9,
97865 + e_QM_FQ_CHANNEL_FMAN0_SP10,
97866 + e_QM_FQ_CHANNEL_FMAN0_SP11,
97867 + e_QM_FQ_CHANNEL_FMAN0_SP12,
97868 + e_QM_FQ_CHANNEL_FMAN0_SP13,
97869 + e_QM_FQ_CHANNEL_FMAN0_SP14,
97870 + e_QM_FQ_CHANNEL_FMAN0_SP15,
97871 +
97872 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
97873 + e_QM_FQ_CHANNEL_RMAN_SP1,
97874 +
97875 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
97876 + connected to SEC */
97877 +} e_QmFQChannel;
97878 +
97879 +/*****************************************************************************
97880 + BMan INTEGRATION-SPECIFIC DEFINITIONS
97881 +******************************************************************************/
97882 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
97883 +
97884 +/*****************************************************************************
97885 + SEC INTEGRATION-SPECIFIC DEFINITIONS
97886 +******************************************************************************/
97887 +#define SEC_NUM_OF_DECOS 3
97888 +#define SEC_ALL_DECOS_MASK 0x00000003
97889 +
97890 +
97891 +/*****************************************************************************
97892 + FM INTEGRATION-SPECIFIC DEFINITIONS
97893 +******************************************************************************/
97894 +#define INTG_MAX_NUM_OF_FM 1
97895 +/* Ports defines */
97896 +#define FM_MAX_NUM_OF_1G_MACS 5
97897 +#define FM_MAX_NUM_OF_10G_MACS 1
97898 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
97899 +#define FM_MAX_NUM_OF_OH_PORTS 4
97900 +
97901 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
97902 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
97903 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
97904 +
97905 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
97906 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
97907 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
97908 +
97909 +#define FM_MAX_NUM_OF_MACSECS 1 /* Should be updated */
97910 +
97911 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
97912 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
97913 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
97914 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
97915 +
97916 +#define FM_VSP_MAX_NUM_OF_ENTRIES 32
97917 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
97918 +
97919 +/* RAMs defines */
97920 +#define FM_MURAM_SIZE (192 * KILOBYTE)
97921 +#define FM_IRAM_SIZE(major, minor) \
97922 + (((major == 6) && ((minor == 4) )) ? (64 * KILOBYTE) : (32 * KILOBYTE))
97923 +#define FM_NUM_OF_CTRL 2
97924 +
97925 +/* PCD defines */
97926 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
97927 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
97928 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
97929 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
97930 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
97931 +
97932 +/* RTC defines */
97933 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
97934 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
97935 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
97936 +
97937 +/* QMI defines */
97938 +#define QMI_MAX_NUM_OF_TNUMS 64
97939 +#define QMI_DEF_TNUMS_THRESH 32
97940 +/* FPM defines */
97941 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
97942 +
97943 +/* DMA defines */
97944 +#define DMA_THRESH_MAX_COMMQ 83
97945 +#define DMA_THRESH_MAX_BUF 127
97946 +
97947 +/* BMI defines */
97948 +#define BMI_MAX_NUM_OF_TASKS 64
97949 +#define BMI_MAX_NUM_OF_DMAS 32
97950 +
97951 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
97952 +#define PORT_MAX_WEIGHT 16
97953 +
97954 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
97955 +
97956 +/* Unique T4240 */
97957 +#define FM_OP_OPEN_DMA_MIN_LIMIT
97958 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
97959 +#define FM_NO_OP_OBSERVED_POOLS
97960 +#define FM_FRAME_END_PARAMS_FOR_OP
97961 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
97962 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
97963 +
97964 +#define FM_NO_GUARANTEED_RESET_VALUES
97965 +
97966 +/* FM errata */
97967 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
97968 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
97969 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
97970 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
97971 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
97972 +
97973 +#define FM_BCB_ERRATA_BMI_SW001
97974 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
97975 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
97976 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
97977 +
97978 +/*****************************************************************************
97979 + RMan INTEGRATION-SPECIFIC DEFINITIONS
97980 +******************************************************************************/
97981 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
97982 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
97983 +
97984 +/* RMan erratas */
97985 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
97986 +
97987 +/*****************************************************************************
97988 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
97989 +******************************************************************************/
97990 +#define NUM_OF_RX_SC 16
97991 +#define NUM_OF_TX_SC 16
97992 +
97993 +#define NUM_OF_SA_PER_RX_SC 2
97994 +#define NUM_OF_SA_PER_TX_SC 2
97995 +
97996 +#endif /* __DPAA_INTEGRATION_EXT_H */
97997 --- /dev/null
97998 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
97999 @@ -0,0 +1,59 @@
98000 +/*
98001 + * Copyright 2012 Freescale Semiconductor Inc.
98002 + *
98003 + * Redistribution and use in source and binary forms, with or without
98004 + * modification, are permitted provided that the following conditions are met:
98005 + * * Redistributions of source code must retain the above copyright
98006 + * notice, this list of conditions and the following disclaimer.
98007 + * * Redistributions in binary form must reproduce the above copyright
98008 + * notice, this list of conditions and the following disclaimer in the
98009 + * documentation and/or other materials provided with the distribution.
98010 + * * Neither the name of Freescale Semiconductor nor the
98011 + * names of its contributors may be used to endorse or promote products
98012 + * derived from this software without specific prior written permission.
98013 + *
98014 + *
98015 + * ALTERNATIVELY, this software may be distributed under the terms of the
98016 + * GNU General Public License ("GPL") as published by the Free Software
98017 + * Foundation, either version 2 of that License or (at your option) any
98018 + * later version.
98019 + *
98020 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98021 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98022 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98023 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98024 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98025 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98026 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98027 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98028 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98029 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98030 + */
98031 +
98032 +/**************************************************************************//**
98033 +
98034 + @File part_ext.h
98035 +
98036 + @Description Definitions for the part (integration) module.
98037 +*//***************************************************************************/
98038 +
98039 +#ifndef __PART_EXT_H
98040 +#define __PART_EXT_H
98041 +
98042 +#include "std_ext.h"
98043 +#include "part_integration_ext.h"
98044 +
98045 +/**************************************************************************//*
98046 + @Description Part data structure - must be contained in any integration
98047 + data structure.
98048 +*//***************************************************************************/
98049 +typedef struct t_Part
98050 +{
98051 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
98052 + /**< Returns the address of the module's memory map base. */
98053 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
98054 + /**< Returns the module's ID according to its memory map base. */
98055 +} t_Part;
98056 +
98057 +
98058 +#endif /* __PART_EXT_H */
98059 --- /dev/null
98060 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
98061 @@ -0,0 +1,304 @@
98062 +/*
98063 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98064 + *
98065 + * Redistribution and use in source and binary forms, with or without
98066 + * modification, are permitted provided that the following conditions are met:
98067 + * * Redistributions of source code must retain the above copyright
98068 + * notice, this list of conditions and the following disclaimer.
98069 + * * Redistributions in binary form must reproduce the above copyright
98070 + * notice, this list of conditions and the following disclaimer in the
98071 + * documentation and/or other materials provided with the distribution.
98072 + * * Neither the name of Freescale Semiconductor nor the
98073 + * names of its contributors may be used to endorse or promote products
98074 + * derived from this software without specific prior written permission.
98075 + *
98076 + *
98077 + * ALTERNATIVELY, this software may be distributed under the terms of the
98078 + * GNU General Public License ("GPL") as published by the Free Software
98079 + * Foundation, either version 2 of that License or (at your option) any
98080 + * later version.
98081 + *
98082 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98083 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98084 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98085 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98086 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98087 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98088 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98089 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98090 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98091 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98092 + */
98093 +
98094 +/**
98095 +
98096 + @File part_integration_ext.h
98097 +
98098 + @Description T4240 external definitions and structures.
98099 +*//***************************************************************************/
98100 +#ifndef __PART_INTEGRATION_EXT_H
98101 +#define __PART_INTEGRATION_EXT_H
98102 +
98103 +#include "std_ext.h"
98104 +#include "ddr_std_ext.h"
98105 +#include "enet_ext.h"
98106 +#include "dpaa_integration_ext.h"
98107 +
98108 +
98109 +/**************************************************************************//**
98110 + @Group T4240_chip_id T4240 Application Programming Interface
98111 +
98112 + @Description T4240 Chip functions,definitions and enums.
98113 +
98114 + @{
98115 +*//***************************************************************************/
98116 +
98117 +#define CORE_E6500
98118 +
98119 +#define INTG_MAX_NUM_OF_CORES 24
98120 +
98121 +
98122 +/**************************************************************************//**
98123 + @Description Module types.
98124 +*//***************************************************************************/
98125 +typedef enum e_ModuleId
98126 +{
98127 + e_MODULE_ID_DUART_1 = 0,
98128 + e_MODULE_ID_DUART_2,
98129 + e_MODULE_ID_DUART_3,
98130 + e_MODULE_ID_DUART_4,
98131 + e_MODULE_ID_LAW,
98132 + e_MODULE_ID_IFC,
98133 + e_MODULE_ID_PAMU,
98134 + e_MODULE_ID_QM, /**< Queue manager module */
98135 + e_MODULE_ID_BM, /**< Buffer manager module */
98136 + e_MODULE_ID_QM_CE_PORTAL_0,
98137 + e_MODULE_ID_QM_CI_PORTAL_0,
98138 + e_MODULE_ID_QM_CE_PORTAL_1,
98139 + e_MODULE_ID_QM_CI_PORTAL_1,
98140 + e_MODULE_ID_QM_CE_PORTAL_2,
98141 + e_MODULE_ID_QM_CI_PORTAL_2,
98142 + e_MODULE_ID_QM_CE_PORTAL_3,
98143 + e_MODULE_ID_QM_CI_PORTAL_3,
98144 + e_MODULE_ID_QM_CE_PORTAL_4,
98145 + e_MODULE_ID_QM_CI_PORTAL_4,
98146 + e_MODULE_ID_QM_CE_PORTAL_5,
98147 + e_MODULE_ID_QM_CI_PORTAL_5,
98148 + e_MODULE_ID_QM_CE_PORTAL_6,
98149 + e_MODULE_ID_QM_CI_PORTAL_6,
98150 + e_MODULE_ID_QM_CE_PORTAL_7,
98151 + e_MODULE_ID_QM_CI_PORTAL_7,
98152 + e_MODULE_ID_QM_CE_PORTAL_8,
98153 + e_MODULE_ID_QM_CI_PORTAL_8,
98154 + e_MODULE_ID_QM_CE_PORTAL_9,
98155 + e_MODULE_ID_QM_CI_PORTAL_9,
98156 + e_MODULE_ID_BM_CE_PORTAL_0,
98157 + e_MODULE_ID_BM_CI_PORTAL_0,
98158 + e_MODULE_ID_BM_CE_PORTAL_1,
98159 + e_MODULE_ID_BM_CI_PORTAL_1,
98160 + e_MODULE_ID_BM_CE_PORTAL_2,
98161 + e_MODULE_ID_BM_CI_PORTAL_2,
98162 + e_MODULE_ID_BM_CE_PORTAL_3,
98163 + e_MODULE_ID_BM_CI_PORTAL_3,
98164 + e_MODULE_ID_BM_CE_PORTAL_4,
98165 + e_MODULE_ID_BM_CI_PORTAL_4,
98166 + e_MODULE_ID_BM_CE_PORTAL_5,
98167 + e_MODULE_ID_BM_CI_PORTAL_5,
98168 + e_MODULE_ID_BM_CE_PORTAL_6,
98169 + e_MODULE_ID_BM_CI_PORTAL_6,
98170 + e_MODULE_ID_BM_CE_PORTAL_7,
98171 + e_MODULE_ID_BM_CI_PORTAL_7,
98172 + e_MODULE_ID_BM_CE_PORTAL_8,
98173 + e_MODULE_ID_BM_CI_PORTAL_8,
98174 + e_MODULE_ID_BM_CE_PORTAL_9,
98175 + e_MODULE_ID_BM_CI_PORTAL_9,
98176 + e_MODULE_ID_FM, /**< Frame manager module */
98177 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
98178 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
98179 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
98180 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
98181 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
98182 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
98183 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
98184 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
98185 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
98186 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
98187 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
98188 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
98189 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
98190 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
98191 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
98192 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
98193 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
98194 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
98195 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
98196 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
98197 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
98198 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
98199 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
98200 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
98201 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
98202 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
98203 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
98204 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
98205 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
98206 + e_MODULE_ID_FM_KG, /**< FM Keygen */
98207 + e_MODULE_ID_FM_DMA, /**< FM DMA */
98208 + e_MODULE_ID_FM_FPM, /**< FM FPM */
98209 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
98210 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
98211 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
98212 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
98213 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
98214 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
98215 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
98216 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
98217 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
98218 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
98219 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
98220 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
98221 +
98222 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
98223 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
98224 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
98225 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
98226 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
98227 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
98228 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
98229 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
98230 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
98231 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
98232 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
98233 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
98234 +
98235 + e_MODULE_ID_PIC, /**< PIC */
98236 + e_MODULE_ID_GPIO, /**< GPIO */
98237 + e_MODULE_ID_SERDES, /**< SERDES */
98238 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
98239 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
98240 +
98241 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
98242 +
98243 + e_MODULE_ID_DUMMY_LAST
98244 +} e_ModuleId;
98245 +
98246 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
98247 +
98248 +#if 0 /* using unified values */
98249 +/*****************************************************************************
98250 + INTEGRATION-SPECIFIC MODULE CODES
98251 +******************************************************************************/
98252 +#define MODULE_UNKNOWN 0x00000000
98253 +#define MODULE_MEM 0x00010000
98254 +#define MODULE_MM 0x00020000
98255 +#define MODULE_CORE 0x00030000
98256 +#define MODULE_T4240 0x00040000
98257 +#define MODULE_T4240_PLATFORM 0x00050000
98258 +#define MODULE_PM 0x00060000
98259 +#define MODULE_MMU 0x00070000
98260 +#define MODULE_PIC 0x00080000
98261 +#define MODULE_CPC 0x00090000
98262 +#define MODULE_DUART 0x000a0000
98263 +#define MODULE_SERDES 0x000b0000
98264 +#define MODULE_PIO 0x000c0000
98265 +#define MODULE_QM 0x000d0000
98266 +#define MODULE_BM 0x000e0000
98267 +#define MODULE_SEC 0x000f0000
98268 +#define MODULE_LAW 0x00100000
98269 +#define MODULE_LBC 0x00110000
98270 +#define MODULE_PAMU 0x00120000
98271 +#define MODULE_FM 0x00130000
98272 +#define MODULE_FM_MURAM 0x00140000
98273 +#define MODULE_FM_PCD 0x00150000
98274 +#define MODULE_FM_RTC 0x00160000
98275 +#define MODULE_FM_MAC 0x00170000
98276 +#define MODULE_FM_PORT 0x00180000
98277 +#define MODULE_FM_SP 0x00190000
98278 +#define MODULE_DPA_PORT 0x001a0000
98279 +#define MODULE_MII 0x001b0000
98280 +#define MODULE_I2C 0x001c0000
98281 +#define MODULE_DMA 0x001d0000
98282 +#define MODULE_DDR 0x001e0000
98283 +#define MODULE_ESPI 0x001f0000
98284 +#define MODULE_DPAA_IPSEC 0x00200000
98285 +#endif /* using unified values */
98286 +
98287 +/*****************************************************************************
98288 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
98289 +******************************************************************************/
98290 +#define PAMU_NUM_OF_PARTITIONS 4
98291 +
98292 +/*****************************************************************************
98293 + LAW INTEGRATION-SPECIFIC DEFINITIONS
98294 +******************************************************************************/
98295 +#define LAW_NUM_OF_WINDOWS 32
98296 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
98297 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
98298 +
98299 +
98300 +/*****************************************************************************
98301 + LBC INTEGRATION-SPECIFIC DEFINITIONS
98302 +******************************************************************************/
98303 +/**************************************************************************//**
98304 + @Group lbc_exception_grp LBC Exception Unit
98305 +
98306 + @Description LBC Exception unit API functions, definitions and enums
98307 +
98308 + @{
98309 +*//***************************************************************************/
98310 +
98311 +/**************************************************************************//**
98312 + @Anchor lbc_exbm
98313 +
98314 + @Collection LBC Errors Bit Mask
98315 +
98316 + These errors are reported through the exceptions callback..
98317 + The values can be or'ed in any combination in the errors mask
98318 + parameter of the errors report structure.
98319 +
98320 + These errors can also be passed as a bit-mask to
98321 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
98322 + for enabling or disabling error checking.
98323 + @{
98324 +*//***************************************************************************/
98325 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
98326 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
98327 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
98328 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
98329 +
98330 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
98331 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
98332 + /**< All possible errors */
98333 +/* @} */
98334 +/** @} */ /* end of lbc_exception_grp group */
98335 +
98336 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
98337 +
98338 +#define LBC_NUM_OF_BANKS 8
98339 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
98340 +#define LBC_PARITY_SUPPORT
98341 +#define LBC_ADDRESS_HOLD_TIME_CTRL
98342 +#define LBC_HIGH_CLK_DIVIDERS
98343 +#define LBC_FCM_AVAILABLE
98344 +
98345 +/*****************************************************************************
98346 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
98347 +******************************************************************************/
98348 +#define GPIO_PORT_OFFSET_0x1000
98349 +
98350 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
98351 + Each port contains up to 32 I/O pins. */
98352 +
98353 +#define GPIO_VALID_PIN_MASKS \
98354 + { /* Port A */ 0xFFFFFFFF, \
98355 + /* Port B */ 0xFFFFFFFF, \
98356 + /* Port C */ 0xFFFFFFFF }
98357 +
98358 +#define GPIO_VALID_INTR_MASKS \
98359 + { /* Port A */ 0xFFFFFFFF, \
98360 + /* Port B */ 0xFFFFFFFF, \
98361 + /* Port C */ 0xFFFFFFFF }
98362 +
98363 +
98364 +
98365 +#endif /* __PART_INTEGRATION_EXT_H */
98366 --- /dev/null
98367 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
98368 @@ -0,0 +1,291 @@
98369 +/*
98370 + * Copyright 2012 Freescale Semiconductor Inc.
98371 + *
98372 + * Redistribution and use in source and binary forms, with or without
98373 + * modification, are permitted provided that the following conditions are met:
98374 + * * Redistributions of source code must retain the above copyright
98375 + * notice, this list of conditions and the following disclaimer.
98376 + * * Redistributions in binary form must reproduce the above copyright
98377 + * notice, this list of conditions and the following disclaimer in the
98378 + * documentation and/or other materials provided with the distribution.
98379 + * * Neither the name of Freescale Semiconductor nor the
98380 + * names of its contributors may be used to endorse or promote products
98381 + * derived from this software without specific prior written permission.
98382 + *
98383 + *
98384 + * ALTERNATIVELY, this software may be distributed under the terms of the
98385 + * GNU General Public License ("GPL") as published by the Free Software
98386 + * Foundation, either version 2 of that License or (at your option) any
98387 + * later version.
98388 + *
98389 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98390 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98391 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98392 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98393 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98394 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98395 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98396 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98397 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98398 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98399 + */
98400 +
98401 +/**
98402 +
98403 + @File dpaa_integration_ext.h
98404 +
98405 + @Description T4240 FM external definitions and structures.
98406 +*//***************************************************************************/
98407 +#ifndef __DPAA_INTEGRATION_EXT_H
98408 +#define __DPAA_INTEGRATION_EXT_H
98409 +
98410 +#include "std_ext.h"
98411 +
98412 +
98413 +#define DPAA_VERSION 11
98414 +
98415 +/**************************************************************************//**
98416 + @Description DPAA SW Portals Enumeration.
98417 +*//***************************************************************************/
98418 +typedef enum
98419 +{
98420 + e_DPAA_SWPORTAL0 = 0,
98421 + e_DPAA_SWPORTAL1,
98422 + e_DPAA_SWPORTAL2,
98423 + e_DPAA_SWPORTAL3,
98424 + e_DPAA_SWPORTAL4,
98425 + e_DPAA_SWPORTAL5,
98426 + e_DPAA_SWPORTAL6,
98427 + e_DPAA_SWPORTAL7,
98428 + e_DPAA_SWPORTAL8,
98429 + e_DPAA_SWPORTAL9,
98430 + e_DPAA_SWPORTAL10,
98431 + e_DPAA_SWPORTAL11,
98432 + e_DPAA_SWPORTAL12,
98433 + e_DPAA_SWPORTAL13,
98434 + e_DPAA_SWPORTAL14,
98435 + e_DPAA_SWPORTAL15,
98436 + e_DPAA_SWPORTAL16,
98437 + e_DPAA_SWPORTAL17,
98438 + e_DPAA_SWPORTAL18,
98439 + e_DPAA_SWPORTAL19,
98440 + e_DPAA_SWPORTAL20,
98441 + e_DPAA_SWPORTAL21,
98442 + e_DPAA_SWPORTAL22,
98443 + e_DPAA_SWPORTAL23,
98444 + e_DPAA_SWPORTAL24,
98445 + e_DPAA_SWPORTAL_DUMMY_LAST
98446 +} e_DpaaSwPortal;
98447 +
98448 +/**************************************************************************//**
98449 + @Description DPAA Direct Connect Portals Enumeration.
98450 +*//***************************************************************************/
98451 +typedef enum
98452 +{
98453 + e_DPAA_DCPORTAL0 = 0,
98454 + e_DPAA_DCPORTAL1,
98455 + e_DPAA_DCPORTAL2,
98456 + e_DPAA_DCPORTAL_DUMMY_LAST
98457 +} e_DpaaDcPortal;
98458 +
98459 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98460 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98461 +
98462 +/*****************************************************************************
98463 + QMan INTEGRATION-SPECIFIC DEFINITIONS
98464 +******************************************************************************/
98465 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
98466 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
98467 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
98468 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
98469 + /**< FQIDs range - 24 bits */
98470 +
98471 +/**************************************************************************//**
98472 + @Description Work Queue Channel assignments in QMan.
98473 +*//***************************************************************************/
98474 +typedef enum
98475 +{
98476 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
98477 + e_QM_FQ_CHANNEL_SWPORTAL1,
98478 + e_QM_FQ_CHANNEL_SWPORTAL2,
98479 + e_QM_FQ_CHANNEL_SWPORTAL3,
98480 + e_QM_FQ_CHANNEL_SWPORTAL4,
98481 + e_QM_FQ_CHANNEL_SWPORTAL5,
98482 + e_QM_FQ_CHANNEL_SWPORTAL6,
98483 + e_QM_FQ_CHANNEL_SWPORTAL7,
98484 + e_QM_FQ_CHANNEL_SWPORTAL8,
98485 + e_QM_FQ_CHANNEL_SWPORTAL9,
98486 + e_QM_FQ_CHANNEL_SWPORTAL10,
98487 + e_QM_FQ_CHANNEL_SWPORTAL11,
98488 + e_QM_FQ_CHANNEL_SWPORTAL12,
98489 + e_QM_FQ_CHANNEL_SWPORTAL13,
98490 + e_QM_FQ_CHANNEL_SWPORTAL14,
98491 + e_QM_FQ_CHANNEL_SWPORTAL15,
98492 + e_QM_FQ_CHANNEL_SWPORTAL16,
98493 + e_QM_FQ_CHANNEL_SWPORTAL17,
98494 + e_QM_FQ_CHANNEL_SWPORTAL18,
98495 + e_QM_FQ_CHANNEL_SWPORTAL19,
98496 + e_QM_FQ_CHANNEL_SWPORTAL20,
98497 + e_QM_FQ_CHANNEL_SWPORTAL21,
98498 + e_QM_FQ_CHANNEL_SWPORTAL22,
98499 + e_QM_FQ_CHANNEL_SWPORTAL23,
98500 + e_QM_FQ_CHANNEL_SWPORTAL24,
98501 +
98502 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
98503 + e_QM_FQ_CHANNEL_POOL2,
98504 + e_QM_FQ_CHANNEL_POOL3,
98505 + e_QM_FQ_CHANNEL_POOL4,
98506 + e_QM_FQ_CHANNEL_POOL5,
98507 + e_QM_FQ_CHANNEL_POOL6,
98508 + e_QM_FQ_CHANNEL_POOL7,
98509 + e_QM_FQ_CHANNEL_POOL8,
98510 + e_QM_FQ_CHANNEL_POOL9,
98511 + e_QM_FQ_CHANNEL_POOL10,
98512 + e_QM_FQ_CHANNEL_POOL11,
98513 + e_QM_FQ_CHANNEL_POOL12,
98514 + e_QM_FQ_CHANNEL_POOL13,
98515 + e_QM_FQ_CHANNEL_POOL14,
98516 + e_QM_FQ_CHANNEL_POOL15,
98517 +
98518 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
98519 + connected to FMan 0; assigned in incrementing order to
98520 + each sub-portal (SP) in the portal */
98521 + e_QM_FQ_CHANNEL_FMAN0_SP1,
98522 + e_QM_FQ_CHANNEL_FMAN0_SP2,
98523 + e_QM_FQ_CHANNEL_FMAN0_SP3,
98524 + e_QM_FQ_CHANNEL_FMAN0_SP4,
98525 + e_QM_FQ_CHANNEL_FMAN0_SP5,
98526 + e_QM_FQ_CHANNEL_FMAN0_SP6,
98527 + e_QM_FQ_CHANNEL_FMAN0_SP7,
98528 + e_QM_FQ_CHANNEL_FMAN0_SP8,
98529 + e_QM_FQ_CHANNEL_FMAN0_SP9,
98530 + e_QM_FQ_CHANNEL_FMAN0_SP10,
98531 + e_QM_FQ_CHANNEL_FMAN0_SP11,
98532 + e_QM_FQ_CHANNEL_FMAN0_SP12,
98533 + e_QM_FQ_CHANNEL_FMAN0_SP13,
98534 + e_QM_FQ_CHANNEL_FMAN0_SP14,
98535 + e_QM_FQ_CHANNEL_FMAN0_SP15,
98536 +
98537 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
98538 + e_QM_FQ_CHANNEL_RMAN_SP1,
98539 +
98540 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
98541 + connected to SEC */
98542 +} e_QmFQChannel;
98543 +
98544 +/*****************************************************************************
98545 + BMan INTEGRATION-SPECIFIC DEFINITIONS
98546 +******************************************************************************/
98547 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
98548 +
98549 +/*****************************************************************************
98550 + SEC INTEGRATION-SPECIFIC DEFINITIONS
98551 +******************************************************************************/
98552 +#define SEC_NUM_OF_DECOS 3
98553 +#define SEC_ALL_DECOS_MASK 0x00000003
98554 +
98555 +
98556 +/*****************************************************************************
98557 + FM INTEGRATION-SPECIFIC DEFINITIONS
98558 +******************************************************************************/
98559 +#define INTG_MAX_NUM_OF_FM 2
98560 +
98561 +/* Ports defines */
98562 +#define FM_MAX_NUM_OF_1G_MACS 6
98563 +#define FM_MAX_NUM_OF_10G_MACS 2
98564 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
98565 +#define FM_MAX_NUM_OF_OH_PORTS 6
98566 +
98567 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
98568 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
98569 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
98570 +
98571 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
98572 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
98573 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
98574 +
98575 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
98576 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
98577 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
98578 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
98579 +
98580 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
98581 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
98582 +
98583 +/* RAMs defines */
98584 +#define FM_MURAM_SIZE (384 * KILOBYTE)
98585 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
98586 +#define FM_NUM_OF_CTRL 4
98587 +
98588 +/* PCD defines */
98589 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
98590 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
98591 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
98592 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
98593 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
98594 +
98595 +/* RTC defines */
98596 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
98597 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
98598 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
98599 +
98600 +/* QMI defines */
98601 +#define QMI_MAX_NUM_OF_TNUMS 64
98602 +#define QMI_DEF_TNUMS_THRESH 32
98603 +/* FPM defines */
98604 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
98605 +
98606 +/* DMA defines */
98607 +#define DMA_THRESH_MAX_COMMQ 83
98608 +#define DMA_THRESH_MAX_BUF 127
98609 +
98610 +/* BMI defines */
98611 +#define BMI_MAX_NUM_OF_TASKS 128
98612 +#define BMI_MAX_NUM_OF_DMAS 84
98613 +
98614 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
98615 +#define PORT_MAX_WEIGHT 16
98616 +
98617 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
98618 +
98619 +/* Unique T4240 */
98620 +#define FM_OP_OPEN_DMA_MIN_LIMIT
98621 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
98622 +#define FM_NO_OP_OBSERVED_POOLS
98623 +#define FM_FRAME_END_PARAMS_FOR_OP
98624 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
98625 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
98626 +
98627 +#define FM_NO_GUARANTEED_RESET_VALUES
98628 +
98629 +/* FM errata */
98630 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
98631 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
98632 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
98633 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
98634 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
98635 +
98636 +#define FM_BCB_ERRATA_BMI_SW001
98637 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
98638 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
98639 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
98640 +
98641 +/*****************************************************************************
98642 + RMan INTEGRATION-SPECIFIC DEFINITIONS
98643 +******************************************************************************/
98644 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
98645 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
98646 +
98647 +/* RMan erratas */
98648 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
98649 +
98650 +/*****************************************************************************
98651 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
98652 +******************************************************************************/
98653 +#define NUM_OF_RX_SC 16
98654 +#define NUM_OF_TX_SC 16
98655 +
98656 +#define NUM_OF_SA_PER_RX_SC 2
98657 +#define NUM_OF_SA_PER_TX_SC 2
98658 +
98659 +#endif /* __DPAA_INTEGRATION_EXT_H */
98660 --- /dev/null
98661 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
98662 @@ -0,0 +1,64 @@
98663 +/*
98664 + * Copyright 2012 Freescale Semiconductor Inc.
98665 + *
98666 + * Redistribution and use in source and binary forms, with or without
98667 + * modification, are permitted provided that the following conditions are met:
98668 + * * Redistributions of source code must retain the above copyright
98669 + * notice, this list of conditions and the following disclaimer.
98670 + * * Redistributions in binary form must reproduce the above copyright
98671 + * notice, this list of conditions and the following disclaimer in the
98672 + * documentation and/or other materials provided with the distribution.
98673 + * * Neither the name of Freescale Semiconductor nor the
98674 + * names of its contributors may be used to endorse or promote products
98675 + * derived from this software without specific prior written permission.
98676 + *
98677 + *
98678 + * ALTERNATIVELY, this software may be distributed under the terms of the
98679 + * GNU General Public License ("GPL") as published by the Free Software
98680 + * Foundation, either version 2 of that License or (at your option) any
98681 + * later version.
98682 + *
98683 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98684 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98685 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98686 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98687 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98688 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98689 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98690 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98691 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98692 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98693 + */
98694 +
98695 +/**************************************************************************//**
98696 +
98697 + @File part_ext.h
98698 +
98699 + @Description Definitions for the part (integration) module.
98700 +*//***************************************************************************/
98701 +
98702 +#ifndef __PART_EXT_H
98703 +#define __PART_EXT_H
98704 +
98705 +#include "std_ext.h"
98706 +#include "part_integration_ext.h"
98707 +
98708 +#if !(defined(LS1043))
98709 +#error "unable to proceed without chip-definition"
98710 +#endif
98711 +
98712 +
98713 +/**************************************************************************//*
98714 + @Description Part data structure - must be contained in any integration
98715 + data structure.
98716 +*//***************************************************************************/
98717 +typedef struct t_Part
98718 +{
98719 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
98720 + /**< Returns the address of the module's memory map base. */
98721 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
98722 + /**< Returns the module's ID according to its memory map base. */
98723 +} t_Part;
98724 +
98725 +
98726 +#endif /* __PART_EXT_H */
98727 --- /dev/null
98728 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
98729 @@ -0,0 +1,185 @@
98730 +/*
98731 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98732 + *
98733 + * Redistribution and use in source and binary forms, with or without
98734 + * modification, are permitted provided that the following conditions are met:
98735 + * * Redistributions of source code must retain the above copyright
98736 + * notice, this list of conditions and the following disclaimer.
98737 + * * Redistributions in binary form must reproduce the above copyright
98738 + * notice, this list of conditions and the following disclaimer in the
98739 + * documentation and/or other materials provided with the distribution.
98740 + * * Neither the name of Freescale Semiconductor nor the
98741 + * names of its contributors may be used to endorse or promote products
98742 + * derived from this software without specific prior written permission.
98743 + *
98744 + *
98745 + * ALTERNATIVELY, this software may be distributed under the terms of the
98746 + * GNU General Public License ("GPL") as published by the Free Software
98747 + * Foundation, either version 2 of that License or (at your option) any
98748 + * later version.
98749 + *
98750 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98751 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98752 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98753 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98754 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98755 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98756 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98757 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98758 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98759 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98760 + */
98761 +
98762 +/**
98763 +
98764 + @File part_integration_ext.h
98765 +
98766 + @Description T4240 external definitions and structures.
98767 +*//***************************************************************************/
98768 +#ifndef __PART_INTEGRATION_EXT_H
98769 +#define __PART_INTEGRATION_EXT_H
98770 +
98771 +#include "std_ext.h"
98772 +#include "ddr_std_ext.h"
98773 +#include "enet_ext.h"
98774 +#include "dpaa_integration_ext.h"
98775 +
98776 +
98777 +/**************************************************************************//**
98778 + @Group T4240_chip_id T4240 Application Programming Interface
98779 +
98780 + @Description T4240 Chip functions,definitions and enums.
98781 +
98782 + @{
98783 +*//***************************************************************************/
98784 +
98785 +#define INTG_MAX_NUM_OF_CORES 4
98786 +
98787 +/**************************************************************************//**
98788 + @Description Module types.
98789 +*//***************************************************************************/
98790 +typedef enum e_ModuleId
98791 +{
98792 + e_MODULE_ID_DUART_1 = 0,
98793 + e_MODULE_ID_DUART_2,
98794 + e_MODULE_ID_DUART_3,
98795 + e_MODULE_ID_DUART_4,
98796 + e_MODULE_ID_LAW,
98797 + e_MODULE_ID_IFC,
98798 + e_MODULE_ID_PAMU,
98799 + e_MODULE_ID_QM, /**< Queue manager module */
98800 + e_MODULE_ID_BM, /**< Buffer manager module */
98801 + e_MODULE_ID_QM_CE_PORTAL_0,
98802 + e_MODULE_ID_QM_CI_PORTAL_0,
98803 + e_MODULE_ID_QM_CE_PORTAL_1,
98804 + e_MODULE_ID_QM_CI_PORTAL_1,
98805 + e_MODULE_ID_QM_CE_PORTAL_2,
98806 + e_MODULE_ID_QM_CI_PORTAL_2,
98807 + e_MODULE_ID_QM_CE_PORTAL_3,
98808 + e_MODULE_ID_QM_CI_PORTAL_3,
98809 + e_MODULE_ID_QM_CE_PORTAL_4,
98810 + e_MODULE_ID_QM_CI_PORTAL_4,
98811 + e_MODULE_ID_QM_CE_PORTAL_5,
98812 + e_MODULE_ID_QM_CI_PORTAL_5,
98813 + e_MODULE_ID_QM_CE_PORTAL_6,
98814 + e_MODULE_ID_QM_CI_PORTAL_6,
98815 + e_MODULE_ID_QM_CE_PORTAL_7,
98816 + e_MODULE_ID_QM_CI_PORTAL_7,
98817 + e_MODULE_ID_QM_CE_PORTAL_8,
98818 + e_MODULE_ID_QM_CI_PORTAL_8,
98819 + e_MODULE_ID_QM_CE_PORTAL_9,
98820 + e_MODULE_ID_QM_CI_PORTAL_9,
98821 + e_MODULE_ID_BM_CE_PORTAL_0,
98822 + e_MODULE_ID_BM_CI_PORTAL_0,
98823 + e_MODULE_ID_BM_CE_PORTAL_1,
98824 + e_MODULE_ID_BM_CI_PORTAL_1,
98825 + e_MODULE_ID_BM_CE_PORTAL_2,
98826 + e_MODULE_ID_BM_CI_PORTAL_2,
98827 + e_MODULE_ID_BM_CE_PORTAL_3,
98828 + e_MODULE_ID_BM_CI_PORTAL_3,
98829 + e_MODULE_ID_BM_CE_PORTAL_4,
98830 + e_MODULE_ID_BM_CI_PORTAL_4,
98831 + e_MODULE_ID_BM_CE_PORTAL_5,
98832 + e_MODULE_ID_BM_CI_PORTAL_5,
98833 + e_MODULE_ID_BM_CE_PORTAL_6,
98834 + e_MODULE_ID_BM_CI_PORTAL_6,
98835 + e_MODULE_ID_BM_CE_PORTAL_7,
98836 + e_MODULE_ID_BM_CI_PORTAL_7,
98837 + e_MODULE_ID_BM_CE_PORTAL_8,
98838 + e_MODULE_ID_BM_CI_PORTAL_8,
98839 + e_MODULE_ID_BM_CE_PORTAL_9,
98840 + e_MODULE_ID_BM_CI_PORTAL_9,
98841 + e_MODULE_ID_FM, /**< Frame manager module */
98842 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
98843 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
98844 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
98845 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
98846 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
98847 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
98848 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
98849 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
98850 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
98851 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
98852 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
98853 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
98854 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
98855 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
98856 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
98857 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
98858 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
98859 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
98860 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
98861 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
98862 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
98863 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
98864 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
98865 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
98866 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
98867 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
98868 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
98869 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
98870 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
98871 + e_MODULE_ID_FM_KG, /**< FM Keygen */
98872 + e_MODULE_ID_FM_DMA, /**< FM DMA */
98873 + e_MODULE_ID_FM_FPM, /**< FM FPM */
98874 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
98875 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
98876 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
98877 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
98878 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
98879 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
98880 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
98881 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
98882 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
98883 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
98884 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
98885 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
98886 +
98887 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
98888 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
98889 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
98890 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
98891 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
98892 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
98893 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
98894 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
98895 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
98896 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
98897 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
98898 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
98899 +
98900 + e_MODULE_ID_PIC, /**< PIC */
98901 + e_MODULE_ID_GPIO, /**< GPIO */
98902 + e_MODULE_ID_SERDES, /**< SERDES */
98903 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
98904 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
98905 +
98906 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
98907 +
98908 + e_MODULE_ID_DUMMY_LAST
98909 +} e_ModuleId;
98910 +
98911 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
98912 +
98913 +
98914 +#endif /* __PART_INTEGRATION_EXT_H */
98915 --- /dev/null
98916 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
98917 @@ -0,0 +1,213 @@
98918 +/*
98919 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98920 + *
98921 + * Redistribution and use in source and binary forms, with or without
98922 + * modification, are permitted provided that the following conditions are met:
98923 + * * Redistributions of source code must retain the above copyright
98924 + * notice, this list of conditions and the following disclaimer.
98925 + * * Redistributions in binary form must reproduce the above copyright
98926 + * notice, this list of conditions and the following disclaimer in the
98927 + * documentation and/or other materials provided with the distribution.
98928 + * * Neither the name of Freescale Semiconductor nor the
98929 + * names of its contributors may be used to endorse or promote products
98930 + * derived from this software without specific prior written permission.
98931 + *
98932 + *
98933 + * ALTERNATIVELY, this software may be distributed under the terms of the
98934 + * GNU General Public License ("GPL") as published by the Free Software
98935 + * Foundation, either version 2 of that License or (at your option) any
98936 + * later version.
98937 + *
98938 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98939 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98940 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98941 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98942 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98943 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98944 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98945 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98946 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98947 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98948 + */
98949 +
98950 +
98951 +/**
98952 +
98953 + @File dpaa_integration_ext.h
98954 +
98955 + @Description P1023 FM external definitions and structures.
98956 +*//***************************************************************************/
98957 +#ifndef __DPAA_INTEGRATION_EXT_H
98958 +#define __DPAA_INTEGRATION_EXT_H
98959 +
98960 +#include "std_ext.h"
98961 +
98962 +
98963 +#define DPAA_VERSION 10
98964 +
98965 +typedef enum e_DpaaSwPortal {
98966 + e_DPAA_SWPORTAL0 = 0,
98967 + e_DPAA_SWPORTAL1,
98968 + e_DPAA_SWPORTAL2,
98969 + e_DPAA_SWPORTAL_DUMMY_LAST
98970 +} e_DpaaSwPortal;
98971 +
98972 +typedef enum {
98973 + e_DPAA_DCPORTAL0 = 0,
98974 + e_DPAA_DCPORTAL2,
98975 + e_DPAA_DCPORTAL_DUMMY_LAST
98976 +} e_DpaaDcPortal;
98977 +
98978 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98979 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98980 +
98981 +/*****************************************************************************
98982 + QMAN INTEGRATION-SPECIFIC DEFINITIONS
98983 +******************************************************************************/
98984 +#define QM_MAX_NUM_OF_POOL_CHANNELS 3
98985 +#define QM_MAX_NUM_OF_WQ 8
98986 +#define QM_MAX_NUM_OF_SWP_AS 2
98987 +#define QM_MAX_NUM_OF_CGS 64
98988 +#define QM_MAX_NUM_OF_FQIDS (16*MEGABYTE)
98989 +
98990 +typedef enum {
98991 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0,
98992 + e_QM_FQ_CHANNEL_SWPORTAL1,
98993 + e_QM_FQ_CHANNEL_SWPORTAL2,
98994 +
98995 + e_QM_FQ_CHANNEL_POOL1 = 0x21,
98996 + e_QM_FQ_CHANNEL_POOL2,
98997 + e_QM_FQ_CHANNEL_POOL3,
98998 +
98999 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40,
99000 + e_QM_FQ_CHANNEL_FMAN0_SP1,
99001 + e_QM_FQ_CHANNEL_FMAN0_SP2,
99002 + e_QM_FQ_CHANNEL_FMAN0_SP3,
99003 + e_QM_FQ_CHANNEL_FMAN0_SP4,
99004 + e_QM_FQ_CHANNEL_FMAN0_SP5,
99005 + e_QM_FQ_CHANNEL_FMAN0_SP6,
99006 +
99007 +
99008 + e_QM_FQ_CHANNEL_CAAM = 0x80
99009 +} e_QmFQChannel;
99010 +
99011 +/*****************************************************************************
99012 + BMAN INTEGRATION-SPECIFIC DEFINITIONS
99013 +******************************************************************************/
99014 +#define BM_MAX_NUM_OF_POOLS 8
99015 +
99016 +/*****************************************************************************
99017 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99018 +******************************************************************************/
99019 +#define SEC_NUM_OF_DECOS 2
99020 +#define SEC_ALL_DECOS_MASK 0x00000003
99021 +#define SEC_RNGB
99022 +#define SEC_NO_ESP_TRAILER_REMOVAL
99023 +
99024 +/*****************************************************************************
99025 + FM INTEGRATION-SPECIFIC DEFINITIONS
99026 +******************************************************************************/
99027 +#define INTG_MAX_NUM_OF_FM 1
99028 +
99029 +/* Ports defines */
99030 +#define FM_MAX_NUM_OF_1G_MACS 2
99031 +#define FM_MAX_NUM_OF_10G_MACS 0
99032 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
99033 +#define FM_MAX_NUM_OF_OH_PORTS 5
99034 +
99035 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
99036 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
99037 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
99038 +
99039 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
99040 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
99041 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
99042 +
99043 +#define FM_MAX_NUM_OF_MACSECS 1
99044 +
99045 +#define FM_MACSEC_SUPPORT
99046 +
99047 +#define FM_LOW_END_RESTRICTION /* prevents the use of TX port 1 with OP port 0 */
99048 +
99049 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
99050 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 2 /**< Number of Offline parsing port external BM pools per Rx port */
99051 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 32 /**< Total number of congestion groups in QM */
99052 +#define FM_MAX_NUM_OF_SUB_PORTALS 7
99053 +
99054 +/* Rams defines */
99055 +#define FM_MURAM_SIZE (64*KILOBYTE)
99056 +#define FM_IRAM_SIZE(major, minor) (32 * KILOBYTE)
99057 +#define FM_NUM_OF_CTRL 2
99058 +
99059 +/* PCD defines */
99060 +#define FM_PCD_PLCR_NUM_ENTRIES 32 /**< Total number of policer profiles */
99061 +#define FM_PCD_KG_NUM_OF_SCHEMES 16 /**< Total number of KG schemes */
99062 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 128 /**< Number of classification plan entries. */
99063 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000240 /**< 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
99068 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2
99069 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2
99070 +
99071 +/* QMI defines */
99072 +#define QMI_MAX_NUM_OF_TNUMS 15
99073 +
99074 +/* FPM defines */
99075 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
99076 +
99077 +/* DMA defines */
99078 +#define DMA_THRESH_MAX_COMMQ 15
99079 +#define DMA_THRESH_MAX_BUF 7
99080 +
99081 +/* BMI defines */
99082 +#define BMI_MAX_NUM_OF_TASKS 64
99083 +#define BMI_MAX_NUM_OF_DMAS 16
99084 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
99085 +#define PORT_MAX_WEIGHT 4
99086 +
99087 +/*****************************************************************************
99088 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
99089 +******************************************************************************/
99090 +#define NUM_OF_RX_SC 16
99091 +#define NUM_OF_TX_SC 16
99092 +
99093 +#define NUM_OF_SA_PER_RX_SC 2
99094 +#define NUM_OF_SA_PER_TX_SC 2
99095 +
99096 +/**************************************************************************//**
99097 + @Description Enum for inter-module interrupts registration
99098 +*//***************************************************************************/
99099 +
99100 +/* 1023 unique features */
99101 +#define FM_QMI_NO_ECC_EXCEPTIONS
99102 +#define FM_CSI_CFED_LIMIT
99103 +#define FM_PEDANTIC_DMA
99104 +#define FM_QMI_NO_DEQ_OPTIONS_SUPPORT
99105 +#define FM_FIFO_ALLOCATION_ALG
99106 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
99107 +#define FM_HAS_TOTAL_DMAS
99108 +#define FM_KG_NO_IPPID_SUPPORT
99109 +#define FM_NO_GUARANTEED_RESET_VALUES
99110 +#define FM_MAC_RESET
99111 +
99112 +/* FM erratas */
99113 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
99114 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
99115 +
99116 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
99117 +#define FM_INT_BUF_LEAK_FMAN_A005 /* No implementation, Out of LLD scope. App must avoid S/G */
99118 +
99119 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
99120 +
99121 +/* #define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
99122 +
99123 +/*
99124 +TKT056919 - axi12axi0 can hang if read request follows the single byte write on the very next cycle
99125 +TKT038900 - FM dma lockup occur due to AXI slave protocol violation
99126 +*/
99127 +#define FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
99128 +
99129 +
99130 +#endif /* __DPAA_INTEGRATION_EXT_H */
99131 --- /dev/null
99132 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
99133 @@ -0,0 +1,82 @@
99134 +/*
99135 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99136 + *
99137 + * Redistribution and use in source and binary forms, with or without
99138 + * modification, are permitted provided that the following conditions are met:
99139 + * * Redistributions of source code must retain the above copyright
99140 + * notice, this list of conditions and the following disclaimer.
99141 + * * Redistributions in binary form must reproduce the above copyright
99142 + * notice, this list of conditions and the following disclaimer in the
99143 + * documentation and/or other materials provided with the distribution.
99144 + * * Neither the name of Freescale Semiconductor nor the
99145 + * names of its contributors may be used to endorse or promote products
99146 + * derived from this software without specific prior written permission.
99147 + *
99148 + *
99149 + * ALTERNATIVELY, this software may be distributed under the terms of the
99150 + * GNU General Public License ("GPL") as published by the Free Software
99151 + * Foundation, either version 2 of that License or (at your option) any
99152 + * later version.
99153 + *
99154 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99155 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99156 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99157 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99158 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99159 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99160 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99161 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99162 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99163 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99164 + */
99165 +
99166 +
99167 +/**************************************************************************//**
99168 +
99169 + @File part_ext.h
99170 +
99171 + @Description Definitions for the part (integration) module.
99172 +*//***************************************************************************/
99173 +
99174 +#ifndef __PART_EXT_H
99175 +#define __PART_EXT_H
99176 +
99177 +#include "std_ext.h"
99178 +#include "part_integration_ext.h"
99179 +
99180 +
99181 +#if !(defined(MPC8306) || \
99182 + defined(MPC8309) || \
99183 + defined(MPC834x) || \
99184 + defined(MPC836x) || \
99185 + defined(MPC832x) || \
99186 + defined(MPC837x) || \
99187 + defined(MPC8568) || \
99188 + defined(MPC8569) || \
99189 + defined(P1020) || \
99190 + defined(P1021) || \
99191 + defined(P1022) || \
99192 + defined(P1023) || \
99193 + defined(P2020) || \
99194 + defined(P3041) || \
99195 + defined(P4080) || \
99196 + defined(P5020) || \
99197 + defined(MSC814x))
99198 +#error "unable to proceed without chip-definition"
99199 +#endif
99200 +
99201 +
99202 +/**************************************************************************//*
99203 + @Description Part data structure - must be contained in any integration
99204 + data structure.
99205 +*//***************************************************************************/
99206 +typedef struct t_Part
99207 +{
99208 + uint64_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
99209 + /**< Returns the address of the module's memory map base. */
99210 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uint64_t baseAddress);
99211 + /**< Returns the module's ID according to its memory map base. */
99212 +} t_Part;
99213 +
99214 +
99215 +#endif /* __PART_EXT_H */
99216 --- /dev/null
99217 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
99218 @@ -0,0 +1,635 @@
99219 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
99220 + * All rights reserved.
99221 + *
99222 + * Redistribution and use in source and binary forms, with or without
99223 + * modification, are permitted provided that the following conditions are met:
99224 + * * Redistributions of source code must retain the above copyright
99225 + * notice, this list of conditions and the following disclaimer.
99226 + * * Redistributions in binary form must reproduce the above copyright
99227 + * notice, this list of conditions and the following disclaimer in the
99228 + * documentation and/or other materials provided with the distribution.
99229 + * * Neither the name of Freescale Semiconductor nor the
99230 + * names of its contributors may be used to endorse or promote products
99231 + * derived from this software without specific prior written permission.
99232 + *
99233 + *
99234 + * ALTERNATIVELY, this software may be distributed under the terms of the
99235 + * GNU General Public License ("GPL") as published by the Free Software
99236 + * Foundation, either version 2 of that License or (at your option) any
99237 + * later version.
99238 + *
99239 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99240 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99241 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99242 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99243 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99244 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99245 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99246 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99247 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99248 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99249 + */
99250 +
99251 +/**************************************************************************//**
99252 + @File part_integration_ext.h
99253 +
99254 + @Description P1023 external definitions and structures.
99255 +*//***************************************************************************/
99256 +#ifndef __PART_INTEGRATION_EXT_H
99257 +#define __PART_INTEGRATION_EXT_H
99258 +
99259 +#include "std_ext.h"
99260 +#include "dpaa_integration_ext.h"
99261 +
99262 +
99263 +/**************************************************************************//**
99264 + @Group 1023_chip_id P1023 Application Programming Interface
99265 +
99266 + @Description P1023 Chip functions,definitions and enums.
99267 +
99268 + @{
99269 +*//***************************************************************************/
99270 +
99271 +#define INTG_MAX_NUM_OF_CORES 2
99272 +
99273 +
99274 +/**************************************************************************//**
99275 + @Description Module types.
99276 +*//***************************************************************************/
99277 +typedef enum e_ModuleId
99278 +{
99279 + e_MODULE_ID_LAW, /**< Local Access module */
99280 + e_MODULE_ID_ECM, /**< e500 Coherency Module */
99281 + e_MODULE_ID_DDR, /**< DDR memory controller */
99282 + e_MODULE_ID_I2C_1, /**< I2C 1 */
99283 + e_MODULE_ID_I2C_2, /**< I2C 1 */
99284 + e_MODULE_ID_DUART_1, /**< DUART module 1 */
99285 + e_MODULE_ID_DUART_2, /**< DUART module 2 */
99286 + e_MODULE_ID_LBC, /**< Local bus memory controller module */
99287 + e_MODULE_ID_PCIE_1, /**< PCI Express 1 controller module */
99288 + e_MODULE_ID_PCIE_ATMU_1, /**< PCI 1 ATMU Window */
99289 + e_MODULE_ID_PCIE_2, /**< PCI Express 2 controller module */
99290 + e_MODULE_ID_PCIE_ATMU_2, /**< PCI 2 ATMU Window */
99291 + e_MODULE_ID_PCIE_3, /**< PCI Express 3 controller module */
99292 + e_MODULE_ID_PCIE_ATMU_3, /**< PCI 3 ATMU Window */
99293 + e_MODULE_ID_MSI, /**< MSI registers */
99294 + e_MODULE_ID_L2_SRAM, /**< L2/SRAM Memory-Mapped controller module */
99295 + e_MODULE_ID_DMA_1, /**< DMA controller 1 */
99296 + e_MODULE_ID_DMA_2, /**< DMA controller 2 */
99297 + e_MODULE_ID_EPIC, /**< Programmable interrupt controller */
99298 + e_MODULE_ID_ESPI, /**< ESPI module */
99299 + e_MODULE_ID_GPIO, /**< General Purpose I/O */
99300 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99301 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99302 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99303 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99304 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99305 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99306 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99307 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99308 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99309 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99310 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99311 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99312 + e_MODULE_ID_USB_DR_1, /**< USB 2.0 module 1 */
99313 + e_MODULE_ID_USB_DR_2, /**< USB 2.0 module 2 */
99314 + e_MODULE_ID_ETSEC_MII_MNG, /**< MII MNG registers */
99315 + e_MODULE_ID_ETSEC_1, /**< ETSEC module 1 */
99316 + e_MODULE_ID_ETSEC_2, /**< ETSEC module 2 */
99317 + e_MODULE_ID_GUTS, /**< Serial DMA */
99318 + e_MODULE_ID_PM, /**< Performance Monitor module */
99319 + e_MODULE_ID_QM, /**< Queue manager module */
99320 + e_MODULE_ID_BM, /**< Buffer manager module */
99321 + e_MODULE_ID_QM_CE_PORTAL,
99322 + e_MODULE_ID_QM_CI_PORTAL,
99323 + e_MODULE_ID_BM_CE_PORTAL,
99324 + e_MODULE_ID_BM_CI_PORTAL,
99325 + e_MODULE_ID_FM, /**< Frame manager #1 module */
99326 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99327 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99328 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99329 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99330 + e_MODULE_ID_FM_PRS, /**< FM parser block */
99331 + e_MODULE_ID_FM_PORT_HO0, /**< FM Host-command/offline-parsing port block */
99332 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99333 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99334 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99335 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99336 + e_MODULE_ID_FM_PORT_1GRx0, /**< FM Rx 1G MAC port block */
99337 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99338 + e_MODULE_ID_FM_PORT_1GTx0, /**< FM Tx 1G MAC port block */
99339 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99340 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99341 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99342 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99343 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99344 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99345 + e_MODULE_ID_FM_1GMDIO0, /**< FM 1G MDIO MAC 0*/
99346 + e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/
99347 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99348 + e_MODULE_ID_FM_RISC0, /**< FM risc #0 */
99349 + e_MODULE_ID_FM_RISC1, /**< FM risc #1 */
99350 + e_MODULE_ID_FM_1GMAC0, /**< FM 1G MAC #0 */
99351 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99352 + e_MODULE_ID_FM_MACSEC, /**< FM MACSEC */
99353 +
99354 + e_MODULE_ID_DUMMY_LAST
99355 +} e_ModuleId;
99356 +
99357 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99358 +
99359 +
99360 +#define P1023_OFFSET_LAW 0x00000C08
99361 +#define P1023_OFFSET_ECM 0x00001000
99362 +#define P1023_OFFSET_DDR 0x00002000
99363 +#define P1023_OFFSET_I2C1 0x00003000
99364 +#define P1023_OFFSET_I2C2 0x00003100
99365 +#define P1023_OFFSET_DUART1 0x00004500
99366 +#define P1023_OFFSET_DUART2 0x00004600
99367 +#define P1023_OFFSET_LBC 0x00005000
99368 +#define P1023_OFFSET_ESPI 0x00007000
99369 +#define P1023_OFFSET_PCIE2 0x00009000
99370 +#define P1023_OFFSET_PCIE2_ATMU 0x00009C00
99371 +#define P1023_OFFSET_PCIE1 0x0000A000
99372 +#define P1023_OFFSET_PCIE1_ATMU 0x0000AC00
99373 +#define P1023_OFFSET_PCIE3 0x0000B000
99374 +#define P1023_OFFSET_PCIE3_ATMU 0x0000BC00
99375 +#define P1023_OFFSET_DMA2 0x0000C100
99376 +#define P1023_OFFSET_GPIO 0x0000F000
99377 +#define P1023_OFFSET_L2_SRAM 0x00020000
99378 +#define P1023_OFFSET_DMA1 0x00021100
99379 +#define P1023_OFFSET_USB1 0x00022000
99380 +#define P1023_OFFSET_SEC_GEN 0x00030000
99381 +#define P1023_OFFSET_SEC_JQ0 0x00031000
99382 +#define P1023_OFFSET_SEC_JQ1 0x00032000
99383 +#define P1023_OFFSET_SEC_JQ2 0x00033000
99384 +#define P1023_OFFSET_SEC_JQ3 0x00034000
99385 +#define P1023_OFFSET_SEC_RTIC 0x00036000
99386 +#define P1023_OFFSET_SEC_QI 0x00037000
99387 +#define P1023_OFFSET_SEC_DECO0_CCB0 0x00038000
99388 +#define P1023_OFFSET_SEC_DECO1_CCB1 0x00039000
99389 +#define P1023_OFFSET_SEC_DECO2_CCB2 0x0003a000
99390 +#define P1023_OFFSET_SEC_DECO3_CCB3 0x0003b000
99391 +#define P1023_OFFSET_SEC_DECO4_CCB4 0x0003c000
99392 +#define P1023_OFFSET_PIC 0x00040000
99393 +#define P1023_OFFSET_MSI 0x00041600
99394 +#define P1023_OFFSET_AXI 0x00081000
99395 +#define P1023_OFFSET_QM 0x00088000
99396 +#define P1023_OFFSET_BM 0x0008A000
99397 +#define P1022_OFFSET_PM 0x000E1000
99398 +
99399 +#define P1023_OFFSET_GUTIL 0x000E0000
99400 +#define P1023_OFFSET_PM 0x000E1000
99401 +#define P1023_OFFSET_DEBUG 0x000E2000
99402 +#define P1023_OFFSET_SERDES 0x000E3000
99403 +#define P1023_OFFSET_ROM 0x000F0000
99404 +#define P1023_OFFSET_FM 0x00100000
99405 +
99406 +#define P1023_OFFSET_FM_MURAM (P1023_OFFSET_FM + 0x00000000)
99407 +#define P1023_OFFSET_FM_BMI (P1023_OFFSET_FM + 0x00080000)
99408 +#define P1023_OFFSET_FM_QMI (P1023_OFFSET_FM + 0x00080400)
99409 +#define P1023_OFFSET_FM_PRS (P1023_OFFSET_FM + 0x00080800)
99410 +#define P1023_OFFSET_FM_PORT_HO0 (P1023_OFFSET_FM + 0x00081000)
99411 +#define P1023_OFFSET_FM_PORT_HO1 (P1023_OFFSET_FM + 0x00082000)
99412 +#define P1023_OFFSET_FM_PORT_HO2 (P1023_OFFSET_FM + 0x00083000)
99413 +#define P1023_OFFSET_FM_PORT_HO3 (P1023_OFFSET_FM + 0x00084000)
99414 +#define P1023_OFFSET_FM_PORT_HO4 (P1023_OFFSET_FM + 0x00085000)
99415 +#define P1023_OFFSET_FM_PORT_1GRX0 (P1023_OFFSET_FM + 0x00088000)
99416 +#define P1023_OFFSET_FM_PORT_1GRX1 (P1023_OFFSET_FM + 0x00089000)
99417 +#define P1023_OFFSET_FM_PORT_1GTX0 (P1023_OFFSET_FM + 0x000A8000)
99418 +#define P1023_OFFSET_FM_PORT_1GTX1 (P1023_OFFSET_FM + 0x000A9000)
99419 +#define P1023_OFFSET_FM_PLCR (P1023_OFFSET_FM + 0x000C0000)
99420 +#define P1023_OFFSET_FM_KG (P1023_OFFSET_FM + 0x000C1000)
99421 +#define P1023_OFFSET_FM_DMA (P1023_OFFSET_FM + 0x000C2000)
99422 +#define P1023_OFFSET_FM_FPM (P1023_OFFSET_FM + 0x000C3000)
99423 +#define P1023_OFFSET_FM_IRAM (P1023_OFFSET_FM + 0x000C4000)
99424 +#define P1023_OFFSET_FM_PRS_IRAM (P1023_OFFSET_FM + 0x000C7000)
99425 +#define P1023_OFFSET_FM_RISC0 (P1023_OFFSET_FM + 0x000D0000)
99426 +#define P1023_OFFSET_FM_RISC1 (P1023_OFFSET_FM + 0x000D0400)
99427 +#define P1023_OFFSET_FM_MACSEC (P1023_OFFSET_FM + 0x000D8000)
99428 +#define P1023_OFFSET_FM_1GMAC0 (P1023_OFFSET_FM + 0x000E0000)
99429 +#define P1023_OFFSET_FM_1GMDIO0 (P1023_OFFSET_FM + 0x000E1120)
99430 +#define P1023_OFFSET_FM_1GMAC1 (P1023_OFFSET_FM + 0x000E2000)
99431 +#define P1023_OFFSET_FM_1GMDIO1 (P1023_OFFSET_FM + 0x000E3000)
99432 +#define P1023_OFFSET_FM_RTC (P1023_OFFSET_FM + 0x000FE000)
99433 +
99434 +/* Offsets relative to QM or BM portals base */
99435 +#define P1023_OFFSET_PORTALS_CE_AREA 0x00000000 /* cache enabled area */
99436 +#define P1023_OFFSET_PORTALS_CI_AREA 0x00100000 /* cache inhibited area */
99437 +
99438 +#define P1023_OFFSET_PORTALS_CE(portal) (P1023_OFFSET_PORTALS_CE_AREA + 0x4000 * (portal))
99439 +#define P1023_OFFSET_PORTALS_CI(portal) (P1023_OFFSET_PORTALS_CI_AREA + 0x1000 * (portal))
99440 +
99441 +/**************************************************************************//**
99442 + @Description Transaction source ID (for memory controllers error reporting).
99443 +*//***************************************************************************/
99444 +typedef enum e_TransSrc
99445 +{
99446 + e_TRANS_SRC_PCIE_2 = 0x01, /**< PCIe port 2 */
99447 + e_TRANS_SRC_PCIE_1 = 0x02, /**< PCIe port 1 */
99448 + e_TRANS_SRC_PCIE_3 = 0x03, /**< PCIe port 3 */
99449 + e_TRANS_SRC_LBC = 0x04, /**< Enhanced local bus */
99450 + e_TRANS_SRC_DPAA_SW_PORTALS = 0x0E, /**< DPAA software portals or SRAM */
99451 + e_TRANS_SRC_DDR = 0x0F, /**< DDR controller */
99452 + e_TRANS_SRC_CORE_INS_FETCH = 0x10, /**< Processor (instruction) */
99453 + e_TRANS_SRC_CORE_DATA = 0x11, /**< Processor (data) */
99454 + e_TRANS_SRC_DMA = 0x15 /**< DMA */
99455 +} e_TransSrc;
99456 +
99457 +/**************************************************************************//**
99458 + @Description Local Access Window Target interface ID
99459 +*//***************************************************************************/
99460 +typedef enum e_P1023LawTargetId
99461 +{
99462 + e_P1023_LAW_TARGET_PCIE_2 = 0x01, /**< PCI Express 2 target interface */
99463 + e_P1023_LAW_TARGET_PCIE_1 = 0x02, /**< PCI Express 1 target interface */
99464 + e_P1023_LAW_TARGET_PCIE_3 = 0x03, /**< PCI Express 3 target interface */
99465 + e_P1023_LAW_TARGET_LBC = 0x04, /**< Local bus target interface */
99466 + e_P1023_LAW_TARGET_QM_PORTALS = 0x0E, /**< Queue Manager Portals */
99467 + e_P1023_LAW_TARGET_BM_PORTALS = 0x0E, /**< Buffer Manager Portals */
99468 + e_P1023_LAW_TARGET_SRAM = 0x0E, /**< SRAM scratchpad */
99469 + e_P1023_LAW_TARGET_DDR = 0x0F, /**< DDR target interface */
99470 + e_P1023_LAW_TARGET_NONE = 0xFF /**< Invalid target interface */
99471 +} e_P1023LawTargetId;
99472 +
99473 +
99474 +/**************************************************************************//**
99475 + @Group 1023_init_grp P1023 Initialization Unit
99476 +
99477 + @Description P1023 initialization unit API functions, definitions and enums
99478 +
99479 + @{
99480 +*//***************************************************************************/
99481 +
99482 +/**************************************************************************//**
99483 + @Description Part ID and revision number
99484 +*//***************************************************************************/
99485 +typedef enum e_P1023DeviceName
99486 +{
99487 + e_P1023_REV_INVALID = 0x00000000, /**< Invalid revision */
99488 + e_SC1023_REV_1_0 = (int)0x80FC0010, /**< SC1023 rev 1.0 */
99489 + e_SC1023_REV_1_1 = (int)0x80FC0011, /**< SC1023 rev 1.1 */
99490 + e_P1023_REV_1_0 = (int)0x80FE0010, /**< P1023 rev 1.0 with security */
99491 + e_P1023_REV_1_1 = (int)0x80FE0011, /**< P1023 rev 1.1 with security */
99492 + e_P1017_REV_1_1 = (int)0x80FF0011, /**< P1017 rev 1.1 with security */
99493 + e_P1023_REV_1_0_NO_SEC = (int)0x80F60010, /**< P1023 rev 1.0 without security */
99494 + e_P1023_REV_1_1_NO_SEC = (int)0x80F60011, /**< P1023 rev 1.1 without security */
99495 + e_P1017_REV_1_1_NO_SEC = (int)0x80F70011 /**< P1017 rev 1.1 without security */
99496 +} e_P1023DeviceName;
99497 +
99498 +/**************************************************************************//**
99499 + @Description structure representing P1023 initialization parameters
99500 +*//***************************************************************************/
99501 +typedef struct t_P1023Params
99502 +{
99503 + uintptr_t ccsrBaseAddress; /**< CCSR base address (virtual) */
99504 + uintptr_t bmPortalsBaseAddress; /**< Portals base address (virtual) */
99505 + uintptr_t qmPortalsBaseAddress; /**< Portals base address (virtual) */
99506 +} t_P1023Params;
99507 +
99508 +/**************************************************************************//**
99509 + @Function P1023_ConfigAndInit
99510 +
99511 + @Description General initiation of the chip registers.
99512 +
99513 + @Param[in] p_P1023Params - A pointer to data structure of parameters
99514 +
99515 + @Return A handle to the P1023 data structure.
99516 +*//***************************************************************************/
99517 +t_Handle P1023_ConfigAndInit(t_P1023Params *p_P1023Params);
99518 +
99519 +/**************************************************************************//**
99520 + @Function P1023_Free
99521 +
99522 + @Description Free all resources.
99523 +
99524 + @Param h_P1023 - (In) The handle of the initialized P1023 object.
99525 +
99526 + @Return E_OK on success; Other value otherwise.
99527 +*//***************************************************************************/
99528 +t_Error P1023_Free(t_Handle h_P1023);
99529 +
99530 +/**************************************************************************//**
99531 + @Function P1023_GetRevInfo
99532 +
99533 + @Description This routine enables access to chip and revision information.
99534 +
99535 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99536 +
99537 + @Return Part ID and revision.
99538 +*//***************************************************************************/
99539 +e_P1023DeviceName P1023_GetRevInfo(uintptr_t gutilBase);
99540 +
99541 +/**************************************************************************//**
99542 + @Function P1023_GetE500Factor
99543 +
99544 + @Description Returns E500 core clock multiplication factor.
99545 +
99546 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99547 + @Param[in] coreId - Id of the requested core.
99548 + @Param[out] p_E500MulFactor - Returns E500 to CCB multification factor.
99549 + @Param[out] p_E500DivFactor - Returns E500 to CCB division factor.
99550 +
99551 + @Return E_OK on success; Other value otherwise.
99552 +*
99553 +*//***************************************************************************/
99554 +t_Error P1023_GetE500Factor(uintptr_t gutilBase,
99555 + uint32_t coreId,
99556 + uint32_t *p_E500MulFactor,
99557 + uint32_t *p_E500DivFactor);
99558 +
99559 +/**************************************************************************//**
99560 + @Function P1023_GetFmFactor
99561 +
99562 + @Description returns FM multiplication factors. (This value is returned using
99563 + two parameters to avoid using float parameter).
99564 +
99565 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99566 + @Param[out] p_FmMulFactor - returns E500 to CCB multification factor.
99567 + @Param[out] p_FmDivFactor - returns E500 to CCB division factor.
99568 +
99569 + @Return E_OK on success; Other value otherwise.
99570 +*//***************************************************************************/
99571 +t_Error P1023_GetFmFactor(uintptr_t gutilBase, uint32_t *p_FmMulFactor, uint32_t *p_FmDivFactor);
99572 +
99573 +/**************************************************************************//**
99574 + @Function P1023_GetCcbFactor
99575 +
99576 + @Description returns system multiplication factor.
99577 +
99578 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99579 +
99580 + @Return System multiplication factor.
99581 +*//***************************************************************************/
99582 +uint32_t P1023_GetCcbFactor(uintptr_t gutilBase);
99583 +
99584 +#if 0
99585 +/**************************************************************************//**
99586 + @Function P1023_GetDdrFactor
99587 +
99588 + @Description returns the multiplication factor of the clock in for the DDR clock .
99589 + Note: assumes the ddr_in_clk is identical to the sys_in_clk
99590 +
99591 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99592 + @Param p_DdrMulFactor - returns DDR in clk multification factor.
99593 + @Param p_DdrDivFactor - returns DDR division factor.
99594 +
99595 + @Return E_OK on success; Other value otherwise..
99596 +*//***************************************************************************/
99597 +t_Error P1023_GetDdrFactor( uintptr_t gutilBase,
99598 + uint32_t *p_DdrMulFactor,
99599 + uint32_t *p_DdrDivFactor);
99600 +
99601 +/**************************************************************************//**
99602 + @Function P1023_GetDdrType
99603 +
99604 + @Description returns the multiplication factor of the clock in for the DDR clock .
99605 +
99606 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99607 + @Param p_DdrType - (Out) returns DDR type DDR1/DDR2/DDR3.
99608 +
99609 + @Return E_OK on success; Other value otherwise.
99610 +*//***************************************************************************/
99611 +t_Error P1023_GetDdrType(uintptr_t gutilBase, e_DdrType *p_DdrType );
99612 +#endif
99613 +
99614 +/** @} */ /* end of 1023_init_grp group */
99615 +/** @} */ /* end of 1023_grp group */
99616 +
99617 +#define CORE_E500V2
99618 +
99619 +#if 0 /* using unified values */
99620 +/*****************************************************************************
99621 + INTEGRATION-SPECIFIC MODULE CODES
99622 +******************************************************************************/
99623 +#define MODULE_UNKNOWN 0x00000000
99624 +#define MODULE_MEM 0x00010000
99625 +#define MODULE_MM 0x00020000
99626 +#define MODULE_CORE 0x00030000
99627 +#define MODULE_P1023 0x00040000
99628 +#define MODULE_MII 0x00050000
99629 +#define MODULE_PM 0x00060000
99630 +#define MODULE_MMU 0x00070000
99631 +#define MODULE_PIC 0x00080000
99632 +#define MODULE_L2_CACHE 0x00090000
99633 +#define MODULE_DUART 0x000a0000
99634 +#define MODULE_SERDES 0x000b0000
99635 +#define MODULE_PIO 0x000c0000
99636 +#define MODULE_QM 0x000d0000
99637 +#define MODULE_BM 0x000e0000
99638 +#define MODULE_SEC 0x000f0000
99639 +#define MODULE_FM 0x00100000
99640 +#define MODULE_FM_MURAM 0x00110000
99641 +#define MODULE_FM_PCD 0x00120000
99642 +#define MODULE_FM_RTC 0x00130000
99643 +#define MODULE_FM_MAC 0x00140000
99644 +#define MODULE_FM_PORT 0x00150000
99645 +#define MODULE_FM_MACSEC 0x00160000
99646 +#define MODULE_FM_MACSEC_SECY 0x00170000
99647 +#define MODULE_FM_SP 0x00280000
99648 +#define MODULE_ECM 0x00190000
99649 +#define MODULE_DMA 0x001a0000
99650 +#define MODULE_DDR 0x001b0000
99651 +#define MODULE_LAW 0x001c0000
99652 +#define MODULE_LBC 0x001d0000
99653 +#define MODULE_I2C 0x001e0000
99654 +#define MODULE_ESPI 0x001f0000
99655 +#define MODULE_PCI 0x00200000
99656 +#define MODULE_DPA_PORT 0x00210000
99657 +#define MODULE_USB 0x00220000
99658 +#endif /* using unified values */
99659 +
99660 +/*****************************************************************************
99661 + LBC INTEGRATION-SPECIFIC DEFINITIONS
99662 +******************************************************************************/
99663 +/**************************************************************************//**
99664 + @Group lbc_exception_grp LBC Exception Unit
99665 +
99666 + @Description LBC Exception unit API functions, definitions and enums
99667 +
99668 + @{
99669 +*//***************************************************************************/
99670 +
99671 +/**************************************************************************//**
99672 + @Anchor lbc_exbm
99673 +
99674 + @Collection LBC Errors Bit Mask
99675 +
99676 + These errors are reported through the exceptions callback..
99677 + The values can be or'ed in any combination in the errors mask
99678 + parameter of the errors report structure.
99679 +
99680 + These errors can also be passed as a bit-mask to
99681 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
99682 + for enabling or disabling error checking.
99683 + @{
99684 +*//***************************************************************************/
99685 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
99686 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
99687 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
99688 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
99689 +
99690 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
99691 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
99692 + /**< All possible errors */
99693 +/* @} */
99694 +/** @} */ /* end of lbc_exception_grp group */
99695 +
99696 +#define LBC_NUM_OF_BANKS 2
99697 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
99698 +#define LBC_ATOMIC_OPERATION_SUPPORT
99699 +#define LBC_PARITY_SUPPORT
99700 +#define LBC_ADDRESS_SHIFT_SUPPORT
99701 +#define LBC_ADDRESS_HOLD_TIME_CTRL
99702 +#define LBC_HIGH_CLK_DIVIDERS
99703 +#define LBC_FCM_AVAILABLE
99704 +
99705 +
99706 +/*****************************************************************************
99707 + LAW INTEGRATION-SPECIFIC DEFINITIONS
99708 +******************************************************************************/
99709 +#define LAW_ARCH_CCB
99710 +#define LAW_NUM_OF_WINDOWS 12
99711 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
99712 +#define LAW_MAX_WINDOW_SIZE 0x0000001000000000LL /**< 32GB */
99713 +
99714 +
99715 +/*****************************************************************************
99716 + SPI INTEGRATION-SPECIFIC DEFINITIONS
99717 +******************************************************************************/
99718 +#define SPI_NUM_OF_CONTROLLERS 1
99719 +
99720 +/*****************************************************************************
99721 + PCI/PCIe INTEGRATION-SPECIFIC DEFINITIONS
99722 +******************************************************************************/
99723 +
99724 +#define PCI_MAX_INBOUND_WINDOWS_NUM 4
99725 +#define PCI_MAX_OUTBOUND_WINDOWS_NUM 5
99726 +
99727 +/**************************************************************************//**
99728 + @Description Target interface of an inbound window
99729 +*//***************************************************************************/
99730 +typedef enum e_PciTargetInterface
99731 +{
99732 + e_PCI_TARGET_PCIE_2 = 0x1, /**< PCI Express target interface 2 */
99733 + e_PCI_TARGET_PCIE_1 = 0x2, /**< PCI Express target interface 1 */
99734 + e_PCI_TARGET_PCIE_3 = 0x3, /**< PCI Express target interface 3 */
99735 + e_PCI_TARGET_LOCAL_MEMORY = 0xF /**< Local Memory (DDR SDRAM, Local Bus, SRAM) target interface */
99736 +
99737 +} e_PciTargetInterface;
99738 +
99739 +/*****************************************************************************
99740 + DDR INTEGRATION-SPECIFIC DEFINITIONS
99741 +******************************************************************************/
99742 +#define DDR_NUM_OF_VALID_CS 2
99743 +
99744 +/*****************************************************************************
99745 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99746 +******************************************************************************/
99747 +#define SEC_ERRATA_STAT_REGS_UNUSABLE
99748 +
99749 +/*****************************************************************************
99750 + DMA INTEGRATION-SPECIFIC DEFINITIONS
99751 +******************************************************************************/
99752 +#define DMA_NUM_OF_CONTROLLERS 2
99753 +
99754 +
99755 +
99756 +
99757 +/*****************************************************************************
99758 + 1588 INTEGRATION-SPECIFIC DEFINITIONS
99759 +******************************************************************************/
99760 +#define PTP_V2
99761 +
99762 +/**************************************************************************//**
99763 + @Function P1023_GetMuxControlReg
99764 +
99765 + @Description Returns the value of PMUXCR (Alternate Function Signal Multiplex
99766 + Control Register)
99767 +
99768 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99769 +
99770 + @Return Value of PMUXCR
99771 +*//***************************************************************************/
99772 +uint32_t P1023_GetMuxControlReg(uintptr_t gutilBase);
99773 +
99774 +/**************************************************************************//**
99775 + @Function P1023_SetMuxControlReg
99776 +
99777 + @Description Sets the value of PMUXCR (Alternate Function Signal Multiplex
99778 + Control Register)
99779 +
99780 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99781 + @Param[in] val - the new value for PMUXCR.
99782 +
99783 + @Return None
99784 +*//***************************************************************************/
99785 +void P1023_SetMuxControlReg(uintptr_t gutilBase, uint32_t val);
99786 +
99787 +/**************************************************************************//**
99788 + @Function P1023_GetDeviceDisableStatusRegister
99789 +
99790 + @Description Returns the value of DEVDISR (Device Disable Register)
99791 +
99792 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99793 +
99794 + @Return Value of DEVDISR
99795 +*//***************************************************************************/
99796 +uint32_t P1023_GetDeviceDisableStatusRegister(uintptr_t gutilBase);
99797 +
99798 +/**************************************************************************//**
99799 + @Function P1023_GetPorDeviceStatusRegister
99800 +
99801 + @Description Returns the value of POR Device Status Register
99802 +
99803 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99804 +
99805 + @Return POR Device Status Register
99806 +*//***************************************************************************/
99807 +uint32_t P1023_GetPorDeviceStatusRegister(uintptr_t gutilBase);
99808 +
99809 +/**************************************************************************//**
99810 + @Function P1023_GetPorBootModeStatusRegister
99811 +
99812 + @Description Returns the value of POR Boot Mode Status Register
99813 +
99814 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99815 +
99816 + @Return POR Boot Mode Status Register value
99817 +*//***************************************************************************/
99818 +uint32_t P1023_GetPorBootModeStatusRegister(uintptr_t gutilBase);
99819 +
99820 +
99821 +#define PORDEVSR_SGMII1_DIS 0x10000000
99822 +#define PORDEVSR_SGMII2_DIS 0x08000000
99823 +#define PORDEVSR_ECP1 0x02000000
99824 +#define PORDEVSR_IO_SEL 0x00780000
99825 +#define PORDEVSR_IO_SEL_SHIFT 19
99826 +#define PORBMSR_HA 0x00070000
99827 +#define PORBMSR_HA_SHIFT 16
99828 +
99829 +#define DEVDISR_QM_BM 0x80000000
99830 +#define DEVDISR_FM 0x40000000
99831 +#define DEVDISR_PCIE1 0x20000000
99832 +#define DEVDISR_MAC_SEC 0x10000000
99833 +#define DEVDISR_ELBC 0x08000000
99834 +#define DEVDISR_PCIE2 0x04000000
99835 +#define DEVDISR_PCIE3 0x02000000
99836 +#define DEVDISR_CAAM 0x01000000
99837 +#define DEVDISR_USB0 0x00800000
99838 +#define DEVDISR_1588 0x00020000
99839 +#define DEVDISR_CORE0 0x00008000
99840 +#define DEVDISR_TB0 0x00004000
99841 +#define DEVDISR_CORE1 0x00002000
99842 +#define DEVDISR_TB1 0x00001000
99843 +#define DEVDISR_DMA1 0x00000400
99844 +#define DEVDISR_DMA2 0x00000200
99845 +#define DEVDISR_DDR 0x00000010
99846 +#define DEVDISR_TSEC1 0x00000080
99847 +#define DEVDISR_TSEC2 0x00000040
99848 +#define DEVDISR_SPI 0x00000008
99849 +#define DEVDISR_I2C 0x00000004
99850 +#define DEVDISR_DUART 0x00000002
99851 +
99852 +
99853 +#endif /* __PART_INTEGRATION_EXT_H */
99854 --- /dev/null
99855 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
99856 @@ -0,0 +1,276 @@
99857 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc
99858 + * All rights reserved.
99859 + *
99860 + * Redistribution and use in source and binary forms, with or without
99861 + * modification, are permitted provided that the following conditions are met:
99862 + * * Redistributions of source code must retain the above copyright
99863 + * notice, this list of conditions and the following disclaimer.
99864 + * * Redistributions in binary form must reproduce the above copyright
99865 + * notice, this list of conditions and the following disclaimer in the
99866 + * documentation and/or other materials provided with the distribution.
99867 + * * Neither the name of Freescale Semiconductor nor the
99868 + * names of its contributors may be used to endorse or promote products
99869 + * derived from this software without specific prior written permission.
99870 + *
99871 + *
99872 + * ALTERNATIVELY, this software may be distributed under the terms of the
99873 + * GNU General Public License ("GPL") as published by the Free Software
99874 + * Foundation, either version 2 of that License or (at your option) any
99875 + * later version.
99876 + *
99877 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99878 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99879 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99880 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99881 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99882 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99883 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99884 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99885 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99886 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99887 + */
99888 +
99889 +/**************************************************************************//**
99890 + @File dpaa_integration_ext.h
99891 +
99892 + @Description P3040/P4080/P5020 FM external definitions and structures.
99893 +*//***************************************************************************/
99894 +#ifndef __DPAA_INTEGRATION_EXT_H
99895 +#define __DPAA_INTEGRATION_EXT_H
99896 +
99897 +#include "std_ext.h"
99898 +
99899 +
99900 +#define DPAA_VERSION 10
99901 +
99902 +typedef enum {
99903 + e_DPAA_SWPORTAL0 = 0,
99904 + e_DPAA_SWPORTAL1,
99905 + e_DPAA_SWPORTAL2,
99906 + e_DPAA_SWPORTAL3,
99907 + e_DPAA_SWPORTAL4,
99908 + e_DPAA_SWPORTAL5,
99909 + e_DPAA_SWPORTAL6,
99910 + e_DPAA_SWPORTAL7,
99911 + e_DPAA_SWPORTAL8,
99912 + e_DPAA_SWPORTAL9,
99913 + e_DPAA_SWPORTAL_DUMMY_LAST
99914 +} e_DpaaSwPortal;
99915 +
99916 +typedef enum {
99917 + e_DPAA_DCPORTAL0 = 0,
99918 + e_DPAA_DCPORTAL1,
99919 + e_DPAA_DCPORTAL2,
99920 + e_DPAA_DCPORTAL3,
99921 + e_DPAA_DCPORTAL4,
99922 + e_DPAA_DCPORTAL_DUMMY_LAST
99923 +} e_DpaaDcPortal;
99924 +
99925 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
99926 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
99927 +
99928 +/*****************************************************************************
99929 + QMan INTEGRATION-SPECIFIC DEFINITIONS
99930 +******************************************************************************/
99931 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
99932 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
99933 +#define QM_MAX_NUM_OF_SWP_AS 4
99934 +#define QM_MAX_NUM_OF_CGS 256 /**< Number of congestion groups */
99935 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) /**< FQIDs range - 24 bits */
99936 +
99937 +/**************************************************************************//**
99938 + @Description Work Queue Channel assignments in QMan.
99939 +*//***************************************************************************/
99940 +typedef enum
99941 +{
99942 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */
99943 + e_QM_FQ_CHANNEL_SWPORTAL1,
99944 + e_QM_FQ_CHANNEL_SWPORTAL2,
99945 + e_QM_FQ_CHANNEL_SWPORTAL3,
99946 + e_QM_FQ_CHANNEL_SWPORTAL4,
99947 + e_QM_FQ_CHANNEL_SWPORTAL5,
99948 + e_QM_FQ_CHANNEL_SWPORTAL6,
99949 + e_QM_FQ_CHANNEL_SWPORTAL7,
99950 + e_QM_FQ_CHANNEL_SWPORTAL8,
99951 + e_QM_FQ_CHANNEL_SWPORTAL9,
99952 +
99953 + e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */
99954 + e_QM_FQ_CHANNEL_POOL2,
99955 + e_QM_FQ_CHANNEL_POOL3,
99956 + e_QM_FQ_CHANNEL_POOL4,
99957 + e_QM_FQ_CHANNEL_POOL5,
99958 + e_QM_FQ_CHANNEL_POOL6,
99959 + e_QM_FQ_CHANNEL_POOL7,
99960 + e_QM_FQ_CHANNEL_POOL8,
99961 + e_QM_FQ_CHANNEL_POOL9,
99962 + e_QM_FQ_CHANNEL_POOL10,
99963 + e_QM_FQ_CHANNEL_POOL11,
99964 + e_QM_FQ_CHANNEL_POOL12,
99965 + e_QM_FQ_CHANNEL_POOL13,
99966 + e_QM_FQ_CHANNEL_POOL14,
99967 + e_QM_FQ_CHANNEL_POOL15,
99968 +
99969 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0:
99970 + connected to FMan 0; assigned in incrementing order to
99971 + each sub-portal (SP) in the portal */
99972 + e_QM_FQ_CHANNEL_FMAN0_SP1,
99973 + e_QM_FQ_CHANNEL_FMAN0_SP2,
99974 + e_QM_FQ_CHANNEL_FMAN0_SP3,
99975 + e_QM_FQ_CHANNEL_FMAN0_SP4,
99976 + e_QM_FQ_CHANNEL_FMAN0_SP5,
99977 + e_QM_FQ_CHANNEL_FMAN0_SP6,
99978 + e_QM_FQ_CHANNEL_FMAN0_SP7,
99979 + e_QM_FQ_CHANNEL_FMAN0_SP8,
99980 + e_QM_FQ_CHANNEL_FMAN0_SP9,
99981 + e_QM_FQ_CHANNEL_FMAN0_SP10,
99982 + e_QM_FQ_CHANNEL_FMAN0_SP11,
99983 +/* difference between 5020 and 4080 :) */
99984 + e_QM_FQ_CHANNEL_FMAN1_SP0 = 0x60,
99985 + e_QM_FQ_CHANNEL_FMAN1_SP1,
99986 + e_QM_FQ_CHANNEL_FMAN1_SP2,
99987 + e_QM_FQ_CHANNEL_FMAN1_SP3,
99988 + e_QM_FQ_CHANNEL_FMAN1_SP4,
99989 + e_QM_FQ_CHANNEL_FMAN1_SP5,
99990 + e_QM_FQ_CHANNEL_FMAN1_SP6,
99991 + e_QM_FQ_CHANNEL_FMAN1_SP7,
99992 + e_QM_FQ_CHANNEL_FMAN1_SP8,
99993 + e_QM_FQ_CHANNEL_FMAN1_SP9,
99994 + e_QM_FQ_CHANNEL_FMAN1_SP10,
99995 + e_QM_FQ_CHANNEL_FMAN1_SP11,
99996 +
99997 + e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2:
99998 + connected to SEC 4.x */
99999 +
100000 + e_QM_FQ_CHANNEL_PME = 0xA0, /**< Dedicated channel serviced by Direct Connect Portal 3:
100001 + connected to PME */
100002 + e_QM_FQ_CHANNEL_RAID = 0xC0 /**< Dedicated channel serviced by Direct Connect Portal 4:
100003 + connected to RAID */
100004 +} e_QmFQChannel;
100005 +
100006 +/*****************************************************************************
100007 + BMan INTEGRATION-SPECIFIC DEFINITIONS
100008 +******************************************************************************/
100009 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
100010 +
100011 +
100012 +/*****************************************************************************
100013 + FM INTEGRATION-SPECIFIC DEFINITIONS
100014 +******************************************************************************/
100015 +#define INTG_MAX_NUM_OF_FM 2
100016 +
100017 +/* Ports defines */
100018 +#define FM_MAX_NUM_OF_1G_MACS 5
100019 +#define FM_MAX_NUM_OF_10G_MACS 1
100020 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
100021 +#define FM_MAX_NUM_OF_OH_PORTS 7
100022 +
100023 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
100024 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
100025 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
100026 +
100027 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
100028 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
100029 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
100030 +
100031 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */
100032 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
100033 +#define FM_MAX_NUM_OF_SUB_PORTALS 12
100034 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
100035 +
100036 +/* Rams defines */
100037 +#define FM_MURAM_SIZE (160*KILOBYTE)
100038 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
100039 +#define FM_NUM_OF_CTRL 2
100040 +
100041 +/* PCD defines */
100042 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
100043 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
100044 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
100045 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */
100046 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
100047 +
100048 +/* RTC defines */
100049 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
100050 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */
100051 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
100052 +
100053 +/* QMI defines */
100054 +#define QMI_MAX_NUM_OF_TNUMS 64
100055 +#define QMI_DEF_TNUMS_THRESH 48
100056 +
100057 +/* FPM defines */
100058 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
100059 +
100060 +/* DMA defines */
100061 +#define DMA_THRESH_MAX_COMMQ 31
100062 +#define DMA_THRESH_MAX_BUF 127
100063 +
100064 +/* BMI defines */
100065 +#define BMI_MAX_NUM_OF_TASKS 128
100066 +#define BMI_MAX_NUM_OF_DMAS 32
100067 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
100068 +#define PORT_MAX_WEIGHT 16
100069 +
100070 +
100071 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
100072 +
100073 +/* p4080-rev1 unique features */
100074 +#define QM_CGS_NO_FRAME_MODE
100075 +
100076 +/* p4080 unique features */
100077 +#define FM_NO_DISPATCH_RAM_ECC
100078 +#define FM_NO_WATCHDOG
100079 +#define FM_NO_TNUM_AGING
100080 +#define FM_KG_NO_BYPASS_FQID_GEN
100081 +#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
100082 +#define FM_NO_BACKUP_POOLS
100083 +#define FM_NO_OP_OBSERVED_POOLS
100084 +#define FM_NO_ADVANCED_RATE_LIMITER
100085 +#define FM_NO_OP_OBSERVED_CGS
100086 +#define FM_HAS_TOTAL_DMAS
100087 +#define FM_KG_NO_IPPID_SUPPORT
100088 +#define FM_NO_GUARANTEED_RESET_VALUES
100089 +#define FM_MAC_RESET
100090 +
100091 +/* FM erratas */
100092 +#define FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
100093 +#define FM_TX_SHORT_FRAME_BAD_TS_ERRATA_10GMAC_A006 /* No implementation, Out of LLD scope */
100094 +#define FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
100095 +#define FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
100096 +#define FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 /* Out of LLD scope, user may disable ECC exceptions using FM_DisableRamsEcc */
100097 +#define FM_BAD_VLAN_DETECT_ERRATA_10GMAC_A010
100098 +
100099 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
100100 +#define FM_GRS_ERRATA_DTSEC_A002
100101 +#define FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
100102 +#define FM_GTS_ERRATA_DTSEC_A004
100103 +#define FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012
100104 +#define FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
100105 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
100106 +
100107 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
100108 +#define FM_TX_LOCKUP_ERRATA_DTSEC6
100109 +
100110 +#define FM_HC_DEF_FQID_ONLY_ERRATA_FMAN_A003 /* Implemented by ucode */
100111 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
100112 +
100113 +#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
100114 +
100115 +#define FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
100116 +
100117 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
100118 +
100119 +#define FM_NO_CTXA_COPY_ERRATA_FMAN_SW001
100120 +#define FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
100121 +
100122 +/*****************************************************************************
100123 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
100124 +******************************************************************************/
100125 +#define NUM_OF_RX_SC 16
100126 +#define NUM_OF_TX_SC 16
100127 +
100128 +#define NUM_OF_SA_PER_RX_SC 2
100129 +#define NUM_OF_SA_PER_TX_SC 2
100130 +
100131 +
100132 +#endif /* __DPAA_INTEGRATION_EXT_H */
100133 --- /dev/null
100134 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
100135 @@ -0,0 +1,83 @@
100136 +/*
100137 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100138 + *
100139 + * Redistribution and use in source and binary forms, with or without
100140 + * modification, are permitted provided that the following conditions are met:
100141 + * * Redistributions of source code must retain the above copyright
100142 + * notice, this list of conditions and the following disclaimer.
100143 + * * Redistributions in binary form must reproduce the above copyright
100144 + * notice, this list of conditions and the following disclaimer in the
100145 + * documentation and/or other materials provided with the distribution.
100146 + * * Neither the name of Freescale Semiconductor nor the
100147 + * names of its contributors may be used to endorse or promote products
100148 + * derived from this software without specific prior written permission.
100149 + *
100150 + *
100151 + * ALTERNATIVELY, this software may be distributed under the terms of the
100152 + * GNU General Public License ("GPL") as published by the Free Software
100153 + * Foundation, either version 2 of that License or (at your option) any
100154 + * later version.
100155 + *
100156 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100157 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100158 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100159 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100160 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100161 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100162 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100163 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100164 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100165 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100166 + */
100167 +
100168 +/**************************************************************************//**
100169 +
100170 + @File part_ext.h
100171 +
100172 + @Description Definitions for the part (integration) module.
100173 +*//***************************************************************************/
100174 +
100175 +#ifndef __PART_EXT_H
100176 +#define __PART_EXT_H
100177 +
100178 +#include "std_ext.h"
100179 +#include "part_integration_ext.h"
100180 +
100181 +
100182 +#if !(defined(MPC8306) || \
100183 + defined(MPC8309) || \
100184 + defined(MPC834x) || \
100185 + defined(MPC836x) || \
100186 + defined(MPC832x) || \
100187 + defined(MPC837x) || \
100188 + defined(MPC8568) || \
100189 + defined(MPC8569) || \
100190 + defined(P1020) || \
100191 + defined(P1021) || \
100192 + defined(P1022) || \
100193 + defined(P1023) || \
100194 + defined(P2020) || \
100195 + defined(P2040) || \
100196 + defined(P3041) || \
100197 + defined(P4080) || \
100198 + defined(SC4080) || \
100199 + defined(P5020) || \
100200 + defined(MSC814x))
100201 +#error "unable to proceed without chip-definition"
100202 +#endif /* !(defined(MPC834x) || ... */
100203 +
100204 +
100205 +/**************************************************************************//*
100206 + @Description Part data structure - must be contained in any integration
100207 + data structure.
100208 +*//***************************************************************************/
100209 +typedef struct t_Part
100210 +{
100211 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
100212 + /**< Returns the address of the module's memory map base. */
100213 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
100214 + /**< Returns the module's ID according to its memory map base. */
100215 +} t_Part;
100216 +
100217 +
100218 +#endif /* __PART_EXT_H */
100219 --- /dev/null
100220 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
100221 @@ -0,0 +1,336 @@
100222 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
100223 + * All rights reserved.
100224 + *
100225 + * Redistribution and use in source and binary forms, with or without
100226 + * modification, are permitted provided that the following conditions are met:
100227 + * * Redistributions of source code must retain the above copyright
100228 + * notice, this list of conditions and the following disclaimer.
100229 + * * Redistributions in binary form must reproduce the above copyright
100230 + * notice, this list of conditions and the following disclaimer in the
100231 + * documentation and/or other materials provided with the distribution.
100232 + * * Neither the name of Freescale Semiconductor nor the
100233 + * names of its contributors may be used to endorse or promote products
100234 + * derived from this software without specific prior written permission.
100235 + *
100236 + *
100237 + * ALTERNATIVELY, this software may be distributed under the terms of the
100238 + * GNU General Public License ("GPL") as published by the Free Software
100239 + * Foundation, either version 2 of that License or (at your option) any
100240 + * later version.
100241 + *
100242 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100243 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100244 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100245 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100246 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100247 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100248 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100249 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100250 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100251 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100252 + */
100253 +
100254 +/**************************************************************************//**
100255 + @File part_integration_ext.h
100256 +
100257 + @Description P3040/P4080/P5020 external definitions and structures.
100258 +*//***************************************************************************/
100259 +#ifndef __PART_INTEGRATION_EXT_H
100260 +#define __PART_INTEGRATION_EXT_H
100261 +
100262 +#include "std_ext.h"
100263 +#include "dpaa_integration_ext.h"
100264 +
100265 +
100266 +/**************************************************************************//**
100267 + @Group P3040/P4080/P5020_chip_id P5020 Application Programming Interface
100268 +
100269 + @Description P3040/P4080/P5020 Chip functions,definitions and enums.
100270 +
100271 + @{
100272 +*//***************************************************************************/
100273 +
100274 +#define CORE_E500MC
100275 +
100276 +#define INTG_MAX_NUM_OF_CORES 1
100277 +
100278 +
100279 +/**************************************************************************//**
100280 + @Description Module types.
100281 +*//***************************************************************************/
100282 +typedef enum e_ModuleId
100283 +{
100284 + e_MODULE_ID_DUART_1 = 0,
100285 + e_MODULE_ID_DUART_2,
100286 + e_MODULE_ID_DUART_3,
100287 + e_MODULE_ID_DUART_4,
100288 + e_MODULE_ID_LAW,
100289 + e_MODULE_ID_LBC,
100290 + e_MODULE_ID_PAMU,
100291 + e_MODULE_ID_QM, /**< Queue manager module */
100292 + e_MODULE_ID_BM, /**< Buffer manager module */
100293 + e_MODULE_ID_QM_CE_PORTAL_0,
100294 + e_MODULE_ID_QM_CI_PORTAL_0,
100295 + e_MODULE_ID_QM_CE_PORTAL_1,
100296 + e_MODULE_ID_QM_CI_PORTAL_1,
100297 + e_MODULE_ID_QM_CE_PORTAL_2,
100298 + e_MODULE_ID_QM_CI_PORTAL_2,
100299 + e_MODULE_ID_QM_CE_PORTAL_3,
100300 + e_MODULE_ID_QM_CI_PORTAL_3,
100301 + e_MODULE_ID_QM_CE_PORTAL_4,
100302 + e_MODULE_ID_QM_CI_PORTAL_4,
100303 + e_MODULE_ID_QM_CE_PORTAL_5,
100304 + e_MODULE_ID_QM_CI_PORTAL_5,
100305 + e_MODULE_ID_QM_CE_PORTAL_6,
100306 + e_MODULE_ID_QM_CI_PORTAL_6,
100307 + e_MODULE_ID_QM_CE_PORTAL_7,
100308 + e_MODULE_ID_QM_CI_PORTAL_7,
100309 + e_MODULE_ID_QM_CE_PORTAL_8,
100310 + e_MODULE_ID_QM_CI_PORTAL_8,
100311 + e_MODULE_ID_QM_CE_PORTAL_9,
100312 + e_MODULE_ID_QM_CI_PORTAL_9,
100313 + e_MODULE_ID_BM_CE_PORTAL_0,
100314 + e_MODULE_ID_BM_CI_PORTAL_0,
100315 + e_MODULE_ID_BM_CE_PORTAL_1,
100316 + e_MODULE_ID_BM_CI_PORTAL_1,
100317 + e_MODULE_ID_BM_CE_PORTAL_2,
100318 + e_MODULE_ID_BM_CI_PORTAL_2,
100319 + e_MODULE_ID_BM_CE_PORTAL_3,
100320 + e_MODULE_ID_BM_CI_PORTAL_3,
100321 + e_MODULE_ID_BM_CE_PORTAL_4,
100322 + e_MODULE_ID_BM_CI_PORTAL_4,
100323 + e_MODULE_ID_BM_CE_PORTAL_5,
100324 + e_MODULE_ID_BM_CI_PORTAL_5,
100325 + e_MODULE_ID_BM_CE_PORTAL_6,
100326 + e_MODULE_ID_BM_CI_PORTAL_6,
100327 + e_MODULE_ID_BM_CE_PORTAL_7,
100328 + e_MODULE_ID_BM_CI_PORTAL_7,
100329 + e_MODULE_ID_BM_CE_PORTAL_8,
100330 + e_MODULE_ID_BM_CI_PORTAL_8,
100331 + e_MODULE_ID_BM_CE_PORTAL_9,
100332 + e_MODULE_ID_BM_CI_PORTAL_9,
100333 + e_MODULE_ID_FM1, /**< Frame manager #1 module */
100334 + e_MODULE_ID_FM1_RTC, /**< FM Real-Time-Clock */
100335 + e_MODULE_ID_FM1_MURAM, /**< FM Multi-User-RAM */
100336 + e_MODULE_ID_FM1_BMI, /**< FM BMI block */
100337 + e_MODULE_ID_FM1_QMI, /**< FM QMI block */
100338 + e_MODULE_ID_FM1_PRS, /**< FM parser block */
100339 + e_MODULE_ID_FM1_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100340 + e_MODULE_ID_FM1_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100341 + e_MODULE_ID_FM1_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100342 + e_MODULE_ID_FM1_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100343 + e_MODULE_ID_FM1_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100344 + e_MODULE_ID_FM1_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100345 + e_MODULE_ID_FM1_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100346 + e_MODULE_ID_FM1_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100347 + e_MODULE_ID_FM1_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100348 + e_MODULE_ID_FM1_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100349 + e_MODULE_ID_FM1_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100350 + e_MODULE_ID_FM1_PORT_1GRx4, /**< FM Rx 1G MAC port block */
100351 + e_MODULE_ID_FM1_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100352 + e_MODULE_ID_FM1_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100353 + e_MODULE_ID_FM1_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100354 + e_MODULE_ID_FM1_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100355 + e_MODULE_ID_FM1_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100356 + e_MODULE_ID_FM1_PORT_1GTx4, /**< FM Tx 1G MAC port block */
100357 + e_MODULE_ID_FM1_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100358 + e_MODULE_ID_FM1_PLCR, /**< FM Policer */
100359 + e_MODULE_ID_FM1_KG, /**< FM Keygen */
100360 + e_MODULE_ID_FM1_DMA, /**< FM DMA */
100361 + e_MODULE_ID_FM1_FPM, /**< FM FPM */
100362 + e_MODULE_ID_FM1_IRAM, /**< FM Instruction-RAM */
100363 + e_MODULE_ID_FM1_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100364 + e_MODULE_ID_FM1_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100365 + e_MODULE_ID_FM1_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100366 + e_MODULE_ID_FM1_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100367 + e_MODULE_ID_FM1_10GMDIO, /**< FM 10G MDIO */
100368 + e_MODULE_ID_FM1_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100369 + e_MODULE_ID_FM1_1GMAC0, /**< FM 1G MAC #0 */
100370 + e_MODULE_ID_FM1_1GMAC1, /**< FM 1G MAC #1 */
100371 + e_MODULE_ID_FM1_1GMAC2, /**< FM 1G MAC #2 */
100372 + e_MODULE_ID_FM1_1GMAC3, /**< FM 1G MAC #3 */
100373 + e_MODULE_ID_FM1_10GMAC0, /**< FM 10G MAC #0 */
100374 +
100375 + e_MODULE_ID_FM2, /**< Frame manager #2 module */
100376 + e_MODULE_ID_FM2_RTC, /**< FM Real-Time-Clock */
100377 + e_MODULE_ID_FM2_MURAM, /**< FM Multi-User-RAM */
100378 + e_MODULE_ID_FM2_BMI, /**< FM BMI block */
100379 + e_MODULE_ID_FM2_QMI, /**< FM QMI block */
100380 + e_MODULE_ID_FM2_PRS, /**< FM parser block */
100381 + e_MODULE_ID_FM2_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100382 + e_MODULE_ID_FM2_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100383 + e_MODULE_ID_FM2_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100384 + e_MODULE_ID_FM2_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100385 + e_MODULE_ID_FM2_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100386 + e_MODULE_ID_FM2_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100387 + e_MODULE_ID_FM2_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100388 + e_MODULE_ID_FM2_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100389 + e_MODULE_ID_FM2_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100390 + e_MODULE_ID_FM2_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100391 + e_MODULE_ID_FM2_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100392 + e_MODULE_ID_FM2_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100393 + e_MODULE_ID_FM2_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100394 + e_MODULE_ID_FM2_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100395 + e_MODULE_ID_FM2_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100396 + e_MODULE_ID_FM2_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100397 + e_MODULE_ID_FM2_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100398 + e_MODULE_ID_FM2_PLCR, /**< FM Policer */
100399 + e_MODULE_ID_FM2_KG, /**< FM Keygen */
100400 + e_MODULE_ID_FM2_DMA, /**< FM DMA */
100401 + e_MODULE_ID_FM2_FPM, /**< FM FPM */
100402 + e_MODULE_ID_FM2_IRAM, /**< FM Instruction-RAM */
100403 + e_MODULE_ID_FM2_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100404 + e_MODULE_ID_FM2_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100405 + e_MODULE_ID_FM2_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100406 + e_MODULE_ID_FM2_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100407 + e_MODULE_ID_FM2_10GMDIO, /**< FM 10G MDIO */
100408 + e_MODULE_ID_FM2_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100409 + e_MODULE_ID_FM2_1GMAC0, /**< FM 1G MAC #0 */
100410 + e_MODULE_ID_FM2_1GMAC1, /**< FM 1G MAC #1 */
100411 + e_MODULE_ID_FM2_1GMAC2, /**< FM 1G MAC #2 */
100412 + e_MODULE_ID_FM2_1GMAC3, /**< FM 1G MAC #3 */
100413 + e_MODULE_ID_FM2_10GMAC0, /**< FM 10G MAC #0 */
100414 +
100415 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
100416 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
100417 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
100418 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
100419 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
100420 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
100421 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
100422 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
100423 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
100424 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
100425 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
100426 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
100427 +
100428 + e_MODULE_ID_MPIC, /**< MPIC */
100429 + e_MODULE_ID_GPIO, /**< GPIO */
100430 + e_MODULE_ID_SERDES, /**< SERDES */
100431 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
100432 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
100433 +
100434 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
100435 + e_MODULE_ID_SRIO_MU, /**< RapidIO messaging unit module */
100436 +
100437 + e_MODULE_ID_DUMMY_LAST
100438 +} e_ModuleId;
100439 +
100440 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
100441 +
100442 +#if 0 /* using unified values */
100443 +/*****************************************************************************
100444 + INTEGRATION-SPECIFIC MODULE CODES
100445 +******************************************************************************/
100446 +#define MODULE_UNKNOWN 0x00000000
100447 +#define MODULE_MEM 0x00010000
100448 +#define MODULE_MM 0x00020000
100449 +#define MODULE_CORE 0x00030000
100450 +#define MODULE_CHIP 0x00040000
100451 +#define MODULE_PLTFRM 0x00050000
100452 +#define MODULE_PM 0x00060000
100453 +#define MODULE_MMU 0x00070000
100454 +#define MODULE_PIC 0x00080000
100455 +#define MODULE_CPC 0x00090000
100456 +#define MODULE_DUART 0x000a0000
100457 +#define MODULE_SERDES 0x000b0000
100458 +#define MODULE_PIO 0x000c0000
100459 +#define MODULE_QM 0x000d0000
100460 +#define MODULE_BM 0x000e0000
100461 +#define MODULE_SEC 0x000f0000
100462 +#define MODULE_LAW 0x00100000
100463 +#define MODULE_LBC 0x00110000
100464 +#define MODULE_PAMU 0x00120000
100465 +#define MODULE_FM 0x00130000
100466 +#define MODULE_FM_MURAM 0x00140000
100467 +#define MODULE_FM_PCD 0x00150000
100468 +#define MODULE_FM_RTC 0x00160000
100469 +#define MODULE_FM_MAC 0x00170000
100470 +#define MODULE_FM_PORT 0x00180000
100471 +#define MODULE_FM_SP 0x00190000
100472 +#define MODULE_DPA_PORT 0x001a0000
100473 +#define MODULE_MII 0x001b0000
100474 +#define MODULE_I2C 0x001c0000
100475 +#define MODULE_DMA 0x001d0000
100476 +#define MODULE_DDR 0x001e0000
100477 +#define MODULE_ESPI 0x001f0000
100478 +#define MODULE_DPAA_IPSEC 0x00200000
100479 +#endif /* using unified values */
100480 +
100481 +/*****************************************************************************
100482 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
100483 +******************************************************************************/
100484 +#define PAMU_NUM_OF_PARTITIONS 5
100485 +
100486 +#define PAMU_PICS_AVICS_ERRATA_PAMU3
100487 +
100488 +/*****************************************************************************
100489 + LAW INTEGRATION-SPECIFIC DEFINITIONS
100490 +******************************************************************************/
100491 +#define LAW_NUM_OF_WINDOWS 32
100492 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
100493 +#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */
100494 +
100495 +
100496 +/*****************************************************************************
100497 + LBC INTEGRATION-SPECIFIC DEFINITIONS
100498 +******************************************************************************/
100499 +/**************************************************************************//**
100500 + @Group lbc_exception_grp LBC Exception Unit
100501 +
100502 + @Description LBC Exception unit API functions, definitions and enums
100503 +
100504 + @{
100505 +*//***************************************************************************/
100506 +
100507 +/**************************************************************************//**
100508 + @Anchor lbc_exbm
100509 +
100510 + @Collection LBC Errors Bit Mask
100511 +
100512 + These errors are reported through the exceptions callback..
100513 + The values can be or'ed in any combination in the errors mask
100514 + parameter of the errors report structure.
100515 +
100516 + These errors can also be passed as a bit-mask to
100517 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
100518 + for enabling or disabling error checking.
100519 + @{
100520 +*//***************************************************************************/
100521 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
100522 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
100523 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
100524 +#define LBC_ERR_ATOMIC_WRITE 0x00800000 /**< Atomic write error */
100525 +#define LBC_ERR_ATOMIC_READ 0x00400000 /**< Atomic read error */
100526 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
100527 +
100528 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
100529 + LBC_ERR_WRITE_PROTECT | LBC_ERR_ATOMIC_WRITE | \
100530 + LBC_ERR_ATOMIC_READ | LBC_ERR_CHIP_SELECT)
100531 + /**< All possible errors */
100532 +/* @} */
100533 +/** @} */ /* end of lbc_exception_grp group */
100534 +
100535 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
100536 +
100537 +#define LBC_NUM_OF_BANKS 8
100538 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
100539 +#define LBC_ATOMIC_OPERATION_SUPPORT
100540 +#define LBC_PARITY_SUPPORT
100541 +#define LBC_ADDRESS_HOLD_TIME_CTRL
100542 +#define LBC_HIGH_CLK_DIVIDERS
100543 +#define LBC_FCM_AVAILABLE
100544 +
100545 +/*****************************************************************************
100546 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
100547 +******************************************************************************/
100548 +#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module;
100549 + Each port contains up to 32 i/O pins. */
100550 +
100551 +#define GPIO_VALID_PIN_MASKS \
100552 + { /* Port A */ 0xFFFFFFFF }
100553 +
100554 +#define GPIO_VALID_INTR_MASKS \
100555 + { /* Port A */ 0xFFFFFFFF }
100556 +
100557 +#endif /* __PART_INTEGRATION_EXT_H */
100558 --- /dev/null
100559 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
100560 @@ -0,0 +1,100 @@
100561 +/*
100562 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100563 + *
100564 + * Redistribution and use in source and binary forms, with or without
100565 + * modification, are permitted provided that the following conditions are met:
100566 + * * Redistributions of source code must retain the above copyright
100567 + * notice, this list of conditions and the following disclaimer.
100568 + * * Redistributions in binary form must reproduce the above copyright
100569 + * notice, this list of conditions and the following disclaimer in the
100570 + * documentation and/or other materials provided with the distribution.
100571 + * * Neither the name of Freescale Semiconductor nor the
100572 + * names of its contributors may be used to endorse or promote products
100573 + * derived from this software without specific prior written permission.
100574 + *
100575 + *
100576 + * ALTERNATIVELY, this software may be distributed under the terms of the
100577 + * GNU General Public License ("GPL") as published by the Free Software
100578 + * Foundation, either version 2 of that License or (at your option) any
100579 + * later version.
100580 + *
100581 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100582 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100583 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100584 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100585 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100586 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100587 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100588 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100589 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100590 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100591 + */
100592 +
100593 +
100594 +#ifndef __MATH_EXT_H
100595 +#define __MATH_EXT_H
100596 +
100597 +
100598 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
100599 +#include <linux/math.h>
100600 +#include <linux/math64.h>
100601 +
100602 +#elif defined(__MWERKS__)
100603 +#define LOW(x) ( sizeof(x)==8 ? *(1+(int32_t*)&x) : (*(int32_t*)&x))
100604 +#define HIGH(x) (*(int32_t*)&x)
100605 +#define ULOW(x) ( sizeof(x)==8 ? *(1+(uint32_t*)&x) : (*(uint32_t*)&x))
100606 +#define UHIGH(x) (*(uint32_t*)&x)
100607 +
100608 +static const double big = 1.0e300;
100609 +
100610 +/* Macro for checking if a number is a power of 2 */
100611 +static __inline__ double ceil(double x)
100612 +{
100613 + int32_t i0,i1,j0; /*- cc 020130 -*/
100614 + uint32_t i,j; /*- cc 020130 -*/
100615 + i0 = HIGH(x);
100616 + i1 = LOW(x);
100617 + j0 = ((i0>>20)&0x7ff)-0x3ff;
100618 + if(j0<20) {
100619 + if(j0<0) { /* raise inexact if x != 0 */
100620 + if(big+x>0.0) {/* return 0*sign(x) if |x|<1 */
100621 + if(i0<0) {i0=0x80000000;i1=0;}
100622 + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
100623 + }
100624 + } else {
100625 + i = (uint32_t)(0x000fffff)>>j0;
100626 + if(((i0&i)|i1)==0) return x; /* x is integral */
100627 + if(big+x>0.0) { /* raise inexact flag */
100628 + if(i0>0) i0 += (0x00100000)>>j0;
100629 + i0 &= (~i); i1=0;
100630 + }
100631 + }
100632 + } else if (j0>51) {
100633 + if(j0==0x400) return x+x; /* inf or NaN */
100634 + else return x; /* x is integral */
100635 + } else {
100636 + i = ((uint32_t)(0xffffffff))>>(j0-20); /*- cc 020130 -*/
100637 + if((i1&i)==0) return x; /* x is integral */
100638 + if(big+x>0.0) { /* raise inexact flag */
100639 + if(i0>0) {
100640 + if(j0==20) i0+=1;
100641 + else {
100642 + j = (uint32_t)(i1 + (1<<(52-j0)));
100643 + if(j<i1) i0+=1; /* got a carry */
100644 + i1 = (int32_t)j;
100645 + }
100646 + }
100647 + i1 &= (~i);
100648 + }
100649 + }
100650 + HIGH(x) = i0;
100651 + LOW(x) = i1;
100652 + return x;
100653 +}
100654 +
100655 +#else
100656 +#include <math.h>
100657 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
100658 +
100659 +
100660 +#endif /* __MATH_EXT_H */
100661 --- /dev/null
100662 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
100663 @@ -0,0 +1,435 @@
100664 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
100665 + * All rights reserved.
100666 + *
100667 + * Redistribution and use in source and binary forms, with or without
100668 + * modification, are permitted provided that the following conditions are met:
100669 + * * Redistributions of source code must retain the above copyright
100670 + * notice, this list of conditions and the following disclaimer.
100671 + * * Redistributions in binary form must reproduce the above copyright
100672 + * notice, this list of conditions and the following disclaimer in the
100673 + * documentation and/or other materials provided with the distribution.
100674 + * * Neither the name of Freescale Semiconductor nor the
100675 + * names of its contributors may be used to endorse or promote products
100676 + * derived from this software without specific prior written permission.
100677 + *
100678 + *
100679 + * ALTERNATIVELY, this software may be distributed under the terms of the
100680 + * GNU General Public License ("GPL") as published by the Free Software
100681 + * Foundation, either version 2 of that License or (at your option) any
100682 + * later version.
100683 + *
100684 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100685 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100686 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100687 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100688 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100689 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100690 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100691 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100692 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100693 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100694 + */
100695 +
100696 +
100697 +/**************************************************************************//**
100698 + @File ncsw_ext.h
100699 +
100700 + @Description General NetCommSw Standard Definitions
100701 +*//***************************************************************************/
100702 +
100703 +#ifndef __NCSW_EXT_H
100704 +#define __NCSW_EXT_H
100705 +
100706 +
100707 +#include "memcpy_ext.h"
100708 +
100709 +#define WRITE_BLOCK IOMemSet32 /* include memcpy_ext.h */
100710 +#define COPY_BLOCK Mem2IOCpy32 /* include memcpy_ext.h */
100711 +
100712 +#define PTR_TO_UINT(_ptr) ((uintptr_t)(_ptr))
100713 +#define UINT_TO_PTR(_val) ((void*)(uintptr_t)(_val))
100714 +
100715 +#define PTR_MOVE(_ptr, _offset) (void*)((uint8_t*)(_ptr) + (_offset))
100716 +
100717 +
100718 +#define WRITE_UINT8_UINT24(arg, data08, data24) \
100719 + WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF))
100720 +#define WRITE_UINT24_UINT8(arg, data24, data08) \
100721 + WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF))
100722 +
100723 +/* Little-Endian access macros */
100724 +
100725 +#define WRITE_UINT16_LE(arg, data) \
100726 + WRITE_UINT16((arg), SwapUint16(data))
100727 +
100728 +#define WRITE_UINT32_LE(arg, data) \
100729 + WRITE_UINT32((arg), SwapUint32(data))
100730 +
100731 +#define WRITE_UINT64_LE(arg, data) \
100732 + WRITE_UINT64((arg), SwapUint64(data))
100733 +
100734 +#define GET_UINT16_LE(arg) \
100735 + SwapUint16(GET_UINT16(arg))
100736 +
100737 +#define GET_UINT32_LE(arg) \
100738 + SwapUint32(GET_UINT32(arg))
100739 +
100740 +#define GET_UINT64_LE(arg) \
100741 + SwapUint64(GET_UINT64(arg))
100742 +
100743 +/* Write and Read again macros */
100744 +#define WRITE_UINT_SYNC(size, arg, data) \
100745 + do { \
100746 + WRITE_UINT##size((arg), (data)); \
100747 + CORE_MemoryBarrier(); \
100748 + } while (0)
100749 +
100750 +#define WRITE_UINT8_SYNC(arg, data) WRITE_UINT_SYNC(8, (arg), (data))
100751 +
100752 +#define WRITE_UINT16_SYNC(arg, data) WRITE_UINT_SYNC(16, (arg), (data))
100753 +#define WRITE_UINT32_SYNC(arg, data) WRITE_UINT_SYNC(32, (arg), (data))
100754 +
100755 +#define MAKE_UINT64(high32, low32) (((uint64_t)high32 << 32) | (low32))
100756 +
100757 +
100758 +/*----------------------*/
100759 +/* Miscellaneous macros */
100760 +/*----------------------*/
100761 +
100762 +#define UNUSED(_x) ((void)(_x))
100763 +
100764 +#define KILOBYTE 0x400UL /* 1024 */
100765 +#define MEGABYTE (KILOBYTE * KILOBYTE) /* 1024*1024 */
100766 +#define GIGABYTE ((uint64_t)(KILOBYTE * MEGABYTE)) /* 1024*1024*1024 */
100767 +#define TERABYTE ((uint64_t)(KILOBYTE * GIGABYTE)) /* 1024*1024*1024*1024 */
100768 +
100769 +#ifndef NO_IRQ
100770 +#define NO_IRQ (0)
100771 +#endif
100772 +#define NCSW_MASTER_ID (0)
100773 +
100774 +/* Macro for checking if a number is a power of 2 */
100775 +#define POWER_OF_2(n) (!((n) & ((n)-1)))
100776 +
100777 +/* Macro for calculating log of base 2 */
100778 +#define LOG2(num, log2Num) \
100779 + do \
100780 + { \
100781 + uint64_t tmp = (num); \
100782 + log2Num = 0; \
100783 + while (tmp > 1) \
100784 + { \
100785 + log2Num++; \
100786 + tmp >>= 1; \
100787 + } \
100788 + } while (0)
100789 +
100790 +#define NEXT_POWER_OF_2(_num, _nextPow) \
100791 +do \
100792 +{ \
100793 + if (POWER_OF_2(_num)) \
100794 + _nextPow = (_num); \
100795 + else \
100796 + { \
100797 + uint64_t tmp = (_num); \
100798 + _nextPow = 1; \
100799 + while (tmp) \
100800 + { \
100801 + _nextPow <<= 1; \
100802 + tmp >>= 1; \
100803 + } \
100804 + } \
100805 +} while (0)
100806 +
100807 +/* Ceiling division - not the fastest way, but safer in terms of overflow */
100808 +#define DIV_CEIL(x,y) (div64_u64((x),(y)) + (((div64_u64((x),(y))*(y)) == (x)) ? 0 : 1))
100809 +
100810 +/* Round up a number to be a multiple of a second number */
100811 +#define ROUND_UP(x,y) ((((x) + (y) - 1) / (y)) * (y))
100812 +
100813 +/* Timing macro for converting usec units to number of ticks. */
100814 +/* (number of usec * clock_Hz) / 1,000,000) - since */
100815 +/* clk is in MHz units, no division needed. */
100816 +#define USEC_TO_CLK(usec,clk) ((usec) * (clk))
100817 +#define CYCLES_TO_USEC(cycles,clk) ((cycles) / (clk))
100818 +
100819 +/* Timing macros for converting between nsec units and number of clocks. */
100820 +#define NSEC_TO_CLK(nsec,clk) DIV_CEIL(((nsec) * (clk)), 1000)
100821 +#define CYCLES_TO_NSEC(cycles,clk) (((cycles) * 1000) / (clk))
100822 +
100823 +/* Timing macros for converting between psec units and number of clocks. */
100824 +#define PSEC_TO_CLK(psec,clk) DIV_CEIL(((psec) * (clk)), 1000000)
100825 +#define CYCLES_TO_PSEC(cycles,clk) (((cycles) * 1000000) / (clk))
100826 +
100827 +/* Min, Max macros */
100828 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
100829 +#define MAX(a,b) ((a) > (b) ? (a) : (b))
100830 +#define IN_RANGE(min,val,max) ((min)<=(val) && (val)<=(max))
100831 +
100832 +#define ABS(a) ((a<0)?(a*-1):a)
100833 +
100834 +#if !(defined(ARRAY_SIZE))
100835 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
100836 +#endif /* !defined(ARRAY_SIZE) */
100837 +
100838 +
100839 +/* possible alignments */
100840 +#define HALF_WORD_ALIGNMENT 2
100841 +#define WORD_ALIGNMENT 4
100842 +#define DOUBLE_WORD_ALIGNMENT 8
100843 +#define BURST_ALIGNMENT 32
100844 +
100845 +#define HALF_WORD_ALIGNED 0x00000001
100846 +#define WORD_ALIGNED 0x00000003
100847 +#define DOUBLE_WORD_ALIGNED 0x00000007
100848 +#define BURST_ALIGNED 0x0000001f
100849 +#ifndef IS_ALIGNED
100850 +#define IS_ALIGNED(n,align) (!((uint32_t)(n) & (align - 1)))
100851 +#endif /* IS_ALIGNED */
100852 +
100853 +
100854 +#define LAST_BUF 1
100855 +#define FIRST_BUF 2
100856 +#define SINGLE_BUF (LAST_BUF | FIRST_BUF)
100857 +#define MIDDLE_BUF 4
100858 +
100859 +#define ARRAY_END -1
100860 +
100861 +#define ILLEGAL_BASE (~0)
100862 +
100863 +#define BUF_POSITION(first, last) state[(!!(last))<<1 | !!(first)]
100864 +#define DECLARE_POSITION static uint8_t state[4] = { (uint8_t)MIDDLE_BUF, (uint8_t)FIRST_BUF, (uint8_t)LAST_BUF, (uint8_t)SINGLE_BUF };
100865 +
100866 +
100867 +/**************************************************************************//**
100868 + @Description Timers operation mode
100869 +*//***************************************************************************/
100870 +typedef enum e_TimerMode
100871 +{
100872 + e_TIMER_MODE_INVALID = 0,
100873 + e_TIMER_MODE_FREE_RUN, /**< Free run - counter continues to increase
100874 + after reaching the reference value. */
100875 + e_TIMER_MODE_PERIODIC, /**< Periodic - counter restarts counting from 0
100876 + after reaching the reference value. */
100877 + e_TIMER_MODE_SINGLE /**< Single (one-shot) - counter stops counting
100878 + after reaching the reference value. */
100879 +} e_TimerMode;
100880 +
100881 +
100882 +/**************************************************************************//**
100883 + @Description Enumeration (bit flags) of communication modes (Transmit,
100884 + receive or both).
100885 +*//***************************************************************************/
100886 +typedef enum e_CommMode
100887 +{
100888 + e_COMM_MODE_NONE = 0, /**< No transmit/receive communication */
100889 + e_COMM_MODE_RX = 1, /**< Only receive communication */
100890 + e_COMM_MODE_TX = 2, /**< Only transmit communication */
100891 + e_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
100892 +} e_CommMode;
100893 +
100894 +/**************************************************************************//**
100895 + @Description General Diagnostic Mode
100896 +*//***************************************************************************/
100897 +typedef enum e_DiagMode
100898 +{
100899 + e_DIAG_MODE_NONE = 0, /**< Normal operation; no diagnostic mode */
100900 + e_DIAG_MODE_CTRL_LOOPBACK, /**< Loopback in the controller */
100901 + e_DIAG_MODE_CHIP_LOOPBACK, /**< Loopback in the chip but not in the
100902 + controller; e.g. IO-pins, SerDes, etc. */
100903 + e_DIAG_MODE_PHY_LOOPBACK, /**< Loopback in the external PHY */
100904 + e_DIAG_MODE_EXT_LOOPBACK, /**< Loopback in the external line (beyond the PHY) */
100905 + e_DIAG_MODE_CTRL_ECHO, /**< Echo incoming data by the controller */
100906 + e_DIAG_MODE_PHY_ECHO /**< Echo incoming data by the PHY */
100907 +} e_DiagMode;
100908 +
100909 +/**************************************************************************//**
100910 + @Description Possible RxStore callback responses.
100911 +*//***************************************************************************/
100912 +typedef enum e_RxStoreResponse
100913 +{
100914 + e_RX_STORE_RESPONSE_PAUSE /**< Pause invoking callback with received data;
100915 + in polling mode, start again invoking callback
100916 + only next time user invokes the receive routine;
100917 + in interrupt mode, start again invoking callback
100918 + only next time a receive event triggers an interrupt;
100919 + in all cases, received data that are pending are not
100920 + lost, rather, their processing is temporarily deferred;
100921 + in all cases, received data are processed in the order
100922 + in which they were received. */
100923 + , e_RX_STORE_RESPONSE_CONTINUE /**< Continue invoking callback with received data. */
100924 +} e_RxStoreResponse;
100925 +
100926 +
100927 +/**************************************************************************//**
100928 + @Description General Handle
100929 +*//***************************************************************************/
100930 +typedef void * t_Handle; /**< handle, used as object's descriptor */
100931 +
100932 +/**************************************************************************//**
100933 + @Description MUTEX type
100934 +*//***************************************************************************/
100935 +typedef uint32_t t_Mutex;
100936 +
100937 +/**************************************************************************//**
100938 + @Description Error Code.
100939 +
100940 + The high word of the error code is the code of the software
100941 + module (driver). The low word is the error type (e_ErrorType).
100942 + To get the values from the error code, use GET_ERROR_TYPE()
100943 + and GET_ERROR_MODULE().
100944 +*//***************************************************************************/
100945 +typedef uint32_t t_Error;
100946 +
100947 +/**************************************************************************//**
100948 + @Description General prototype of interrupt service routine (ISR).
100949 +
100950 + @Param[in] handle - Optional handle of the module handling the interrupt.
100951 +
100952 + @Return None
100953 + *//***************************************************************************/
100954 +typedef void (t_Isr)(t_Handle handle);
100955 +
100956 +/**************************************************************************//**
100957 + @Anchor mem_attr
100958 +
100959 + @Collection Memory Attributes
100960 +
100961 + Various attributes of memory partitions. These values may be
100962 + or'ed together to create a mask of all memory attributes.
100963 + @{
100964 +*//***************************************************************************/
100965 +#define MEMORY_ATTR_CACHEABLE 0x00000001
100966 + /**< Memory is cacheable */
100967 +#define MEMORY_ATTR_QE_2ND_BUS_ACCESS 0x00000002
100968 + /**< Memory can be accessed by QUICC Engine
100969 + through its secondary bus interface */
100970 +
100971 +/* @} */
100972 +
100973 +
100974 +/**************************************************************************//**
100975 + @Function t_GetBufFunction
100976 +
100977 + @Description User callback function called by driver to get data buffer.
100978 +
100979 + User provides this function. Driver invokes it.
100980 +
100981 + @Param[in] h_BufferPool - A handle to buffer pool manager
100982 + @Param[out] p_BufContextHandle - Returns the user's private context that
100983 + should be associated with the buffer
100984 +
100985 + @Return Pointer to data buffer, NULL if error
100986 + *//***************************************************************************/
100987 +typedef uint8_t * (t_GetBufFunction)(t_Handle h_BufferPool,
100988 + t_Handle *p_BufContextHandle);
100989 +
100990 +/**************************************************************************//**
100991 + @Function t_PutBufFunction
100992 +
100993 + @Description User callback function called by driver to return data buffer.
100994 +
100995 + User provides this function. Driver invokes it.
100996 +
100997 + @Param[in] h_BufferPool - A handle to buffer pool manager
100998 + @Param[in] p_Buffer - A pointer to buffer to return
100999 + @Param[in] h_BufContext - The user's private context associated with
101000 + the returned buffer
101001 +
101002 + @Return E_OK on success; Error code otherwise
101003 + *//***************************************************************************/
101004 +typedef t_Error (t_PutBufFunction)(t_Handle h_BufferPool,
101005 + uint8_t *p_Buffer,
101006 + t_Handle h_BufContext);
101007 +
101008 +/**************************************************************************//**
101009 + @Function t_PhysToVirt
101010 +
101011 + @Description Translates a physical address to the matching virtual address.
101012 +
101013 + @Param[in] addr - The physical address to translate.
101014 +
101015 + @Return Virtual address.
101016 +*//***************************************************************************/
101017 +typedef void * t_PhysToVirt(physAddress_t addr);
101018 +
101019 +/**************************************************************************//**
101020 + @Function t_VirtToPhys
101021 +
101022 + @Description Translates a virtual address to the matching physical address.
101023 +
101024 + @Param[in] addr - The virtual address to translate.
101025 +
101026 + @Return Physical address.
101027 +*//***************************************************************************/
101028 +typedef physAddress_t t_VirtToPhys(void *addr);
101029 +
101030 +/**************************************************************************//**
101031 + @Description Buffer Pool Information Structure.
101032 +*//***************************************************************************/
101033 +typedef struct t_BufferPoolInfo
101034 +{
101035 + t_Handle h_BufferPool; /**< A handle to the buffer pool manager */
101036 + t_GetBufFunction *f_GetBuf; /**< User callback to get a free buffer */
101037 + t_PutBufFunction *f_PutBuf; /**< User callback to return a buffer */
101038 + uint16_t bufferSize; /**< Buffer size (in bytes) */
101039 +
101040 + t_PhysToVirt *f_PhysToVirt; /**< User callback to translate pool buffers
101041 + physical addresses to virtual addresses */
101042 + t_VirtToPhys *f_VirtToPhys; /**< User callback to translate pool buffers
101043 + virtual addresses to physical addresses */
101044 +} t_BufferPoolInfo;
101045 +
101046 +
101047 +/**************************************************************************//**
101048 + @Description User callback function called by driver when transmit completed.
101049 +
101050 + User provides this function. Driver invokes it.
101051 +
101052 + @Param[in] h_App - Application's handle, as was provided to the
101053 + driver by the user
101054 + @Param[in] queueId - Transmit queue ID
101055 + @Param[in] p_Data - Pointer to the data buffer
101056 + @Param[in] h_BufContext - The user's private context associated with
101057 + the given data buffer
101058 + @Param[in] status - Transmit status and errors
101059 + @Param[in] flags - Driver-dependent information
101060 + *//***************************************************************************/
101061 +typedef void (t_TxConfFunction)(t_Handle h_App,
101062 + uint32_t queueId,
101063 + uint8_t *p_Data,
101064 + t_Handle h_BufContext,
101065 + uint16_t status,
101066 + uint32_t flags);
101067 +
101068 +/**************************************************************************//**
101069 + @Description User callback function called by driver with receive data.
101070 +
101071 + User provides this function. Driver invokes it.
101072 +
101073 + @Param[in] h_App - Application's handle, as was provided to the
101074 + driver by the user
101075 + @Param[in] queueId - Receive queue ID
101076 + @Param[in] p_Data - Pointer to the buffer with received data
101077 + @Param[in] h_BufContext - The user's private context associated with
101078 + the given data buffer
101079 + @Param[in] length - Length of received data
101080 + @Param[in] status - Receive status and errors
101081 + @Param[in] position - Position of buffer in frame
101082 + @Param[in] flags - Driver-dependent information
101083 +
101084 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
101085 + operation for all ready data.
101086 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
101087 + *//***************************************************************************/
101088 +typedef e_RxStoreResponse (t_RxStoreFunction)(t_Handle h_App,
101089 + uint32_t queueId,
101090 + uint8_t *p_Data,
101091 + t_Handle h_BufContext,
101092 + uint32_t length,
101093 + uint16_t status,
101094 + uint8_t position,
101095 + uint32_t flags);
101096 +
101097 +
101098 +#endif /* __NCSW_EXT_H */
101099 --- /dev/null
101100 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
101101 @@ -0,0 +1,430 @@
101102 +/*
101103 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101104 + *
101105 + * Redistribution and use in source and binary forms, with or without
101106 + * modification, are permitted provided that the following conditions are met:
101107 + * * Redistributions of source code must retain the above copyright
101108 + * notice, this list of conditions and the following disclaimer.
101109 + * * Redistributions in binary form must reproduce the above copyright
101110 + * notice, this list of conditions and the following disclaimer in the
101111 + * documentation and/or other materials provided with the distribution.
101112 + * * Neither the name of Freescale Semiconductor nor the
101113 + * names of its contributors may be used to endorse or promote products
101114 + * derived from this software without specific prior written permission.
101115 + *
101116 + *
101117 + * ALTERNATIVELY, this software may be distributed under the terms of the
101118 + * GNU General Public License ("GPL") as published by the Free Software
101119 + * Foundation, either version 2 of that License or (at your option) any
101120 + * later version.
101121 + *
101122 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101123 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101124 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101125 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101126 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101127 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101128 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101129 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101130 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101131 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101132 + */
101133 +
101134 +
101135 +/**************************************************************************//**
101136 + @File net_ext.h
101137 +
101138 + @Description This file contains common and general netcomm headers definitions.
101139 +*//***************************************************************************/
101140 +#ifndef __NET_EXT_H
101141 +#define __NET_EXT_H
101142 +
101143 +#include "std_ext.h"
101144 +
101145 +
101146 +typedef uint8_t headerFieldPpp_t;
101147 +
101148 +#define NET_HEADER_FIELD_PPP_PID (1)
101149 +#define NET_HEADER_FIELD_PPP_COMPRESSED (NET_HEADER_FIELD_PPP_PID << 1)
101150 +#define NET_HEADER_FIELD_PPP_ALL_FIELDS ((NET_HEADER_FIELD_PPP_PID << 2) - 1)
101151 +
101152 +
101153 +typedef uint8_t headerFieldPppoe_t;
101154 +
101155 +#define NET_HEADER_FIELD_PPPoE_VER (1)
101156 +#define NET_HEADER_FIELD_PPPoE_TYPE (NET_HEADER_FIELD_PPPoE_VER << 1)
101157 +#define NET_HEADER_FIELD_PPPoE_CODE (NET_HEADER_FIELD_PPPoE_VER << 2)
101158 +#define NET_HEADER_FIELD_PPPoE_SID (NET_HEADER_FIELD_PPPoE_VER << 3)
101159 +#define NET_HEADER_FIELD_PPPoE_LEN (NET_HEADER_FIELD_PPPoE_VER << 4)
101160 +#define NET_HEADER_FIELD_PPPoE_SESSION (NET_HEADER_FIELD_PPPoE_VER << 5)
101161 +#define NET_HEADER_FIELD_PPPoE_PID (NET_HEADER_FIELD_PPPoE_VER << 6)
101162 +#define NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
101163 +
101164 +#define NET_HEADER_FIELD_PPPMUX_PID (1)
101165 +#define NET_HEADER_FIELD_PPPMUX_CKSUM (NET_HEADER_FIELD_PPPMUX_PID << 1)
101166 +#define NET_HEADER_FIELD_PPPMUX_COMPRESSED (NET_HEADER_FIELD_PPPMUX_PID << 2)
101167 +#define NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
101168 +
101169 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
101170 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
101171 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
101172 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
101173 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
101174 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
101175 +
101176 +
101177 +typedef uint8_t headerFieldEth_t;
101178 +
101179 +#define NET_HEADER_FIELD_ETH_DA (1)
101180 +#define NET_HEADER_FIELD_ETH_SA (NET_HEADER_FIELD_ETH_DA << 1)
101181 +#define NET_HEADER_FIELD_ETH_LENGTH (NET_HEADER_FIELD_ETH_DA << 2)
101182 +#define NET_HEADER_FIELD_ETH_TYPE (NET_HEADER_FIELD_ETH_DA << 3)
101183 +#define NET_HEADER_FIELD_ETH_FINAL_CKSUM (NET_HEADER_FIELD_ETH_DA << 4)
101184 +#define NET_HEADER_FIELD_ETH_PADDING (NET_HEADER_FIELD_ETH_DA << 5)
101185 +#define NET_HEADER_FIELD_ETH_ALL_FIELDS ((NET_HEADER_FIELD_ETH_DA << 6) - 1)
101186 +
101187 +#define NET_HEADER_FIELD_ETH_ADDR_SIZE 6
101188 +
101189 +typedef uint16_t headerFieldIp_t;
101190 +
101191 +#define NET_HEADER_FIELD_IP_VER (1)
101192 +#define NET_HEADER_FIELD_IP_DSCP (NET_HEADER_FIELD_IP_VER << 2)
101193 +#define NET_HEADER_FIELD_IP_ECN (NET_HEADER_FIELD_IP_VER << 3)
101194 +#define NET_HEADER_FIELD_IP_PROTO (NET_HEADER_FIELD_IP_VER << 4)
101195 +
101196 +#define NET_HEADER_FIELD_IP_PROTO_SIZE 1
101197 +
101198 +typedef uint16_t headerFieldIpv4_t;
101199 +
101200 +#define NET_HEADER_FIELD_IPv4_VER (1)
101201 +#define NET_HEADER_FIELD_IPv4_HDR_LEN (NET_HEADER_FIELD_IPv4_VER << 1)
101202 +#define NET_HEADER_FIELD_IPv4_TOS (NET_HEADER_FIELD_IPv4_VER << 2)
101203 +#define NET_HEADER_FIELD_IPv4_TOTAL_LEN (NET_HEADER_FIELD_IPv4_VER << 3)
101204 +#define NET_HEADER_FIELD_IPv4_ID (NET_HEADER_FIELD_IPv4_VER << 4)
101205 +#define NET_HEADER_FIELD_IPv4_FLAG_D (NET_HEADER_FIELD_IPv4_VER << 5)
101206 +#define NET_HEADER_FIELD_IPv4_FLAG_M (NET_HEADER_FIELD_IPv4_VER << 6)
101207 +#define NET_HEADER_FIELD_IPv4_OFFSET (NET_HEADER_FIELD_IPv4_VER << 7)
101208 +#define NET_HEADER_FIELD_IPv4_TTL (NET_HEADER_FIELD_IPv4_VER << 8)
101209 +#define NET_HEADER_FIELD_IPv4_PROTO (NET_HEADER_FIELD_IPv4_VER << 9)
101210 +#define NET_HEADER_FIELD_IPv4_CKSUM (NET_HEADER_FIELD_IPv4_VER << 10)
101211 +#define NET_HEADER_FIELD_IPv4_SRC_IP (NET_HEADER_FIELD_IPv4_VER << 11)
101212 +#define NET_HEADER_FIELD_IPv4_DST_IP (NET_HEADER_FIELD_IPv4_VER << 12)
101213 +#define NET_HEADER_FIELD_IPv4_OPTS (NET_HEADER_FIELD_IPv4_VER << 13)
101214 +#define NET_HEADER_FIELD_IPv4_OPTS_COUNT (NET_HEADER_FIELD_IPv4_VER << 14)
101215 +#define NET_HEADER_FIELD_IPv4_ALL_FIELDS ((NET_HEADER_FIELD_IPv4_VER << 15) - 1)
101216 +
101217 +#define NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
101218 +#define NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
101219 +
101220 +
101221 +typedef uint8_t headerFieldIpv6_t;
101222 +
101223 +#define NET_HEADER_FIELD_IPv6_VER (1)
101224 +#define NET_HEADER_FIELD_IPv6_TC (NET_HEADER_FIELD_IPv6_VER << 1)
101225 +#define NET_HEADER_FIELD_IPv6_SRC_IP (NET_HEADER_FIELD_IPv6_VER << 2)
101226 +#define NET_HEADER_FIELD_IPv6_DST_IP (NET_HEADER_FIELD_IPv6_VER << 3)
101227 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR (NET_HEADER_FIELD_IPv6_VER << 4)
101228 +#define NET_HEADER_FIELD_IPv6_FL (NET_HEADER_FIELD_IPv6_VER << 5)
101229 +#define NET_HEADER_FIELD_IPv6_HOP_LIMIT (NET_HEADER_FIELD_IPv6_VER << 6)
101230 +#define NET_HEADER_FIELD_IPv6_ALL_FIELDS ((NET_HEADER_FIELD_IPv6_VER << 7) - 1)
101231 +
101232 +#define NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
101233 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
101234 +
101235 +#define NET_HEADER_FIELD_ICMP_TYPE (1)
101236 +#define NET_HEADER_FIELD_ICMP_CODE (NET_HEADER_FIELD_ICMP_TYPE << 1)
101237 +#define NET_HEADER_FIELD_ICMP_CKSUM (NET_HEADER_FIELD_ICMP_TYPE << 2)
101238 +#define NET_HEADER_FIELD_ICMP_ID (NET_HEADER_FIELD_ICMP_TYPE << 3)
101239 +#define NET_HEADER_FIELD_ICMP_SQ_NUM (NET_HEADER_FIELD_ICMP_TYPE << 4)
101240 +#define NET_HEADER_FIELD_ICMP_ALL_FIELDS ((NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
101241 +
101242 +#define NET_HEADER_FIELD_ICMP_CODE_SIZE 1
101243 +#define NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
101244 +
101245 +#define NET_HEADER_FIELD_IGMP_VERSION (1)
101246 +#define NET_HEADER_FIELD_IGMP_TYPE (NET_HEADER_FIELD_IGMP_VERSION << 1)
101247 +#define NET_HEADER_FIELD_IGMP_CKSUM (NET_HEADER_FIELD_IGMP_VERSION << 2)
101248 +#define NET_HEADER_FIELD_IGMP_DATA (NET_HEADER_FIELD_IGMP_VERSION << 3)
101249 +#define NET_HEADER_FIELD_IGMP_ALL_FIELDS ((NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
101250 +
101251 +
101252 +typedef uint16_t headerFieldTcp_t;
101253 +
101254 +#define NET_HEADER_FIELD_TCP_PORT_SRC (1)
101255 +#define NET_HEADER_FIELD_TCP_PORT_DST (NET_HEADER_FIELD_TCP_PORT_SRC << 1)
101256 +#define NET_HEADER_FIELD_TCP_SEQ (NET_HEADER_FIELD_TCP_PORT_SRC << 2)
101257 +#define NET_HEADER_FIELD_TCP_ACK (NET_HEADER_FIELD_TCP_PORT_SRC << 3)
101258 +#define NET_HEADER_FIELD_TCP_OFFSET (NET_HEADER_FIELD_TCP_PORT_SRC << 4)
101259 +#define NET_HEADER_FIELD_TCP_FLAGS (NET_HEADER_FIELD_TCP_PORT_SRC << 5)
101260 +#define NET_HEADER_FIELD_TCP_WINDOW (NET_HEADER_FIELD_TCP_PORT_SRC << 6)
101261 +#define NET_HEADER_FIELD_TCP_CKSUM (NET_HEADER_FIELD_TCP_PORT_SRC << 7)
101262 +#define NET_HEADER_FIELD_TCP_URGPTR (NET_HEADER_FIELD_TCP_PORT_SRC << 8)
101263 +#define NET_HEADER_FIELD_TCP_OPTS (NET_HEADER_FIELD_TCP_PORT_SRC << 9)
101264 +#define NET_HEADER_FIELD_TCP_OPTS_COUNT (NET_HEADER_FIELD_TCP_PORT_SRC << 10)
101265 +#define NET_HEADER_FIELD_TCP_ALL_FIELDS ((NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
101266 +
101267 +#define NET_HEADER_FIELD_TCP_PORT_SIZE 2
101268 +
101269 +
101270 +typedef uint8_t headerFieldSctp_t;
101271 +
101272 +#define NET_HEADER_FIELD_SCTP_PORT_SRC (1)
101273 +#define NET_HEADER_FIELD_SCTP_PORT_DST (NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
101274 +#define NET_HEADER_FIELD_SCTP_VER_TAG (NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
101275 +#define NET_HEADER_FIELD_SCTP_CKSUM (NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
101276 +#define NET_HEADER_FIELD_SCTP_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
101277 +
101278 +#define NET_HEADER_FIELD_SCTP_PORT_SIZE 2
101279 +
101280 +typedef uint8_t headerFieldDccp_t;
101281 +
101282 +#define NET_HEADER_FIELD_DCCP_PORT_SRC (1)
101283 +#define NET_HEADER_FIELD_DCCP_PORT_DST (NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
101284 +#define NET_HEADER_FIELD_DCCP_ALL_FIELDS ((NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
101285 +
101286 +#define NET_HEADER_FIELD_DCCP_PORT_SIZE 2
101287 +
101288 +
101289 +typedef uint8_t headerFieldUdp_t;
101290 +
101291 +#define NET_HEADER_FIELD_UDP_PORT_SRC (1)
101292 +#define NET_HEADER_FIELD_UDP_PORT_DST (NET_HEADER_FIELD_UDP_PORT_SRC << 1)
101293 +#define NET_HEADER_FIELD_UDP_LEN (NET_HEADER_FIELD_UDP_PORT_SRC << 2)
101294 +#define NET_HEADER_FIELD_UDP_CKSUM (NET_HEADER_FIELD_UDP_PORT_SRC << 3)
101295 +#define NET_HEADER_FIELD_UDP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
101296 +
101297 +#define NET_HEADER_FIELD_UDP_PORT_SIZE 2
101298 +
101299 +typedef uint8_t headerFieldUdpLite_t;
101300 +
101301 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
101302 +#define NET_HEADER_FIELD_UDP_LITE_PORT_DST (NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
101303 +#define NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
101304 +
101305 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
101306 +
101307 +typedef uint8_t headerFieldUdpEncapEsp_t;
101308 +
101309 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
101310 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
101311 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
101312 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
101313 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
101314 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
101315 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
101316 +
101317 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
101318 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
101319 +
101320 +#define NET_HEADER_FIELD_IPHC_CID (1)
101321 +#define NET_HEADER_FIELD_IPHC_CID_TYPE (NET_HEADER_FIELD_IPHC_CID << 1)
101322 +#define NET_HEADER_FIELD_IPHC_HCINDEX (NET_HEADER_FIELD_IPHC_CID << 2)
101323 +#define NET_HEADER_FIELD_IPHC_GEN (NET_HEADER_FIELD_IPHC_CID << 3)
101324 +#define NET_HEADER_FIELD_IPHC_D_BIT (NET_HEADER_FIELD_IPHC_CID << 4)
101325 +#define NET_HEADER_FIELD_IPHC_ALL_FIELDS ((NET_HEADER_FIELD_IPHC_CID << 5) - 1)
101326 +
101327 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
101328 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
101329 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
101330 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
101331 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
101332 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
101333 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
101334 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
101335 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
101336 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
101337 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
101338 +
101339 +#define NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
101340 +#define NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
101341 +#define NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
101342 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
101343 +#define NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
101344 +#define NET_HEADER_FIELD_L2TPv2_VERSION (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
101345 +#define NET_HEADER_FIELD_L2TPv2_LEN (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
101346 +#define NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
101347 +#define NET_HEADER_FIELD_L2TPv2_SESSION_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
101348 +#define NET_HEADER_FIELD_L2TPv2_NS (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
101349 +#define NET_HEADER_FIELD_L2TPv2_NR (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
101350 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
101351 +#define NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
101352 +#define NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
101353 +
101354 +#define NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
101355 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
101356 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
101357 +#define NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
101358 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
101359 +#define NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
101360 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SENT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
101361 +#define NET_HEADER_FIELD_L2TPv3_CTRL_RECV (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
101362 +#define NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
101363 +#define NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
101364 +
101365 +#define NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
101366 +#define NET_HEADER_FIELD_L2TPv3_SESS_VERSION (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
101367 +#define NET_HEADER_FIELD_L2TPv3_SESS_ID (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
101368 +#define NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
101369 +#define NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
101370 +
101371 +
101372 +typedef uint8_t headerFieldVlan_t;
101373 +
101374 +#define NET_HEADER_FIELD_VLAN_VPRI (1)
101375 +#define NET_HEADER_FIELD_VLAN_CFI (NET_HEADER_FIELD_VLAN_VPRI << 1)
101376 +#define NET_HEADER_FIELD_VLAN_VID (NET_HEADER_FIELD_VLAN_VPRI << 2)
101377 +#define NET_HEADER_FIELD_VLAN_LENGTH (NET_HEADER_FIELD_VLAN_VPRI << 3)
101378 +#define NET_HEADER_FIELD_VLAN_TYPE (NET_HEADER_FIELD_VLAN_VPRI << 4)
101379 +#define NET_HEADER_FIELD_VLAN_ALL_FIELDS ((NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
101380 +
101381 +#define NET_HEADER_FIELD_VLAN_TCI (NET_HEADER_FIELD_VLAN_VPRI | \
101382 + NET_HEADER_FIELD_VLAN_CFI | \
101383 + NET_HEADER_FIELD_VLAN_VID)
101384 +
101385 +
101386 +typedef uint8_t headerFieldLlc_t;
101387 +
101388 +#define NET_HEADER_FIELD_LLC_DSAP (1)
101389 +#define NET_HEADER_FIELD_LLC_SSAP (NET_HEADER_FIELD_LLC_DSAP << 1)
101390 +#define NET_HEADER_FIELD_LLC_CTRL (NET_HEADER_FIELD_LLC_DSAP << 2)
101391 +#define NET_HEADER_FIELD_LLC_ALL_FIELDS ((NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
101392 +
101393 +#define NET_HEADER_FIELD_NLPID_NLPID (1)
101394 +#define NET_HEADER_FIELD_NLPID_ALL_FIELDS ((NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
101395 +
101396 +
101397 +typedef uint8_t headerFieldSnap_t;
101398 +
101399 +#define NET_HEADER_FIELD_SNAP_OUI (1)
101400 +#define NET_HEADER_FIELD_SNAP_PID (NET_HEADER_FIELD_SNAP_OUI << 1)
101401 +#define NET_HEADER_FIELD_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
101402 +
101403 +
101404 +typedef uint8_t headerFieldLlcSnap_t;
101405 +
101406 +#define NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
101407 +#define NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
101408 +
101409 +#define NET_HEADER_FIELD_ARP_HTYPE (1)
101410 +#define NET_HEADER_FIELD_ARP_PTYPE (NET_HEADER_FIELD_ARP_HTYPE << 1)
101411 +#define NET_HEADER_FIELD_ARP_HLEN (NET_HEADER_FIELD_ARP_HTYPE << 2)
101412 +#define NET_HEADER_FIELD_ARP_PLEN (NET_HEADER_FIELD_ARP_HTYPE << 3)
101413 +#define NET_HEADER_FIELD_ARP_OPER (NET_HEADER_FIELD_ARP_HTYPE << 4)
101414 +#define NET_HEADER_FIELD_ARP_SHA (NET_HEADER_FIELD_ARP_HTYPE << 5)
101415 +#define NET_HEADER_FIELD_ARP_SPA (NET_HEADER_FIELD_ARP_HTYPE << 6)
101416 +#define NET_HEADER_FIELD_ARP_THA (NET_HEADER_FIELD_ARP_HTYPE << 7)
101417 +#define NET_HEADER_FIELD_ARP_TPA (NET_HEADER_FIELD_ARP_HTYPE << 8)
101418 +#define NET_HEADER_FIELD_ARP_ALL_FIELDS ((NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
101419 +
101420 +#define NET_HEADER_FIELD_RFC2684_LLC (1)
101421 +#define NET_HEADER_FIELD_RFC2684_NLPID (NET_HEADER_FIELD_RFC2684_LLC << 1)
101422 +#define NET_HEADER_FIELD_RFC2684_OUI (NET_HEADER_FIELD_RFC2684_LLC << 2)
101423 +#define NET_HEADER_FIELD_RFC2684_PID (NET_HEADER_FIELD_RFC2684_LLC << 3)
101424 +#define NET_HEADER_FIELD_RFC2684_VPN_OUI (NET_HEADER_FIELD_RFC2684_LLC << 4)
101425 +#define NET_HEADER_FIELD_RFC2684_VPN_IDX (NET_HEADER_FIELD_RFC2684_LLC << 5)
101426 +#define NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
101427 +
101428 +#define NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
101429 +#define NET_HEADER_FIELD_USER_DEFINED_PCDID (NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
101430 +#define NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
101431 +
101432 +#define NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
101433 +#define NET_HEADER_FIELD_PAYLOAD_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
101434 +#define NET_HEADER_FIELD_MAX_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
101435 +#define NET_HEADER_FIELD_MIN_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
101436 +#define NET_HEADER_FIELD_PAYLOAD_TYPE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
101437 +#define NET_HEADER_FIELD_FRAME_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
101438 +#define NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
101439 +
101440 +
101441 +typedef uint8_t headerFieldGre_t;
101442 +
101443 +#define NET_HEADER_FIELD_GRE_TYPE (1)
101444 +#define NET_HEADER_FIELD_GRE_ALL_FIELDS ((NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
101445 +
101446 +
101447 +typedef uint8_t headerFieldMinencap_t;
101448 +
101449 +#define NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
101450 +#define NET_HEADER_FIELD_MINENCAP_DST_IP (NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
101451 +#define NET_HEADER_FIELD_MINENCAP_TYPE (NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
101452 +#define NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
101453 +
101454 +
101455 +typedef uint8_t headerFieldIpsecAh_t;
101456 +
101457 +#define NET_HEADER_FIELD_IPSEC_AH_SPI (1)
101458 +#define NET_HEADER_FIELD_IPSEC_AH_NH (NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
101459 +#define NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
101460 +
101461 +
101462 +typedef uint8_t headerFieldIpsecEsp_t;
101463 +
101464 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
101465 +#define NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
101466 +#define NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
101467 +
101468 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
101469 +
101470 +
101471 +typedef uint8_t headerFieldMpls_t;
101472 +
101473 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
101474 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
101475 +
101476 +
101477 +typedef uint8_t headerFieldMacsec_t;
101478 +
101479 +#define NET_HEADER_FIELD_MACSEC_SECTAG (1)
101480 +#define NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
101481 +
101482 +
101483 +typedef enum {
101484 + HEADER_TYPE_NONE = 0,
101485 + HEADER_TYPE_PAYLOAD,
101486 + HEADER_TYPE_ETH,
101487 + HEADER_TYPE_VLAN,
101488 + HEADER_TYPE_IPv4,
101489 + HEADER_TYPE_IPv6,
101490 + HEADER_TYPE_IP,
101491 + HEADER_TYPE_TCP,
101492 + HEADER_TYPE_UDP,
101493 + HEADER_TYPE_UDP_LITE,
101494 + HEADER_TYPE_IPHC,
101495 + HEADER_TYPE_SCTP,
101496 + HEADER_TYPE_SCTP_CHUNK_DATA,
101497 + HEADER_TYPE_PPPoE,
101498 + HEADER_TYPE_PPP,
101499 + HEADER_TYPE_PPPMUX,
101500 + HEADER_TYPE_PPPMUX_SUBFRAME,
101501 + HEADER_TYPE_L2TPv2,
101502 + HEADER_TYPE_L2TPv3_CTRL,
101503 + HEADER_TYPE_L2TPv3_SESS,
101504 + HEADER_TYPE_LLC,
101505 + HEADER_TYPE_LLC_SNAP,
101506 + HEADER_TYPE_NLPID,
101507 + HEADER_TYPE_SNAP,
101508 + HEADER_TYPE_MPLS,
101509 + HEADER_TYPE_IPSEC_AH,
101510 + HEADER_TYPE_IPSEC_ESP,
101511 + HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
101512 + HEADER_TYPE_MACSEC,
101513 + HEADER_TYPE_GRE,
101514 + HEADER_TYPE_MINENCAP,
101515 + HEADER_TYPE_DCCP,
101516 + HEADER_TYPE_ICMP,
101517 + HEADER_TYPE_IGMP,
101518 + HEADER_TYPE_ARP,
101519 + HEADER_TYPE_CAPWAP,
101520 + HEADER_TYPE_CAPWAP_DTLS,
101521 + HEADER_TYPE_RFC2684,
101522 + HEADER_TYPE_USER_DEFINED_L2,
101523 + HEADER_TYPE_USER_DEFINED_L3,
101524 + HEADER_TYPE_USER_DEFINED_L4,
101525 + HEADER_TYPE_USER_DEFINED_SHIM1,
101526 + HEADER_TYPE_USER_DEFINED_SHIM2,
101527 + MAX_HEADER_TYPE_COUNT
101528 +} e_NetHeaderType;
101529 +
101530 +
101531 +#endif /* __NET_EXT_H */
101532 --- /dev/null
101533 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
101534 @@ -0,0 +1,48 @@
101535 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101536 + * All rights reserved.
101537 + *
101538 + * Redistribution and use in source and binary forms, with or without
101539 + * modification, are permitted provided that the following conditions are met:
101540 + * * Redistributions of source code must retain the above copyright
101541 + * notice, this list of conditions and the following disclaimer.
101542 + * * Redistributions in binary form must reproduce the above copyright
101543 + * notice, this list of conditions and the following disclaimer in the
101544 + * documentation and/or other materials provided with the distribution.
101545 + * * Neither the name of Freescale Semiconductor nor the
101546 + * names of its contributors may be used to endorse or promote products
101547 + * derived from this software without specific prior written permission.
101548 + *
101549 + *
101550 + * ALTERNATIVELY, this software may be distributed under the terms of the
101551 + * GNU General Public License ("GPL") as published by the Free Software
101552 + * Foundation, either version 2 of that License or (at your option) any
101553 + * later version.
101554 + *
101555 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101556 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101557 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101558 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101559 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101560 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101561 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101562 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101563 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101564 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101565 + */
101566 +
101567 +
101568 +/**************************************************************************//**
101569 + @File std_ext.h
101570 +
101571 + @Description General Standard Definitions
101572 +*//***************************************************************************/
101573 +
101574 +#ifndef __STD_EXT_H
101575 +#define __STD_EXT_H
101576 +
101577 +
101578 +#include "types_ext.h"
101579 +#include "ncsw_ext.h"
101580 +
101581 +
101582 +#endif /* __STD_EXT_H */
101583 --- /dev/null
101584 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
101585 @@ -0,0 +1,49 @@
101586 +/*
101587 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101588 + *
101589 + * Redistribution and use in source and binary forms, with or without
101590 + * modification, are permitted provided that the following conditions are met:
101591 + * * Redistributions of source code must retain the above copyright
101592 + * notice, this list of conditions and the following disclaimer.
101593 + * * Redistributions in binary form must reproduce the above copyright
101594 + * notice, this list of conditions and the following disclaimer in the
101595 + * documentation and/or other materials provided with the distribution.
101596 + * * Neither the name of Freescale Semiconductor nor the
101597 + * names of its contributors may be used to endorse or promote products
101598 + * derived from this software without specific prior written permission.
101599 + *
101600 + *
101601 + * ALTERNATIVELY, this software may be distributed under the terms of the
101602 + * GNU General Public License ("GPL") as published by the Free Software
101603 + * Foundation, either version 2 of that License or (at your option) any
101604 + * later version.
101605 + *
101606 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101607 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101608 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101609 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101610 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101611 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101612 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101613 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101614 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101615 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101616 + */
101617 +
101618 +
101619 +#ifndef __STDARG_EXT_H
101620 +#define __STDARG_EXT_H
101621 +
101622 +
101623 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
101624 +#include <stdarg.h>
101625 +
101626 +#else
101627 +#include <stdarg.h>
101628 +
101629 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101630 +
101631 +#include "std_ext.h"
101632 +
101633 +
101634 +#endif /* __STDARG_EXT_H */
101635 --- /dev/null
101636 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
101637 @@ -0,0 +1,162 @@
101638 +/*
101639 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101640 + *
101641 + * Redistribution and use in source and binary forms, with or without
101642 + * modification, are permitted provided that the following conditions are met:
101643 + * * Redistributions of source code must retain the above copyright
101644 + * notice, this list of conditions and the following disclaimer.
101645 + * * Redistributions in binary form must reproduce the above copyright
101646 + * notice, this list of conditions and the following disclaimer in the
101647 + * documentation and/or other materials provided with the distribution.
101648 + * * Neither the name of Freescale Semiconductor nor the
101649 + * names of its contributors may be used to endorse or promote products
101650 + * derived from this software without specific prior written permission.
101651 + *
101652 + *
101653 + * ALTERNATIVELY, this software may be distributed under the terms of the
101654 + * GNU General Public License ("GPL") as published by the Free Software
101655 + * Foundation, either version 2 of that License or (at your option) any
101656 + * later version.
101657 + *
101658 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101659 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101660 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101661 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101662 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101663 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101664 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101665 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101666 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101667 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101668 + */
101669 +
101670 +
101671 +
101672 +#ifndef __STDLIB_EXT_H
101673 +#define __STDLIB_EXT_H
101674 +
101675 +
101676 +#if (defined(NCSW_LINUX)) && defined(__KERNEL__)
101677 +#include "stdarg_ext.h"
101678 +#include "std_ext.h"
101679 +
101680 +
101681 +/**
101682 + * strtoul - convert a string to an uint32_t
101683 + * @cp: The start of the string
101684 + * @endp: A pointer to the end of the parsed string will be placed here
101685 + * @base: The number base to use
101686 + */
101687 +uint32_t strtoul(const char *cp,char **endp,uint32_t base);
101688 +
101689 +/**
101690 + * strtol - convert a string to a int32_t
101691 + * @cp: The start of the string
101692 + * @endp: A pointer to the end of the parsed string will be placed here
101693 + * @base: The number base to use
101694 + */
101695 +long strtol(const char *cp,char **endp,uint32_t base);
101696 +
101697 +/**
101698 + * strtoull - convert a string to an uint64_t
101699 + * @cp: The start of the string
101700 + * @endp: A pointer to the end of the parsed string will be placed here
101701 + * @base: The number base to use
101702 + */
101703 +uint64_t strtoull(const char *cp,char **endp,uint32_t base);
101704 +
101705 +/**
101706 + * strtoll - convert a string to a int64 long
101707 + * @cp: The start of the string
101708 + * @endp: A pointer to the end of the parsed string will be placed here
101709 + * @base: The number base to use
101710 + */
101711 +long long strtoll(const char *cp,char **endp,uint32_t base);
101712 +
101713 +/**
101714 + * atoi - convert a character to a int
101715 + * @s: The start of the string
101716 + */
101717 +int atoi(const char *s);
101718 +
101719 +/**
101720 + * strnlen - Find the length of a length-limited string
101721 + * @s: The string to be sized
101722 + * @count: The maximum number of bytes to search
101723 + */
101724 +size_t strnlen(const char * s, size_t count);
101725 +
101726 +/**
101727 + * strlen - Find the length of a string
101728 + * @s: The string to be sized
101729 + */
101730 +size_t strlen(const char * s);
101731 +
101732 +/**
101733 + * strtok - Split a string into tokens
101734 + * @s: The string to be searched
101735 + * @ct: The characters to search for
101736 + *
101737 + * WARNING: strtok is deprecated, use strsep instead.
101738 + */
101739 +char * strtok(char * s,const char * ct);
101740 +
101741 +/**
101742 + * strncpy - Copy a length-limited, %NUL-terminated string
101743 + * @dest: Where to copy the string to
101744 + * @src: Where to copy the string from
101745 + * @count: The maximum number of bytes to copy
101746 + *
101747 + * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
101748 + * However, the result is not %NUL-terminated if the source exceeds
101749 + * @count bytes.
101750 + */
101751 +char * strncpy(char * dest,const char *src,size_t count);
101752 +
101753 +/**
101754 + * strcpy - Copy a %NUL terminated string
101755 + * @dest: Where to copy the string to
101756 + * @src: Where to copy the string from
101757 + */
101758 +char * strcpy(char * dest,const char *src);
101759 +
101760 +/**
101761 + * vsscanf - Unformat a buffer into a list of arguments
101762 + * @buf: input buffer
101763 + * @fmt: format of buffer
101764 + * @args: arguments
101765 + */
101766 +int vsscanf(const char * buf, const char * fmt, va_list args);
101767 +
101768 +/**
101769 + * vsnprintf - Format a string and place it in a buffer
101770 + * @buf: The buffer to place the result into
101771 + * @size: The size of the buffer, including the trailing null space
101772 + * @fmt: The format string to use
101773 + * @args: Arguments for the format string
101774 + *
101775 + * Call this function if you are already dealing with a va_list.
101776 + * You probably want snprintf instead.
101777 + */
101778 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
101779 +
101780 +/**
101781 + * vsprintf - Format a string and place it in a buffer
101782 + * @buf: The buffer to place the result into
101783 + * @fmt: The format string to use
101784 + * @args: Arguments for the format string
101785 + *
101786 + * Call this function if you are already dealing with a va_list.
101787 + * You probably want sprintf instead.
101788 + */
101789 +int vsprintf(char *buf, const char *fmt, va_list args);
101790 +
101791 +#else
101792 +#include <stdlib.h>
101793 +#include <stdio.h>
101794 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101795 +
101796 +#include "std_ext.h"
101797 +
101798 +
101799 +#endif /* __STDLIB_EXT_H */
101800 --- /dev/null
101801 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
101802 @@ -0,0 +1,56 @@
101803 +/*
101804 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101805 + *
101806 + * Redistribution and use in source and binary forms, with or without
101807 + * modification, are permitted provided that the following conditions are met:
101808 + * * Redistributions of source code must retain the above copyright
101809 + * notice, this list of conditions and the following disclaimer.
101810 + * * Redistributions in binary form must reproduce the above copyright
101811 + * notice, this list of conditions and the following disclaimer in the
101812 + * documentation and/or other materials provided with the distribution.
101813 + * * Neither the name of Freescale Semiconductor nor the
101814 + * names of its contributors may be used to endorse or promote products
101815 + * derived from this software without specific prior written permission.
101816 + *
101817 + *
101818 + * ALTERNATIVELY, this software may be distributed under the terms of the
101819 + * GNU General Public License ("GPL") as published by the Free Software
101820 + * Foundation, either version 2 of that License or (at your option) any
101821 + * later version.
101822 + *
101823 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101824 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101825 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101826 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101827 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101828 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101829 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101830 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101831 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101832 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101833 + */
101834 +
101835 +
101836 +#ifndef __STRING_EXT_H
101837 +#define __STRING_EXT_H
101838 +
101839 +
101840 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
101841 +#include <linux/kernel.h>
101842 +#include <linux/string.h>
101843 +extern char * strtok ( char * str, const char * delimiters );
101844 +
101845 +#elif defined(__KERNEL__)
101846 +#include "linux/types.h"
101847 +#include "linux/posix_types.h"
101848 +#include "linux/string.h"
101849 +
101850 +#else
101851 +#include <string.h>
101852 +
101853 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101854 +
101855 +#include "std_ext.h"
101856 +
101857 +
101858 +#endif /* __STRING_EXT_H */
101859 --- /dev/null
101860 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
101861 @@ -0,0 +1,62 @@
101862 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101863 + * All rights reserved.
101864 + *
101865 + * Redistribution and use in source and binary forms, with or without
101866 + * modification, are permitted provided that the following conditions are met:
101867 + * * Redistributions of source code must retain the above copyright
101868 + * notice, this list of conditions and the following disclaimer.
101869 + * * Redistributions in binary form must reproduce the above copyright
101870 + * notice, this list of conditions and the following disclaimer in the
101871 + * documentation and/or other materials provided with the distribution.
101872 + * * Neither the name of Freescale Semiconductor nor the
101873 + * names of its contributors may be used to endorse or promote products
101874 + * derived from this software without specific prior written permission.
101875 + *
101876 + *
101877 + * ALTERNATIVELY, this software may be distributed under the terms of the
101878 + * GNU General Public License ("GPL") as published by the Free Software
101879 + * Foundation, either version 2 of that License or (at your option) any
101880 + * later version.
101881 + *
101882 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101883 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101884 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101885 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101886 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101887 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101888 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101889 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101890 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101891 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101892 + */
101893 +
101894 +
101895 +/**************************************************************************//**
101896 + @File types_ext.h
101897 +
101898 + @Description General types Standard Definitions
101899 +*//***************************************************************************/
101900 +
101901 +#ifndef __TYPES_EXT_H
101902 +#define __TYPES_EXT_H
101903 +
101904 +#if defined(NCSW_LINUX)
101905 +#include "types_linux.h"
101906 +
101907 +#elif defined(NCSW_VXWORKS)
101908 +#include "types_vxworks.h"
101909 +
101910 +#elif defined(__GNUC__) && defined(__cplusplus)
101911 +#include "types_bb_gpp.h"
101912 +
101913 +#elif defined(__GNUC__)
101914 +#include "types_bb_gcc.h"
101915 +
101916 +#elif defined(__ghs__)
101917 +#include "types_ghs.h"
101918 +
101919 +#else
101920 +#include "types_dflt.h"
101921 +#endif /* defined (__ROCOO__) */
101922 +
101923 +#endif /* __TYPES_EXT_H */
101924 --- /dev/null
101925 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
101926 @@ -0,0 +1,56 @@
101927 +/*
101928 + * Copyright 2012 Freescale Semiconductor Inc.
101929 + *
101930 + * Redistribution and use in source and binary forms, with or without
101931 + * modification, are permitted provided that the following conditions are met:
101932 + * * Redistributions of source code must retain the above copyright
101933 + * notice, this list of conditions and the following disclaimer.
101934 + * * Redistributions in binary form must reproduce the above copyright
101935 + * notice, this list of conditions and the following disclaimer in the
101936 + * documentation and/or other materials provided with the distribution.
101937 + * * Neither the name of Freescale Semiconductor nor the
101938 + * names of its contributors may be used to endorse or promote products
101939 + * derived from this software without specific prior written permission.
101940 + *
101941 + *
101942 + * ALTERNATIVELY, this software may be distributed under the terms of the
101943 + * GNU General Public License ("GPL") as published by the Free Software
101944 + * Foundation, either version 2 of that License or (at your option) any
101945 + * later version.
101946 + *
101947 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101948 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101949 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101950 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101951 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101952 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101953 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101954 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101955 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101956 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101957 + */
101958 +
101959 +
101960 +/**************************************************************************//**
101961 + @File debug_ext.h
101962 +
101963 + @Description Debug mode definitions.
101964 +*//***************************************************************************/
101965 +
101966 +#ifndef __XX_COMMON_H
101967 +#define __XX_COMMON_H
101968 +
101969 +/*****************************************************************************
101970 + * UNIFIED MODULE CODES
101971 + *****************************************************************************/
101972 +#define MODULE_UNKNOWN 0x00000000
101973 +#define MODULE_FM 0x00010000
101974 +#define MODULE_FM_MURAM 0x00020000
101975 +#define MODULE_FM_PCD 0x00030000
101976 +#define MODULE_FM_RTC 0x00040000
101977 +#define MODULE_FM_MAC 0x00050000
101978 +#define MODULE_FM_PORT 0x00060000
101979 +#define MODULE_MM 0x00070000
101980 +#define MODULE_FM_SP 0x00080000
101981 +#define MODULE_FM_MACSEC 0x00090000
101982 +#endif /* __XX_COMMON_H */
101983 --- /dev/null
101984 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
101985 @@ -0,0 +1,791 @@
101986 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101987 + * All rights reserved.
101988 + *
101989 + * Redistribution and use in source and binary forms, with or without
101990 + * modification, are permitted provided that the following conditions are met:
101991 + * * Redistributions of source code must retain the above copyright
101992 + * notice, this list of conditions and the following disclaimer.
101993 + * * Redistributions in binary form must reproduce the above copyright
101994 + * notice, this list of conditions and the following disclaimer in the
101995 + * documentation and/or other materials provided with the distribution.
101996 + * * Neither the name of Freescale Semiconductor nor the
101997 + * names of its contributors may be used to endorse or promote products
101998 + * derived from this software without specific prior written permission.
101999 + *
102000 + *
102001 + * ALTERNATIVELY, this software may be distributed under the terms of the
102002 + * GNU General Public License ("GPL") as published by the Free Software
102003 + * Foundation, either version 2 of that License or (at your option) any
102004 + * later version.
102005 + *
102006 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102007 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102008 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102009 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102010 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102011 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102012 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102013 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102014 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102015 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102016 + */
102017 +
102018 +
102019 +/**************************************************************************//**
102020 + @File xx_ext.h
102021 +
102022 + @Description Prototypes, externals and typedefs for system-supplied
102023 + (external) routines
102024 +*//***************************************************************************/
102025 +
102026 +#ifndef __XX_EXT_H
102027 +#define __XX_EXT_H
102028 +
102029 +#include "std_ext.h"
102030 +#include "xx_common.h"
102031 +#include "part_ext.h"
102032 +
102033 +
102034 +
102035 +/**************************************************************************//**
102036 + @Group xx_id XX Interface (System call hooks)
102037 +
102038 + @Description Prototypes, externals and typedefs for system-supplied
102039 + (external) routines
102040 +
102041 + @{
102042 +*//***************************************************************************/
102043 +
102044 +#ifdef DEBUG_XX_MALLOC
102045 +void * XX_MallocDebug(uint32_t size, char *fname, int line);
102046 +
102047 +void * XX_MallocSmartDebug(uint32_t size,
102048 + int memPartitionId,
102049 + uint32_t alignment,
102050 + char *fname,
102051 + int line);
102052 +
102053 +#define XX_Malloc(sz) \
102054 + XX_MallocDebug((sz), __FILE__, __LINE__)
102055 +
102056 +#define XX_MallocSmart(sz, memt, al) \
102057 + XX_MallocSmartDebug((sz), (memt), (al), __FILE__, __LINE__)
102058 +
102059 +#else /* not DEBUG_XX_MALLOC */
102060 +/**************************************************************************//**
102061 + @Function XX_Malloc
102062 +
102063 + @Description allocates contiguous block of memory.
102064 +
102065 + @Param[in] size - Number of bytes to allocate.
102066 +
102067 + @Return The address of the newly allocated block on success, NULL on failure.
102068 +*//***************************************************************************/
102069 +void * XX_Malloc(uint32_t size);
102070 +
102071 +/**************************************************************************//**
102072 + @Function XX_MallocSmart
102073 +
102074 + @Description Allocates contiguous block of memory in a specified
102075 + alignment and from the specified segment.
102076 +
102077 + @Param[in] size - Number of bytes to allocate.
102078 + @Param[in] memPartitionId - Memory partition ID; The value zero must
102079 + be mapped to the default heap partition.
102080 + @Param[in] alignment - Required memory alignment (in bytes).
102081 +
102082 + @Return The address of the newly allocated block on success, NULL on failure.
102083 +*//***************************************************************************/
102084 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment);
102085 +#endif /* not DEBUG_XX_MALLOC */
102086 +
102087 +/**************************************************************************//**
102088 + @Function XX_FreeSmart
102089 +
102090 + @Description Frees the memory block pointed to by "p".
102091 + Only for memory allocated by XX_MallocSmart
102092 +
102093 + @Param[in] p_Memory - pointer to the memory block.
102094 +
102095 + @Return None.
102096 +*//***************************************************************************/
102097 +void XX_FreeSmart(void *p_Memory);
102098 +
102099 +/**************************************************************************//**
102100 + @Function XX_Free
102101 +
102102 + @Description frees the memory block pointed to by "p".
102103 +
102104 + @Param[in] p_Memory - pointer to the memory block.
102105 +
102106 + @Return None.
102107 +*//***************************************************************************/
102108 +void XX_Free(void *p_Memory);
102109 +
102110 +/**************************************************************************//**
102111 + @Function XX_Print
102112 +
102113 + @Description print a string.
102114 +
102115 + @Param[in] str - string to print.
102116 +
102117 + @Return None.
102118 +*//***************************************************************************/
102119 +void XX_Print(char *str, ...);
102120 +
102121 +/**************************************************************************//**
102122 + @Function XX_SetIntr
102123 +
102124 + @Description Set an interrupt service routine for a specific interrupt source.
102125 +
102126 + @Param[in] irq - Interrupt ID (system-specific number).
102127 + @Param[in] f_Isr - Callback routine that will be called when the interrupt occurs.
102128 + @Param[in] handle - The argument for the user callback routine.
102129 +
102130 + @Return E_OK on success; error code otherwise..
102131 +*//***************************************************************************/
102132 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle);
102133 +
102134 +/**************************************************************************//**
102135 + @Function XX_FreeIntr
102136 +
102137 + @Description Free a specific interrupt and a specific callback routine.
102138 +
102139 + @Param[in] irq - Interrupt ID (system-specific number).
102140 +
102141 + @Return E_OK on success; error code otherwise..
102142 +*//***************************************************************************/
102143 +t_Error XX_FreeIntr(int irq);
102144 +
102145 +/**************************************************************************//**
102146 + @Function XX_EnableIntr
102147 +
102148 + @Description Enable a specific interrupt.
102149 +
102150 + @Param[in] irq - Interrupt ID (system-specific number).
102151 +
102152 + @Return E_OK on success; error code otherwise..
102153 +*//***************************************************************************/
102154 +t_Error XX_EnableIntr(int irq);
102155 +
102156 +/**************************************************************************//**
102157 + @Function XX_DisableIntr
102158 +
102159 + @Description Disable a specific interrupt.
102160 +
102161 + @Param[in] irq - Interrupt ID (system-specific number).
102162 +
102163 + @Return E_OK on success; error code otherwise..
102164 +*//***************************************************************************/
102165 +t_Error XX_DisableIntr(int irq);
102166 +
102167 +/**************************************************************************//**
102168 + @Function XX_DisableAllIntr
102169 +
102170 + @Description Disable all interrupts by masking them at the CPU.
102171 +
102172 + @Return A value that represents the interrupts state before the
102173 + operation, and should be passed to the matching
102174 + XX_RestoreAllIntr() call.
102175 +*//***************************************************************************/
102176 +uint32_t XX_DisableAllIntr(void);
102177 +
102178 +/**************************************************************************//**
102179 + @Function XX_RestoreAllIntr
102180 +
102181 + @Description Restore previous state of interrupts level at the CPU.
102182 +
102183 + @Param[in] flags - A value that represents the interrupts state to restore,
102184 + as returned by the matching call for XX_DisableAllIntr().
102185 +
102186 + @Return None.
102187 +*//***************************************************************************/
102188 +void XX_RestoreAllIntr(uint32_t flags);
102189 +
102190 +
102191 +/**************************************************************************//**
102192 + @Function XX_Exit
102193 +
102194 + @Description Stop execution and report status (where it is applicable)
102195 +
102196 + @Param[in] status - exit status
102197 +*//***************************************************************************/
102198 +void XX_Exit(int status);
102199 +
102200 +
102201 +/*****************************************************************************/
102202 +/* Tasklet Service Routines */
102203 +/*****************************************************************************/
102204 +typedef t_Handle t_TaskletHandle;
102205 +
102206 +/**************************************************************************//**
102207 + @Function XX_InitTasklet
102208 +
102209 + @Description Create and initialize a tasklet object.
102210 +
102211 + @Param[in] routine - A routine to be ran as a tasklet.
102212 + @Param[in] data - An argument to pass to the tasklet.
102213 +
102214 + @Return Tasklet handle is returned on success. NULL is returned otherwise.
102215 +*//***************************************************************************/
102216 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data);
102217 +
102218 +/**************************************************************************//**
102219 + @Function XX_FreeTasklet
102220 +
102221 + @Description Free a tasklet object.
102222 +
102223 + @Param[in] h_Tasklet - A handle to a tasklet to be free.
102224 +
102225 + @Return None.
102226 +*//***************************************************************************/
102227 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet);
102228 +
102229 +/**************************************************************************//**
102230 + @Function XX_ScheduleTask
102231 +
102232 + @Description Schedule a tasklet object.
102233 +
102234 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102235 + @Param[in] immediate - Indicate whether to schedule this tasklet on
102236 + the immediate queue or on the delayed one.
102237 +
102238 + @Return 0 - on success. Error code - otherwise.
102239 +*//***************************************************************************/
102240 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate);
102241 +
102242 +/**************************************************************************//**
102243 + @Function XX_FlushScheduledTasks
102244 +
102245 + @Description Flush all tasks there are in the scheduled tasks queue.
102246 +
102247 + @Return None.
102248 +*//***************************************************************************/
102249 +void XX_FlushScheduledTasks(void);
102250 +
102251 +/**************************************************************************//**
102252 + @Function XX_TaskletIsQueued
102253 +
102254 + @Description Check if task is queued.
102255 +
102256 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102257 +
102258 + @Return 1 - task is queued. 0 - otherwise.
102259 +*//***************************************************************************/
102260 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet);
102261 +
102262 +/**************************************************************************//**
102263 + @Function XX_SetTaskletData
102264 +
102265 + @Description Set data to a scheduled task. Used to change data of already
102266 + scheduled task.
102267 +
102268 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102269 + @Param[in] data - Data to be set.
102270 +*//***************************************************************************/
102271 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data);
102272 +
102273 +/**************************************************************************//**
102274 + @Function XX_GetTaskletData
102275 +
102276 + @Description Get the data of scheduled task.
102277 +
102278 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102279 +
102280 + @Return handle to the data of the task.
102281 +*//***************************************************************************/
102282 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet);
102283 +
102284 +/**************************************************************************//**
102285 + @Function XX_BottomHalf
102286 +
102287 + @Description Bottom half implementation, invoked by the interrupt handler.
102288 +
102289 + This routine handles all bottom-half tasklets with interrupts
102290 + enabled.
102291 +
102292 + @Return None.
102293 +*//***************************************************************************/
102294 +void XX_BottomHalf(void);
102295 +
102296 +
102297 +/*****************************************************************************/
102298 +/* Spinlock Service Routines */
102299 +/*****************************************************************************/
102300 +
102301 +/**************************************************************************//**
102302 + @Function XX_InitSpinlock
102303 +
102304 + @Description Creates a spinlock.
102305 +
102306 + @Return Spinlock handle is returned on success; NULL otherwise.
102307 +*//***************************************************************************/
102308 +t_Handle XX_InitSpinlock(void);
102309 +
102310 +/**************************************************************************//**
102311 + @Function XX_FreeSpinlock
102312 +
102313 + @Description Frees the memory allocated for the spinlock creation.
102314 +
102315 + @Param[in] h_Spinlock - A handle to a spinlock.
102316 +
102317 + @Return None.
102318 +*//***************************************************************************/
102319 +void XX_FreeSpinlock(t_Handle h_Spinlock);
102320 +
102321 +/**************************************************************************//**
102322 + @Function XX_LockSpinlock
102323 +
102324 + @Description Locks a spinlock.
102325 +
102326 + @Param[in] h_Spinlock - A handle to a spinlock.
102327 +
102328 + @Return None.
102329 +*//***************************************************************************/
102330 +void XX_LockSpinlock(t_Handle h_Spinlock);
102331 +
102332 +/**************************************************************************//**
102333 + @Function XX_UnlockSpinlock
102334 +
102335 + @Description Unlocks a spinlock.
102336 +
102337 + @Param[in] h_Spinlock - A handle to a spinlock.
102338 +
102339 + @Return None.
102340 +*//***************************************************************************/
102341 +void XX_UnlockSpinlock(t_Handle h_Spinlock);
102342 +
102343 +/**************************************************************************//**
102344 + @Function XX_LockIntrSpinlock
102345 +
102346 + @Description Locks a spinlock (interrupt safe).
102347 +
102348 + @Param[in] h_Spinlock - A handle to a spinlock.
102349 +
102350 + @Return A value that represents the interrupts state before the
102351 + operation, and should be passed to the matching
102352 + XX_UnlockIntrSpinlock() call.
102353 +*//***************************************************************************/
102354 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock);
102355 +
102356 +/**************************************************************************//**
102357 + @Function XX_UnlockIntrSpinlock
102358 +
102359 + @Description Unlocks a spinlock (interrupt safe).
102360 +
102361 + @Param[in] h_Spinlock - A handle to a spinlock.
102362 + @Param[in] intrFlags - A value that represents the interrupts state to
102363 + restore, as returned by the matching call for
102364 + XX_LockIntrSpinlock().
102365 +
102366 + @Return None.
102367 +*//***************************************************************************/
102368 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags);
102369 +
102370 +
102371 +/*****************************************************************************/
102372 +/* Timers Service Routines */
102373 +/*****************************************************************************/
102374 +
102375 +/**************************************************************************//**
102376 + @Function XX_CurrentTime
102377 +
102378 + @Description Returns current system time.
102379 +
102380 + @Return Current system time (in milliseconds).
102381 +*//***************************************************************************/
102382 +uint32_t XX_CurrentTime(void);
102383 +
102384 +/**************************************************************************//**
102385 + @Function XX_CreateTimer
102386 +
102387 + @Description Creates a timer.
102388 +
102389 + @Return Timer handle is returned on success; NULL otherwise.
102390 +*//***************************************************************************/
102391 +t_Handle XX_CreateTimer(void);
102392 +
102393 +/**************************************************************************//**
102394 + @Function XX_FreeTimer
102395 +
102396 + @Description Frees the memory allocated for the timer creation.
102397 +
102398 + @Param[in] h_Timer - A handle to a timer.
102399 +
102400 + @Return None.
102401 +*//***************************************************************************/
102402 +void XX_FreeTimer(t_Handle h_Timer);
102403 +
102404 +/**************************************************************************//**
102405 + @Function XX_StartTimer
102406 +
102407 + @Description Starts a timer.
102408 +
102409 + The user can select to start the timer as periodic timer or as
102410 + one-shot timer. The user should provide a callback routine that
102411 + will be called when the timer expires.
102412 +
102413 + @Param[in] h_Timer - A handle to a timer.
102414 + @Param[in] msecs - Timer expiration period (in milliseconds).
102415 + @Param[in] periodic - TRUE for a periodic timer;
102416 + FALSE for a one-shot timer..
102417 + @Param[in] f_TimerExpired - A callback routine to be called when the
102418 + timer expires.
102419 + @Param[in] h_Arg - The argument to pass in the timer-expired
102420 + callback routine.
102421 +
102422 + @Return None.
102423 +*//***************************************************************************/
102424 +void XX_StartTimer(t_Handle h_Timer,
102425 + uint32_t msecs,
102426 + bool periodic,
102427 + void (*f_TimerExpired)(t_Handle h_Arg),
102428 + t_Handle h_Arg);
102429 +
102430 +/**************************************************************************//**
102431 + @Function XX_StopTimer
102432 +
102433 + @Description Frees the memory allocated for the timer creation.
102434 +
102435 + @Param[in] h_Timer - A handle to a timer.
102436 +
102437 + @Return None.
102438 +*//***************************************************************************/
102439 +void XX_StopTimer(t_Handle h_Timer);
102440 +
102441 +/**************************************************************************//**
102442 + @Function XX_ModTimer
102443 +
102444 + @Description Updates the expiration time of a timer.
102445 +
102446 + This routine adds the given time to the current system time,
102447 + and sets this value as the new expiration time of the timer.
102448 +
102449 + @Param[in] h_Timer - A handle to a timer.
102450 + @Param[in] msecs - The new interval until timer expiration
102451 + (in milliseconds).
102452 +
102453 + @Return None.
102454 +*//***************************************************************************/
102455 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs);
102456 +
102457 +/**************************************************************************//**
102458 + @Function XX_Sleep
102459 +
102460 + @Description Non-busy wait until the desired time (in milliseconds) has passed.
102461 +
102462 + @Param[in] msecs - The requested sleep time (in milliseconds).
102463 +
102464 + @Return Zero if the requested time has elapsed; Otherwise, the value
102465 + returned will be the unslept amount) in milliseconds.
102466 +
102467 + @Cautions This routine enables interrupts during its wait time.
102468 +*//***************************************************************************/
102469 +uint32_t XX_Sleep(uint32_t msecs);
102470 +
102471 +/**************************************************************************//**
102472 + @Function XX_UDelay
102473 +
102474 + @Description Busy-wait until the desired time (in microseconds) has passed.
102475 +
102476 + @Param[in] usecs - The requested delay time (in microseconds).
102477 +
102478 + @Return None.
102479 +
102480 + @Cautions It is highly unrecommended to call this routine during interrupt
102481 + time, because the system time may not be updated properly during
102482 + the delay loop. The behavior of this routine during interrupt
102483 + time is unexpected.
102484 +*//***************************************************************************/
102485 +void XX_UDelay(uint32_t usecs);
102486 +
102487 +
102488 +/*****************************************************************************/
102489 +/* Other Service Routines */
102490 +/*****************************************************************************/
102491 +
102492 +/**************************************************************************//**
102493 + @Function XX_PhysToVirt
102494 +
102495 + @Description Translates a physical address to the matching virtual address.
102496 +
102497 + @Param[in] addr - The physical address to translate.
102498 +
102499 + @Return Virtual address.
102500 +*//***************************************************************************/
102501 +void * XX_PhysToVirt(physAddress_t addr);
102502 +
102503 +/**************************************************************************//**
102504 + @Function XX_VirtToPhys
102505 +
102506 + @Description Translates a virtual address to the matching physical address.
102507 +
102508 + @Param[in] addr - The virtual address to translate.
102509 +
102510 + @Return Physical address.
102511 +*//***************************************************************************/
102512 +physAddress_t XX_VirtToPhys(void *addr);
102513 +
102514 +
102515 +/**************************************************************************//**
102516 + @Group xx_ipc XX Inter-Partition-Communication API
102517 +
102518 + @Description The following API is to be used when working with multiple
102519 + partitions configuration.
102520 +
102521 + @{
102522 +*//***************************************************************************/
102523 +
102524 +#define XX_IPC_MAX_ADDR_NAME_LENGTH 16 /**< Maximum length of an endpoint name string;
102525 + The IPC service can use this constant to limit
102526 + the storage space for IPC endpoint names. */
102527 +
102528 +
102529 +/**************************************************************************//**
102530 + @Function t_IpcMsgCompletion
102531 +
102532 + @Description Callback function used upon IPC non-blocking transaction completion
102533 + to return message buffer to the caller and to forward reply if available.
102534 +
102535 + This callback function may be attached by the source endpoint to any outgoing
102536 + IPC message to indicate a non-blocking send (see also XX_IpcSendMessage() routine).
102537 + Upon completion of an IPC transaction (consisting of a message and an optional reply),
102538 + the IPC service invokes this callback routine to return the message buffer to the sender
102539 + and to provide the received reply, if requested.
102540 +
102541 + User provides this function. Driver invokes it.
102542 +
102543 + @Param[in] h_Module - Abstract handle to the sending module - the same handle as was passed
102544 + in the XX_IpcSendMessage() function; This handle is typically used to point
102545 + to the internal data structure of the source endpoint.
102546 + @Param[in] p_Msg - Pointer to original (sent) message buffer;
102547 + The source endpoint can free (or reuse) this buffer when message
102548 + completion callback is called.
102549 + @Param[in] p_Reply - Pointer to (received) reply buffer;
102550 + This pointer is the same as was provided by the source endpoint in
102551 + XX_IpcSendMessage().
102552 + @Param[in] replyLength - Length (in bytes) of actual data in the reply buffer.
102553 + @Param[in] status - Completion status - E_OK or failure indication, e.g. IPC transaction completion
102554 + timeout.
102555 +
102556 + @Return None
102557 + *//***************************************************************************/
102558 +typedef void (t_IpcMsgCompletion)(t_Handle h_Module,
102559 + uint8_t *p_Msg,
102560 + uint8_t *p_Reply,
102561 + uint32_t replyLength,
102562 + t_Error status);
102563 +
102564 +/**************************************************************************//**
102565 + @Function t_IpcMsgHandler
102566 +
102567 + @Description Callback function used as IPC message handler.
102568 +
102569 + The IPC service invokes message handlers for each IPC message received.
102570 + The actual function pointer should be registered by each destination endpoint
102571 + via the XX_IpcRegisterMsgHandler() routine.
102572 +
102573 + User provides this function. Driver invokes it.
102574 +
102575 + @Param[in] h_Module - Abstract handle to the message handling module - the same handle as
102576 + was passed in the XX_IpcRegisterMsgHandler() function; this handle is
102577 + typically used to point to the internal data structure of the destination
102578 + endpoint.
102579 + @Param[in] p_Msg - Pointer to message buffer with data received from peer.
102580 + @Param[in] msgLength - Length (in bytes) of message data.
102581 + @Param[in] p_Reply - Pointer to reply buffer, to be filled by the message handler and then sent
102582 + by the IPC service;
102583 + The reply buffer is allocated by the IPC service with size equals to the
102584 + replyLength parameter provided in message handler registration (see
102585 + XX_IpcRegisterMsgHandler() function);
102586 + If replyLength was initially specified as zero during message handler registration,
102587 + the IPC service may set this pointer to NULL and assume that a reply is not needed;
102588 + The IPC service is also responsible for freeing the reply buffer after the
102589 + reply has been sent or dismissed.
102590 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
102591 + [In] equals the replyLength parameter provided in message handler
102592 + registration (see XX_IpcRegisterMsgHandler() function), and
102593 + [Out] should be updated by message handler to the actual reply length; if
102594 + this value is set to zero, the IPC service must assume that a reply should
102595 + not be sent;
102596 + Note: If p_Reply is not NULL, p_ReplyLength must not be NULL as well.
102597 +
102598 + @Return E_OK on success; Error code otherwise.
102599 + *//***************************************************************************/
102600 +typedef t_Error (t_IpcMsgHandler)(t_Handle h_Module,
102601 + uint8_t *p_Msg,
102602 + uint32_t msgLength,
102603 + uint8_t *p_Reply,
102604 + uint32_t *p_ReplyLength);
102605 +
102606 +/**************************************************************************//**
102607 + @Function XX_IpcRegisterMsgHandler
102608 +
102609 + @Description IPC mailbox registration.
102610 +
102611 + This function is used for registering an IPC message handler in the IPC service.
102612 + This function is called by each destination endpoint to indicate that it is ready
102613 + to handle incoming messages. The IPC service invokes the message handler upon receiving
102614 + a message addressed to the specified destination endpoint.
102615 +
102616 + @Param[in] addr - The address name string associated with the destination endpoint;
102617 + This address must be unique across the IPC service domain to ensure
102618 + correct message routing.
102619 + @Param[in] f_MsgHandler - Pointer to the message handler callback for processing incoming
102620 + message; invoked by the IPC service upon receiving a message
102621 + addressed to the destination endpoint specified by the addr
102622 + parameter.
102623 + @Param[in] h_Module - Abstract handle to the message handling module, passed unchanged
102624 + to f_MsgHandler callback function.
102625 + @Param[in] replyLength - The maximal data length (in bytes) of any reply that the specified message handler
102626 + may generate; the IPC service provides the message handler with buffer
102627 + for reply according to the length specified here (refer also to the description
102628 + of #t_IpcMsgHandler callback function type);
102629 + This size shall be zero if the message handler never generates replies.
102630 +
102631 + @Return E_OK on success; Error code otherwise.
102632 +*//***************************************************************************/
102633 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
102634 + t_IpcMsgHandler *f_MsgHandler,
102635 + t_Handle h_Module,
102636 + uint32_t replyLength);
102637 +
102638 +/**************************************************************************//**
102639 + @Function XX_IpcUnregisterMsgHandler
102640 +
102641 + @Description Release IPC mailbox routine.
102642 +
102643 + This function is used for unregistering an IPC message handler from the IPC service.
102644 + This function is called by each destination endpoint to indicate that it is no longer
102645 + capable of handling incoming messages.
102646 +
102647 + @Param[in] addr - The address name string associated with the destination endpoint;
102648 + This address is the same as was used when the message handler was
102649 + registered via XX_IpcRegisterMsgHandler().
102650 +
102651 + @Return E_OK on success; Error code otherwise.
102652 +*//***************************************************************************/
102653 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
102654 +
102655 +/**************************************************************************//**
102656 + @Function XX_IpcInitSession
102657 +
102658 + @Description This function is used for creating an IPC session between the source endpoint
102659 + and the destination endpoint.
102660 +
102661 + The actual implementation and representation of a session is left for the IPC service.
102662 + The function returns an abstract handle to the created session. This handle shall be used
102663 + by the source endpoint in subsequent calls to XX_IpcSendMessage().
102664 + The IPC service assumes that before this function is called, no messages are sent from
102665 + the specified source endpoint to the specified destination endpoint.
102666 +
102667 + The IPC service may use a connection-oriented approach or a connectionless approach (or both)
102668 + as described below.
102669 +
102670 + @par Connection-Oriented Approach
102671 +
102672 + The IPC service may implement a session in a connection-oriented approach - when this function is called,
102673 + the IPC service should take the necessary steps to bring up a source-to-destination channel for messages
102674 + and a destination-to-source channel for replies. The returned handle should represent the internal
102675 + representation of these channels.
102676 +
102677 + @par Connectionless Approach
102678 +
102679 + The IPC service may implement a session in a connectionless approach - when this function is called, the
102680 + IPC service should not perform any particular steps, but it must store the pair of source and destination
102681 + addresses in some session representation and return it as a handle. When XX_IpcSendMessage() shall be
102682 + called, the IPC service may use this handle to provide the necessary identifiers for routing the messages
102683 + through the connectionless medium.
102684 +
102685 + @Param[in] destAddr - The address name string associated with the destination endpoint.
102686 + @Param[in] srcAddr - The address name string associated with the source endpoint.
102687 +
102688 + @Return Abstract handle to the initialized session, or NULL on error.
102689 +*//***************************************************************************/
102690 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
102691 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
102692 +
102693 +/**************************************************************************//**
102694 + @Function XX_IpcFreeSession
102695 +
102696 + @Description This function is used for terminating an existing IPC session between a source endpoint
102697 + and a destination endpoint.
102698 +
102699 + The IPC service assumes that after this function is called, no messages shall be sent from
102700 + the associated source endpoint to the associated destination endpoint.
102701 +
102702 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
102703 + returned by the XX_IpcInitSession() function.
102704 +
102705 + @Return E_OK on success; Error code otherwise.
102706 +*//***************************************************************************/
102707 +t_Error XX_IpcFreeSession(t_Handle h_Session);
102708 +
102709 +/**************************************************************************//**
102710 + @Function XX_IpcSendMessage
102711 +
102712 + @Description IPC message send routine.
102713 +
102714 + This function may be used by a source endpoint to send an IPC message to a destination
102715 + endpoint. The source endpoint cannot send a message to the destination endpoint without
102716 + first initiating a session with that destination endpoint via XX_IpcInitSession() routine.
102717 +
102718 + The source endpoint must provide the buffer pointer and length of the outgoing message.
102719 + Optionally, it may also provide a buffer for an expected reply. In the latter case, the
102720 + transaction is not considered complete by the IPC service until the reply has been received.
102721 + If the source endpoint does not provide a reply buffer, the transaction is considered
102722 + complete after the message has been sent. The source endpoint must keep the message (and
102723 + optional reply) buffers valid until the transaction is complete.
102724 +
102725 + @par Non-blocking mode
102726 +
102727 + The source endpoint may request a non-blocking send by providing a non-NULL pointer to a message
102728 + completion callback function (f_Completion). Upon completion of the IPC transaction (consisting of a
102729 + message and an optional reply), the IPC service invokes this callback routine to return the message
102730 + buffer to the sender and to provide the received reply, if requested.
102731 +
102732 + @par Blocking mode
102733 +
102734 + The source endpoint may request a blocking send by setting f_Completion to NULL. The function is
102735 + expected to block until the IPC transaction is complete - either the reply has been received or (if no reply
102736 + was requested) the message has been sent.
102737 +
102738 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
102739 + returned by the XX_IpcInitSession() function.
102740 + @Param[in] p_Msg - Pointer to message buffer to send.
102741 + @Param[in] msgLength - Length (in bytes) of actual data in the message buffer.
102742 + @Param[in] p_Reply - Pointer to reply buffer - if this buffer is not NULL, the IPC service
102743 + fills this buffer with the received reply data;
102744 + In blocking mode, the reply data must be valid when the function returns;
102745 + In non-blocking mode, the reply data is valid when f_Completion is called;
102746 + If this pointer is NULL, no reply is expected.
102747 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
102748 + [In] specifies the maximal length (in bytes) of the reply buffer pointed by
102749 + p_Reply, and
102750 + [Out] in non-blocking mode this value is updated by the IPC service to the
102751 + actual reply length (in bytes).
102752 + @Param[in] f_Completion - Pointer to a completion callback to be used in non-blocking send mode;
102753 + The completion callback is invoked by the IPC service upon
102754 + completion of the IPC transaction (consisting of a message and an optional
102755 + reply);
102756 + If this pointer is NULL, the function is expected to block until the IPC
102757 + transaction is complete.
102758 + @Param[in] h_Arg - Abstract handle to the sending module; passed unchanged to the f_Completion
102759 + callback function as the first argument.
102760 +
102761 + @Return E_OK on success; Error code otherwise.
102762 +*//***************************************************************************/
102763 +t_Error XX_IpcSendMessage(t_Handle h_Session,
102764 + uint8_t *p_Msg,
102765 + uint32_t msgLength,
102766 + uint8_t *p_Reply,
102767 + uint32_t *p_ReplyLength,
102768 + t_IpcMsgCompletion *f_Completion,
102769 + t_Handle h_Arg);
102770 +
102771 +
102772 +/** @} */ /* end of xx_ipc group */
102773 +/** @} */ /* end of xx_id group */
102774 +
102775 +
102776 +#endif /* __XX_EXT_H */
102777 --- /dev/null
102778 +++ b/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
102779 @@ -0,0 +1,56 @@
102780 +/*
102781 + * Copyright 2012 Freescale Semiconductor Inc.
102782 + *
102783 + * Redistribution and use in source and binary forms, with or without
102784 + * modification, are permitted provided that the following conditions are met:
102785 + * * Redistributions of source code must retain the above copyright
102786 + * notice, this list of conditions and the following disclaimer.
102787 + * * Redistributions in binary form must reproduce the above copyright
102788 + * notice, this list of conditions and the following disclaimer in the
102789 + * documentation and/or other materials provided with the distribution.
102790 + * * Neither the name of Freescale Semiconductor nor the
102791 + * names of its contributors may be used to endorse or promote products
102792 + * derived from this software without specific prior written permission.
102793 + *
102794 + *
102795 + * ALTERNATIVELY, this software may be distributed under the terms of the
102796 + * GNU General Public License ("GPL") as published by the Free Software
102797 + * Foundation, either version 2 of that License or (at your option) any
102798 + * later version.
102799 + *
102800 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102801 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102802 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102803 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102804 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102805 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102806 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102807 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102808 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102809 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102810 + */
102811 +
102812 +#ifndef __dflags_h
102813 +#define __dflags_h
102814 +
102815 +
102816 +#define NCSW_LINUX
102817 +
102818 +#define LS1043
102819 +
102820 +#define DEBUG_ERRORS 1
102821 +
102822 +#if defined(DEBUG)
102823 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
102824 +
102825 +#define DEBUG_XX_MALLOC
102826 +#define DEBUG_MEM_LEAKS
102827 +
102828 +#else
102829 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
102830 +#endif /* (DEBUG) */
102831 +
102832 +#define REPORT_EVENTS 1
102833 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
102834 +
102835 +#endif /* __dflags_h */
102836 --- /dev/null
102837 +++ b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
102838 @@ -0,0 +1,53 @@
102839 +#
102840 +# Makefile config for the Freescale NetcommSW
102841 +#
102842 +NET_DPA = $(srctree)/drivers/net
102843 +DRV_DPA = $(srctree)/drivers/net/ethernet/freescale/sdk_dpaa
102844 +FMAN = $(srctree)/drivers/net/ethernet/freescale/sdk_fman
102845 +
102846 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
102847 +ccflags-y +=-include $(FMAN)/p3040_4080_5020_dflags.h
102848 +endif
102849 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
102850 +ccflags-y +=-include $(FMAN)/p1023_dflags.h
102851 +endif
102852 +ifdef CONFIG_FMAN_V3H
102853 +ccflags-y +=-include $(FMAN)/fmanv3h_dflags.h
102854 +endif
102855 +ifdef CONFIG_FMAN_V3L
102856 +ccflags-y +=-include $(FMAN)/fmanv3l_dflags.h
102857 +endif
102858 +ifdef CONFIG_FMAN_ARM
102859 +ccflags-y +=-include $(FMAN)/ls1043_dflags.h
102860 +endif
102861 +
102862 +ccflags-y += -I$(DRV_DPA)/
102863 +ccflags-y += -I$(FMAN)/inc
102864 +ccflags-y += -I$(FMAN)/inc/cores
102865 +ccflags-y += -I$(FMAN)/inc/etc
102866 +ccflags-y += -I$(FMAN)/inc/Peripherals
102867 +ccflags-y += -I$(FMAN)/inc/flib
102868 +
102869 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
102870 +ccflags-y += -I$(FMAN)/inc/integrations/P3040_P4080_P5020
102871 +endif
102872 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
102873 +ccflags-y += -I$(FMAN)/inc/integrations/P1023
102874 +endif
102875 +ifdef CONFIG_FMAN_V3H
102876 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3H
102877 +endif
102878 +ifdef CONFIG_FMAN_V3L
102879 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3L
102880 +endif
102881 +ifdef CONFIG_FMAN_ARM
102882 +ccflags-y += -I$(FMAN)/inc/integrations/LS1043
102883 +endif
102884 +
102885 +ccflags-y += -I$(FMAN)/src/inc
102886 +ccflags-y += -I$(FMAN)/src/inc/system
102887 +ccflags-y += -I$(FMAN)/src/inc/wrapper
102888 +ccflags-y += -I$(FMAN)/src/inc/xx
102889 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd
102890 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/Peripherals
102891 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/integrations
102892 --- /dev/null
102893 +++ b/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
102894 @@ -0,0 +1,65 @@
102895 +/*
102896 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102897 + *
102898 + * Redistribution and use in source and binary forms, with or without
102899 + * modification, are permitted provided that the following conditions are met:
102900 + * * Redistributions of source code must retain the above copyright
102901 + * notice, this list of conditions and the following disclaimer.
102902 + * * Redistributions in binary form must reproduce the above copyright
102903 + * notice, this list of conditions and the following disclaimer in the
102904 + * documentation and/or other materials provided with the distribution.
102905 + * * Neither the name of Freescale Semiconductor nor the
102906 + * names of its contributors may be used to endorse or promote products
102907 + * derived from this software without specific prior written permission.
102908 + *
102909 + *
102910 + * ALTERNATIVELY, this software may be distributed under the terms of the
102911 + * GNU General Public License ("GPL") as published by the Free Software
102912 + * Foundation, either version 2 of that License or (at your option) any
102913 + * later version.
102914 + *
102915 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102916 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102917 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102918 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102919 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102920 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102921 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102922 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102923 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102924 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102925 + */
102926 +
102927 +#ifndef __dflags_h
102928 +#define __dflags_h
102929 +
102930 +
102931 +#define NCSW_LINUX
102932 +#if 0
102933 +#define DEBUG
102934 +#endif
102935 +
102936 +#define P1023
102937 +#define NCSW_PPC_CORE
102938 +
102939 +#define DEBUG_ERRORS 1
102940 +
102941 +#if defined(DEBUG)
102942 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
102943 +
102944 +#define DEBUG_XX_MALLOC
102945 +#define DEBUG_MEM_LEAKS
102946 +
102947 +#else
102948 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
102949 +#endif /* (DEBUG) */
102950 +
102951 +#define REPORT_EVENTS 1
102952 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
102953 +
102954 +#ifdef CONFIG_P4080_SIM
102955 +#error "Do not define CONFIG_P4080_SIM..."
102956 +#endif
102957 +
102958 +
102959 +#endif /* __dflags_h */
102960 --- /dev/null
102961 +++ b/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
102962 @@ -0,0 +1,62 @@
102963 +/*
102964 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102965 + *
102966 + * Redistribution and use in source and binary forms, with or without
102967 + * modification, are permitted provided that the following conditions are met:
102968 + * * Redistributions of source code must retain the above copyright
102969 + * notice, this list of conditions and the following disclaimer.
102970 + * * Redistributions in binary form must reproduce the above copyright
102971 + * notice, this list of conditions and the following disclaimer in the
102972 + * documentation and/or other materials provided with the distribution.
102973 + * * Neither the name of Freescale Semiconductor nor the
102974 + * names of its contributors may be used to endorse or promote products
102975 + * derived from this software without specific prior written permission.
102976 + *
102977 + *
102978 + * ALTERNATIVELY, this software may be distributed under the terms of the
102979 + * GNU General Public License ("GPL") as published by the Free Software
102980 + * Foundation, either version 2 of that License or (at your option) any
102981 + * later version.
102982 + *
102983 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102984 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102985 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102986 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102987 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102988 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102989 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102990 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102991 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102992 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102993 + */
102994 +
102995 +#ifndef __dflags_h
102996 +#define __dflags_h
102997 +
102998 +
102999 +#define NCSW_LINUX
103000 +
103001 +#define P4080
103002 +#define NCSW_PPC_CORE
103003 +
103004 +#define DEBUG_ERRORS 1
103005 +
103006 +#if defined(DEBUG)
103007 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
103008 +
103009 +#define DEBUG_XX_MALLOC
103010 +#define DEBUG_MEM_LEAKS
103011 +
103012 +#else
103013 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
103014 +#endif /* (DEBUG) */
103015 +
103016 +#define REPORT_EVENTS 1
103017 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
103018 +
103019 +#ifdef CONFIG_P4080_SIM
103020 +#define SIMULATOR
103021 +#endif /* CONFIG_P4080_SIM */
103022 +
103023 +
103024 +#endif /* __dflags_h */
103025 --- /dev/null
103026 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/Makefile
103027 @@ -0,0 +1,11 @@
103028 +#
103029 +# Makefile for the Freescale Ethernet controllers
103030 +#
103031 +ccflags-y += -DVERSION=\"\"
103032 +#
103033 +#Include netcomm SW specific definitions
103034 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
103035 +#
103036 +obj-y += system/
103037 +obj-y += wrapper/
103038 +obj-y += xx/
103039 --- /dev/null
103040 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
103041 @@ -0,0 +1,118 @@
103042 +/*
103043 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103044 + *
103045 + * Redistribution and use in source and binary forms, with or without
103046 + * modification, are permitted provided that the following conditions are met:
103047 + * * Redistributions of source code must retain the above copyright
103048 + * notice, this list of conditions and the following disclaimer.
103049 + * * Redistributions in binary form must reproduce the above copyright
103050 + * notice, this list of conditions and the following disclaimer in the
103051 + * documentation and/or other materials provided with the distribution.
103052 + * * Neither the name of Freescale Semiconductor nor the
103053 + * names of its contributors may be used to endorse or promote products
103054 + * derived from this software without specific prior written permission.
103055 + *
103056 + *
103057 + * ALTERNATIVELY, this software may be distributed under the terms of the
103058 + * GNU General Public License ("GPL") as published by the Free Software
103059 + * Foundation, either version 2 of that License or (at your option) any
103060 + * later version.
103061 + *
103062 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103063 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103064 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103065 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103066 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103067 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103068 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103069 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103070 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103071 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103072 + */
103073 +
103074 +#ifndef __SYS_EXT_H
103075 +#define __SYS_EXT_H
103076 +
103077 +#include "std_ext.h"
103078 +
103079 +
103080 +/**************************************************************************//**
103081 + @Group sys_grp System Interfaces
103082 +
103083 + @Description Linux system programming interfaces.
103084 +
103085 + @{
103086 +*//***************************************************************************/
103087 +
103088 +/**************************************************************************//**
103089 + @Group sys_gen_grp System General Interface
103090 +
103091 + @Description General definitions, structures and routines of the linux
103092 + system programming interface.
103093 +
103094 + @{
103095 +*//***************************************************************************/
103096 +
103097 +/**************************************************************************//**
103098 + @Collection Macros for Advanced Configuration Requests
103099 + @{
103100 +*//***************************************************************************/
103101 +#define SYS_MAX_ADV_CONFIG_ARGS 4
103102 + /**< Maximum number of arguments in
103103 + an advanced configuration entry */
103104 +/* @} */
103105 +
103106 +/**************************************************************************//**
103107 + @Description System Object Advanced Configuration Entry
103108 +
103109 + This structure represents a single request for an advanced
103110 + configuration call on the initialized object. An array of such
103111 + requests may be contained in the settings structure of the
103112 + corresponding object.
103113 +
103114 + The maximum number of arguments is limited to #SYS_MAX_ADV_CONFIG_ARGS.
103115 +*//***************************************************************************/
103116 +typedef struct t_SysObjectAdvConfigEntry
103117 +{
103118 + void *p_Function; /**< Pointer to advanced configuration routine */
103119 +
103120 + uintptr_t args[SYS_MAX_ADV_CONFIG_ARGS];
103121 + /**< Array of arguments for the specified routine;
103122 + All arguments should be casted to uint32_t. */
103123 +} t_SysObjectAdvConfigEntry;
103124 +
103125 +
103126 +/** @} */ /* end of sys_gen_grp */
103127 +/** @} */ /* end of sys_grp */
103128 +
103129 +#define NCSW_PARAMS(_num, _params) ADV_CONFIG_PARAMS_##_num _params
103130 +
103131 +#define ADV_CONFIG_PARAMS_1(_type) \
103132 + , (_type)p_Entry->args[0]
103133 +
103134 +#define SET_ADV_CONFIG_ARGS_1(_arg0) \
103135 + p_Entry->args[0] = (uintptr_t )(_arg0); \
103136 +
103137 +#define ARGS(_num, _params) SET_ADV_CONFIG_ARGS_##_num _params
103138 +
103139 +#define ADD_ADV_CONFIG_START(_p_Entries, _maxEntries) \
103140 + { \
103141 + t_SysObjectAdvConfigEntry *p_Entry; \
103142 + t_SysObjectAdvConfigEntry *p_Entrys = (_p_Entries); \
103143 + int i=0, max = (_maxEntries); \
103144 +
103145 +#define ADD_ADV_CONFIG_END \
103146 + }
103147 +
103148 +#define ADV_CONFIG_CHECK_START(_p_Entry) \
103149 + { \
103150 + t_SysObjectAdvConfigEntry *p_Entry = _p_Entry; \
103151 + t_Error errCode; \
103152 +
103153 +#define ADV_CONFIG_CHECK(_handle, _func, _params) \
103154 + if (p_Entry->p_Function == _func) \
103155 + { \
103156 + errCode = _func(_handle _params); \
103157 + } else
103158 +
103159 +#endif /* __SYS_EXT_H */
103160 --- /dev/null
103161 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
103162 @@ -0,0 +1,46 @@
103163 +/*
103164 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103165 + *
103166 + * Redistribution and use in source and binary forms, with or without
103167 + * modification, are permitted provided that the following conditions are met:
103168 + * * Redistributions of source code must retain the above copyright
103169 + * notice, this list of conditions and the following disclaimer.
103170 + * * Redistributions in binary form must reproduce the above copyright
103171 + * notice, this list of conditions and the following disclaimer in the
103172 + * documentation and/or other materials provided with the distribution.
103173 + * * Neither the name of Freescale Semiconductor nor the
103174 + * names of its contributors may be used to endorse or promote products
103175 + * derived from this software without specific prior written permission.
103176 + *
103177 + *
103178 + * ALTERNATIVELY, this software may be distributed under the terms of the
103179 + * GNU General Public License ("GPL") as published by the Free Software
103180 + * Foundation, either version 2 of that License or (at your option) any
103181 + * later version.
103182 + *
103183 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103184 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103185 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103186 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103187 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103188 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103189 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103190 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103191 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103192 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103193 + */
103194 +
103195 +#ifndef __SYS_IO_EXT_H
103196 +#define __SYS_IO_EXT_H
103197 +
103198 +#include "std_ext.h"
103199 +#include "error_ext.h"
103200 +
103201 +
103202 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size);
103203 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr);
103204 +uint64_t SYS_PhysToVirt (uint64_t addr);
103205 +uint64_t SYS_VirtToPhys (uint64_t addr);
103206 +
103207 +
103208 +#endif /* __SYS_IO_EXT_H */
103209 --- /dev/null
103210 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
103211 @@ -0,0 +1,208 @@
103212 +/*
103213 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103214 + *
103215 + * Redistribution and use in source and binary forms, with or without
103216 + * modification, are permitted provided that the following conditions are met:
103217 + * * Redistributions of source code must retain the above copyright
103218 + * notice, this list of conditions and the following disclaimer.
103219 + * * Redistributions in binary form must reproduce the above copyright
103220 + * notice, this list of conditions and the following disclaimer in the
103221 + * documentation and/or other materials provided with the distribution.
103222 + * * Neither the name of Freescale Semiconductor nor the
103223 + * names of its contributors may be used to endorse or promote products
103224 + * derived from this software without specific prior written permission.
103225 + *
103226 + *
103227 + * ALTERNATIVELY, this software may be distributed under the terms of the
103228 + * GNU General Public License ("GPL") as published by the Free Software
103229 + * Foundation, either version 2 of that License or (at your option) any
103230 + * later version.
103231 + *
103232 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103233 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103234 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103235 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103236 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103237 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103238 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103239 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103240 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103241 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103242 + */
103243 +
103244 +#ifndef __TYPES_LINUX_H__
103245 +#define __TYPES_LINUX_H__
103246 +
103247 +#include <linux/version.h>
103248 +
103249 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
103250 +#define MODVERSIONS
103251 +#endif
103252 +#ifdef MODVERSIONS
103253 +#include <config/modversions.h>
103254 +#endif /* MODVERSIONS */
103255 +
103256 +#include <linux/kernel.h>
103257 +#include <linux/types.h>
103258 +#include <asm/io.h>
103259 +#include <linux/delay.h>
103260 +
103261 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
103262 + #error "This kernel is probably not supported!!!"
103263 +#elif (!((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) || \
103264 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)) || \
103265 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30))))
103266 + #warning "This kernel is probably not supported!!! You may need to add some fixes."
103267 +#endif /* LINUX_VERSION_CODE */
103268 +
103269 +
103270 +typedef float float_t; /* Single precision floating point */
103271 +typedef double double_t; /* Double precision floating point */
103272 +
103273 +
103274 +#define _Packed
103275 +#define _PackedType __attribute__ ((packed))
103276 +
103277 +typedef phys_addr_t physAddress_t;
103278 +
103279 +#define UINT8_MAX 0xFF
103280 +#define UINT8_MIN 0
103281 +#define UINT16_MAX 0xFFFF
103282 +#define UINT16_MIN 0
103283 +#define UINT32_MAX 0xFFFFFFFF
103284 +#define UINT32_MIN 0
103285 +#define UINT64_MAX 0xFFFFFFFFFFFFFFFFLL
103286 +#define UINT64_MIN 0
103287 +#define INT8_MAX 0x7F
103288 +#define INT8_MIN 0x80
103289 +#define INT16_MAX 0x7FFF
103290 +#define INT16_MIN 0x8000
103291 +#define INT32_MAX 0x7FFFFFFF
103292 +#define INT32_MIN 0x80000000
103293 +#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
103294 +#define INT64_MIN 0x8000000000000000LL
103295 +
103296 +#define ON 1
103297 +#define OFF 0
103298 +
103299 +#define FALSE false
103300 +#define TRUE true
103301 +
103302 +
103303 +/************************/
103304 +/* memory access macros */
103305 +/************************/
103306 +#ifdef CONFIG_FMAN_ARM
103307 +#define in_be16(a) __be16_to_cpu(__raw_readw(a))
103308 +#define in_be32(a) __be32_to_cpu(__raw_readl(a))
103309 +#define out_be16(a, v) __raw_writew(__cpu_to_be16(v), a)
103310 +#define out_be32(a, v) __raw_writel(__cpu_to_be32(v), a)
103311 +#endif
103312 +
103313 +#define GET_UINT8(arg) *(volatile uint8_t *)(&(arg))
103314 +#define GET_UINT16(arg) in_be16(&(arg))//*(volatile uint16_t*)(&(arg))
103315 +#define GET_UINT32(arg) in_be32(&(arg))//*(volatile uint32_t*)(&(arg))
103316 +#define GET_UINT64(arg) *(volatile uint64_t*)(&(arg))
103317 +
103318 +#ifdef VERBOSE_WRITE
103319 +void XX_Print(char *str, ...);
103320 +#define WRITE_UINT8(arg, data) \
103321 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%02x\r\n", (uint32_t)&(arg), (data)); *(volatile uint8_t *)(&(arg)) = (data); } while (0)
103322 +#define WRITE_UINT16(arg, data) \
103323 + 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)
103324 +#define WRITE_UINT32(arg, data) \
103325 + 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)
103326 +#define WRITE_UINT64(arg, data) \
103327 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%016llx\r\n", (uint32_t)&(arg), (data)); *(volatile uint64_t*)(&(arg)) = (data); } while (0)
103328 +
103329 +#else /* not VERBOSE_WRITE */
103330 +#define WRITE_UINT8(arg, data) *(volatile uint8_t *)(&(arg)) = (data)
103331 +#define WRITE_UINT16(arg, data) out_be16(&(arg), data)//*(volatile uint16_t*)(&(arg)) = (data)
103332 +#define WRITE_UINT32(arg, data) out_be32(&(arg), data)//*(volatile unsigned int *)(&(arg)) = (data)
103333 +#define WRITE_UINT64(arg, data) *(volatile uint64_t*)(&(arg)) = (data)
103334 +#endif /* not VERBOSE_WRITE */
103335 +
103336 +
103337 +/*****************************************************************************/
103338 +/* General stuff */
103339 +/*****************************************************************************/
103340 +#ifdef ARRAY_SIZE
103341 +#undef ARRAY_SIZE
103342 +#endif /* ARRAY_SIZE */
103343 +
103344 +#ifdef MAJOR
103345 +#undef MAJOR
103346 +#endif /* MAJOR */
103347 +
103348 +#ifdef MINOR
103349 +#undef MINOR
103350 +#endif /* MINOR */
103351 +
103352 +#ifdef QE_SIZEOF_BD
103353 +#undef QE_SIZEOF_BD
103354 +#endif /* QE_SIZEOF_BD */
103355 +
103356 +#ifdef BD_BUFFER_CLEAR
103357 +#undef BD_BUFFER_CLEAR
103358 +#endif /* BD_BUFFER_CLEAR */
103359 +
103360 +#ifdef BD_BUFFER
103361 +#undef BD_BUFFER
103362 +#endif /* BD_BUFFER */
103363 +
103364 +#ifdef BD_STATUS_AND_LENGTH_SET
103365 +#undef BD_STATUS_AND_LENGTH_SET
103366 +#endif /* BD_STATUS_AND_LENGTH_SET */
103367 +
103368 +#ifdef BD_STATUS_AND_LENGTH
103369 +#undef BD_STATUS_AND_LENGTH
103370 +#endif /* BD_STATUS_AND_LENGTH */
103371 +
103372 +#ifdef BD_BUFFER_ARG
103373 +#undef BD_BUFFER_ARG
103374 +#endif /* BD_BUFFER_ARG */
103375 +
103376 +#ifdef BD_GET_NEXT
103377 +#undef BD_GET_NEXT
103378 +#endif /* BD_GET_NEXT */
103379 +
103380 +#ifdef QE_SDEBCR_BA_MASK
103381 +#undef QE_SDEBCR_BA_MASK
103382 +#endif /* QE_SDEBCR_BA_MASK */
103383 +
103384 +#ifdef BD_BUFFER_SET
103385 +#undef BD_BUFFER_SET
103386 +#endif /* BD_BUFFER_SET */
103387 +
103388 +#ifdef UPGCR_PROTOCOL
103389 +#undef UPGCR_PROTOCOL
103390 +#endif /* UPGCR_PROTOCOL */
103391 +
103392 +#ifdef UPGCR_TMS
103393 +#undef UPGCR_TMS
103394 +#endif /* UPGCR_TMS */
103395 +
103396 +#ifdef UPGCR_RMS
103397 +#undef UPGCR_RMS
103398 +#endif /* UPGCR_RMS */
103399 +
103400 +#ifdef UPGCR_ADDR
103401 +#undef UPGCR_ADDR
103402 +#endif /* UPGCR_ADDR */
103403 +
103404 +#ifdef UPGCR_DIAG
103405 +#undef UPGCR_DIAG
103406 +#endif /* UPGCR_DIAG */
103407 +
103408 +#ifdef NCSW_PARAMS
103409 +#undef NCSW_PARAMS
103410 +#endif /* NCSW_PARAMS */
103411 +
103412 +#ifdef NO_IRQ
103413 +#undef NO_IRQ
103414 +#endif /* NO_IRQ */
103415 +
103416 +#define PRINT_LINE XX_Print("%s:\n %s [%d]\n",__FILE__,__FUNCTION__,__LINE__);
103417 +
103418 +
103419 +#endif /* __TYPES_LINUX_H__ */
103420 --- /dev/null
103421 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
103422 @@ -0,0 +1,84 @@
103423 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
103424 + * All rights reserved.
103425 + *
103426 + * Redistribution and use in source and binary forms, with or without
103427 + * modification, are permitted provided that the following conditions are met:
103428 + * * Redistributions of source code must retain the above copyright
103429 + * notice, this list of conditions and the following disclaimer.
103430 + * * Redistributions in binary form must reproduce the above copyright
103431 + * notice, this list of conditions and the following disclaimer in the
103432 + * documentation and/or other materials provided with the distribution.
103433 + * * Neither the name of Freescale Semiconductor nor the
103434 + * names of its contributors may be used to endorse or promote products
103435 + * derived from this software without specific prior written permission.
103436 + *
103437 + *
103438 + * ALTERNATIVELY, this software may be distributed under the terms of the
103439 + * GNU General Public License ("GPL") as published by the Free Software
103440 + * Foundation, either version 2 of that License or (at your option) any
103441 + * later version.
103442 + *
103443 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103444 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103445 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103446 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103447 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103448 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103449 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103450 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103451 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103452 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103453 + */
103454 +
103455 +/******************************************************************************
103456 + @File fsl_fman_test.h
103457 +
103458 + @Description
103459 +*//***************************************************************************/
103460 +
103461 +#ifndef __FSL_FMAN_TEST_H
103462 +#define __FSL_FMAN_TEST_H
103463 +
103464 +#include <linux/types.h>
103465 +#include <linux/smp.h> /* raw_smp_processor_id() */
103466 +
103467 +//#define FMT_K_DBG
103468 +//#define FMT_K_DBG_RUNTIME
103469 +
103470 +#define _fmt_prk(stage, format, arg...) \
103471 + printk(stage "fmt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
103472 +
103473 +#define _fmt_inf(format, arg...) _fmt_prk(KERN_INFO, format, ##arg)
103474 +#define _fmt_wrn(format, arg...) _fmt_prk(KERN_WARNING, format, ##arg)
103475 +#define _fmt_err(format, arg...) _fmt_prk(KERN_ERR, format, ##arg)
103476 +
103477 +/* there are two macros for debugging: for runtime and generic.
103478 + * Helps when the runtime functions are not targeted for debugging,
103479 + * thus all the unnecessary information will be skipped.
103480 + */
103481 +/* used for generic debugging */
103482 +#if defined(FMT_K_DBG)
103483 + #define _fmt_dbg(format, arg...) \
103484 + printk("fmt [%s:%u](cpu:%u) - " format, \
103485 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
103486 +#else
103487 +# define _fmt_dbg(arg...)
103488 +#endif
103489 +
103490 +/* used for debugging runtime functions */
103491 +#if defined(FMT_K_DBG_RUNTIME)
103492 + #define _fmt_dbgr(format, arg...) \
103493 + printk("fmt [%s:%u](cpu:%u) - " format, \
103494 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
103495 +#else
103496 +# define _fmt_dbgr(arg...)
103497 +#endif
103498 +
103499 +#define FMT_RX_ERR_Q 0xffffffff
103500 +#define FMT_RX_DFLT_Q 0xfffffffe
103501 +#define FMT_TX_ERR_Q 0xfffffffd
103502 +#define FMT_TX_CONF_Q 0xfffffffc
103503 +
103504 +#define FMAN_TEST_MAX_TX_FQS 8
103505 +
103506 +#endif /* __FSL_FMAN_TEST_H */
103507 --- /dev/null
103508 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
103509 @@ -0,0 +1,130 @@
103510 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
103511 + * All rights reserved.
103512 + *
103513 + * Redistribution and use in source and binary forms, with or without
103514 + * modification, are permitted provided that the following conditions are met:
103515 + * * Redistributions of source code must retain the above copyright
103516 + * notice, this list of conditions and the following disclaimer.
103517 + * * Redistributions in binary form must reproduce the above copyright
103518 + * notice, this list of conditions and the following disclaimer in the
103519 + * documentation and/or other materials provided with the distribution.
103520 + * * Neither the name of Freescale Semiconductor nor the
103521 + * names of its contributors may be used to endorse or promote products
103522 + * derived from this software without specific prior written permission.
103523 + *
103524 + *
103525 + * ALTERNATIVELY, this software may be distributed under the terms of the
103526 + * GNU General Public License ("GPL") as published by the Free Software
103527 + * Foundation, either version 2 of that License or (at your option) any
103528 + * later version.
103529 + *
103530 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103531 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103532 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103533 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103534 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103535 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103536 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103537 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103538 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103539 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103540 + */
103541 +
103542 +/*
103543 + @File lnxwrp_exp_sym.h
103544 + @Description FMan exported routines
103545 +*/
103546 +
103547 +#ifndef __LNXWRP_EXP_SYM_H
103548 +#define __LNXWRP_EXP_SYM_H
103549 +
103550 +#include "fm_port_ext.h"
103551 +#include "fm_pcd_ext.h"
103552 +#include "fm_mac_ext.h"
103553 +
103554 +
103555 +/* FMAN Port exported routines */
103556 +EXPORT_SYMBOL(FM_PORT_Disable);
103557 +EXPORT_SYMBOL(FM_PORT_Enable);
103558 +EXPORT_SYMBOL(FM_PORT_SetPCD);
103559 +EXPORT_SYMBOL(FM_PORT_DeletePCD);
103560 +
103561 +/* Runtime PCD exported routines */
103562 +EXPORT_SYMBOL(FM_PCD_Enable);
103563 +EXPORT_SYMBOL(FM_PCD_Disable);
103564 +EXPORT_SYMBOL(FM_PCD_GetCounter);
103565 +EXPORT_SYMBOL(FM_PCD_PrsLoadSw);
103566 +EXPORT_SYMBOL(FM_PCD_KgSetDfltValue);
103567 +EXPORT_SYMBOL(FM_PCD_KgSetAdditionalDataAfterParsing);
103568 +EXPORT_SYMBOL(FM_PCD_SetException);
103569 +EXPORT_SYMBOL(FM_PCD_ModifyCounter);
103570 +EXPORT_SYMBOL(FM_PCD_SetPlcrStatistics);
103571 +EXPORT_SYMBOL(FM_PCD_SetPrsStatistics);
103572 +EXPORT_SYMBOL(FM_PCD_ForceIntr);
103573 +EXPORT_SYMBOL(FM_PCD_HcTxConf);
103574 +
103575 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsSet);
103576 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsDelete);
103577 +EXPORT_SYMBOL(FM_PCD_KgSchemeSet);
103578 +EXPORT_SYMBOL(FM_PCD_KgSchemeDelete);
103579 +EXPORT_SYMBOL(FM_PCD_KgSchemeGetCounter);
103580 +EXPORT_SYMBOL(FM_PCD_KgSchemeSetCounter);
103581 +EXPORT_SYMBOL(FM_PCD_CcRootBuild);
103582 +EXPORT_SYMBOL(FM_PCD_CcRootDelete);
103583 +EXPORT_SYMBOL(FM_PCD_MatchTableSet);
103584 +EXPORT_SYMBOL(FM_PCD_MatchTableDelete);
103585 +EXPORT_SYMBOL(FM_PCD_CcRootModifyNextEngine);
103586 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyNextEngine);
103587 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyNextEngine);
103588 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyMissNextEngine);
103589 +EXPORT_SYMBOL(FM_PCD_MatchTableRemoveKey);
103590 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNRemoveKey);
103591 +EXPORT_SYMBOL(FM_PCD_MatchTableAddKey);
103592 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKeyAndNextEngine);
103593 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKeyAndNextEngine);
103594 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKey);
103595 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKey);
103596 +EXPORT_SYMBOL(FM_PCD_MatchTableGetIndexedHashBucket);
103597 +EXPORT_SYMBOL(FM_PCD_MatchTableGetNextEngine);
103598 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyCounter);
103599 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyStatistics);
103600 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNGetKeyStatistics);
103601 +EXPORT_SYMBOL(FM_PCD_MatchTableGetMissStatistics);
103602 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissStatistics);
103603 +EXPORT_SYMBOL(FM_PCD_HashTableSet);
103604 +EXPORT_SYMBOL(FM_PCD_HashTableDelete);
103605 +EXPORT_SYMBOL(FM_PCD_HashTableAddKey);
103606 +EXPORT_SYMBOL(FM_PCD_HashTableRemoveKey);
103607 +EXPORT_SYMBOL(FM_PCD_HashTableModifyNextEngine);
103608 +EXPORT_SYMBOL(FM_PCD_HashTableModifyMissNextEngine);
103609 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissNextEngine);
103610 +EXPORT_SYMBOL(FM_PCD_HashTableFindNGetKeyStatistics);
103611 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSet);
103612 +EXPORT_SYMBOL(FM_PCD_PlcrProfileDelete);
103613 +EXPORT_SYMBOL(FM_PCD_PlcrProfileGetCounter);
103614 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSetCounter);
103615 +EXPORT_SYMBOL(FM_PCD_ManipNodeSet);
103616 +EXPORT_SYMBOL(FM_PCD_ManipNodeDelete);
103617 +EXPORT_SYMBOL(FM_PCD_ManipGetStatistics);
103618 +EXPORT_SYMBOL(FM_PCD_ManipNodeReplace);
103619 +#if (DPAA_VERSION >= 11)
103620 +EXPORT_SYMBOL(FM_PCD_FrmReplicSetGroup);
103621 +EXPORT_SYMBOL(FM_PCD_FrmReplicDeleteGroup);
103622 +EXPORT_SYMBOL(FM_PCD_FrmReplicAddMember);
103623 +EXPORT_SYMBOL(FM_PCD_FrmReplicRemoveMember);
103624 +#endif /* DPAA_VERSION >= 11 */
103625 +
103626 +#ifdef FM_CAPWAP_SUPPORT
103627 +EXPORT_SYMBOL(FM_PCD_StatisticsSetNode);
103628 +#endif /* FM_CAPWAP_SUPPORT */
103629 +
103630 +EXPORT_SYMBOL(FM_PCD_SetAdvancedOffloadSupport);
103631 +
103632 +/* FMAN MAC exported routines */
103633 +EXPORT_SYMBOL(FM_MAC_GetStatistics);
103634 +
103635 +EXPORT_SYMBOL(FM_MAC_GetFrameSizeCounters);
103636 +
103637 +EXPORT_SYMBOL(FM_GetSpecialOperationCoding);
103638 +
103639 +#endif /* __LNXWRP_EXP_SYM_H */
103640 --- /dev/null
103641 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
103642 @@ -0,0 +1,163 @@
103643 +/*
103644 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103645 + *
103646 + * Redistribution and use in source and binary forms, with or without
103647 + * modification, are permitted provided that the following conditions are met:
103648 + * * Redistributions of source code must retain the above copyright
103649 + * notice, this list of conditions and the following disclaimer.
103650 + * * Redistributions in binary form must reproduce the above copyright
103651 + * notice, this list of conditions and the following disclaimer in the
103652 + * documentation and/or other materials provided with the distribution.
103653 + * * Neither the name of Freescale Semiconductor nor the
103654 + * names of its contributors may be used to endorse or promote products
103655 + * derived from this software without specific prior written permission.
103656 + *
103657 + *
103658 + * ALTERNATIVELY, this software may be distributed under the terms of the
103659 + * GNU General Public License ("GPL") as published by the Free Software
103660 + * Foundation, either version 2 of that License or (at your option) any
103661 + * later version.
103662 + *
103663 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103664 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103665 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103666 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103667 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103668 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103669 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103670 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103671 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103672 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103673 + */
103674 +
103675 +/******************************************************************************
103676 + @File lnxwrp_fm_ext.h
103677 +
103678 + @Description TODO
103679 +*//***************************************************************************/
103680 +
103681 +#ifndef __LNXWRP_FM_EXT_H
103682 +#define __LNXWRP_FM_EXT_H
103683 +
103684 +#include "std_ext.h"
103685 +#include "sys_ext.h"
103686 +#include "fm_ext.h"
103687 +#include "fm_muram_ext.h"
103688 +#include "fm_pcd_ext.h"
103689 +#include "fm_port_ext.h"
103690 +#include "fm_mac_ext.h"
103691 +#include "fm_rtc_ext.h"
103692 +
103693 +
103694 +/**************************************************************************//**
103695 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
103696 +
103697 + @Description FM API functions, definitions and enums.
103698 +
103699 + @{
103700 +*//***************************************************************************/
103701 +
103702 +/**************************************************************************//**
103703 + @Group FM_LnxKern_init_grp Initialization Unit
103704 +
103705 + @Description Initialization Unit
103706 +
103707 + Initialization Flow:
103708 + Initialization of the FM Module will be carried out by the Linux
103709 + kernel according to the following sequence:
103710 + a. Calling the initialization routine with no parameters.
103711 + b. The driver will register to the Device-Tree.
103712 + c. The Linux Device-Tree will initiate a call to the driver for
103713 + initialization.
103714 + d. The driver will read the appropriate information from the Device-Tree
103715 + e. [Optional] Calling the advance initialization routines to change
103716 + driver's defaults.
103717 + f. Initialization of the device will be automatically upon using it.
103718 +
103719 + @{
103720 +*//***************************************************************************/
103721 +
103722 +typedef struct t_WrpFmDevSettings
103723 +{
103724 + t_FmParams param;
103725 + t_SysObjectAdvConfigEntry *advConfig;
103726 +} t_WrpFmDevSettings;
103727 +
103728 +typedef struct t_WrpFmPcdDevSettings
103729 +{
103730 + t_FmPcdParams param;
103731 + t_SysObjectAdvConfigEntry *advConfig;
103732 +} t_WrpFmPcdDevSettings;
103733 +
103734 +typedef struct t_WrpFmPortDevSettings
103735 +{
103736 + bool frag_enabled;
103737 + t_FmPortParams param;
103738 + t_SysObjectAdvConfigEntry *advConfig;
103739 +} t_WrpFmPortDevSettings;
103740 +
103741 +typedef struct t_WrpFmMacDevSettings
103742 +{
103743 + t_FmMacParams param;
103744 + t_SysObjectAdvConfigEntry *advConfig;
103745 +} t_WrpFmMacDevSettings;
103746 +
103747 +
103748 +/**************************************************************************//**
103749 + @Function LNXWRP_FM_Init
103750 +
103751 + @Description Initialize the FM linux wrapper.
103752 +
103753 + @Return A handle (descriptor) of the newly created FM Linux wrapper
103754 + structure.
103755 +*//***************************************************************************/
103756 +t_Handle LNXWRP_FM_Init(void);
103757 +
103758 +/**************************************************************************//**
103759 + @Function LNXWRP_FM_Free
103760 +
103761 + @Description Free the FM linux wrapper.
103762 +
103763 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
103764 +
103765 + @Return E_OK on success; Error code otherwise.
103766 +*//***************************************************************************/
103767 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm);
103768 +
103769 +/**************************************************************************//**
103770 + @Function LNXWRP_FM_GetMacHandle
103771 +
103772 + @Description Get the FM-MAC LLD handle from the FM linux wrapper.
103773 +
103774 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
103775 + @Param[in] fmId - Index of the FM device to get the MAC handle from.
103776 + @Param[in] macId - Index of the mac handle.
103777 +
103778 + @Return A handle of the LLD compressor.
103779 +*//***************************************************************************/
103780 +t_Handle LNXWRP_FM_GetMacHandle(t_Handle h_LnxWrpFm, uint8_t fmId, uint8_t macId);
103781 +
103782 +#ifdef CONFIG_FSL_SDK_FMAN_TEST
103783 +t_Handle LNXWRP_FM_TEST_Init(void);
103784 +t_Error LNXWRP_FM_TEST_Free(t_Handle h_FmTestLnxWrp);
103785 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
103786 +
103787 +/** @} */ /* end of FM_LnxKern_init_grp group */
103788 +
103789 +
103790 +/**************************************************************************//**
103791 + @Group FM_LnxKern_ctrl_grp Control Unit
103792 +
103793 + @Description Control Unit
103794 +
103795 + TODO
103796 + @{
103797 +*//***************************************************************************/
103798 +
103799 +#include "lnxwrp_fsl_fman.h"
103800 +
103801 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
103802 +/** @} */ /* end of FM_LnxKern_grp group */
103803 +
103804 +
103805 +#endif /* __LNXWRP_FM_EXT_H */
103806 --- /dev/null
103807 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
103808 @@ -0,0 +1,921 @@
103809 +/*
103810 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103811 + *
103812 + * Redistribution and use in source and binary forms, with or without
103813 + * modification, are permitted provided that the following conditions are met:
103814 + * * Redistributions of source code must retain the above copyright
103815 + * notice, this list of conditions and the following disclaimer.
103816 + * * Redistributions in binary form must reproduce the above copyright
103817 + * notice, this list of conditions and the following disclaimer in the
103818 + * documentation and/or other materials provided with the distribution.
103819 + * * Neither the name of Freescale Semiconductor nor the
103820 + * names of its contributors may be used to endorse or promote products
103821 + * derived from this software without specific prior written permission.
103822 + *
103823 + *
103824 + * ALTERNATIVELY, this software may be distributed under the terms of the
103825 + * GNU General Public License ("GPL") as published by the Free Software
103826 + * Foundation, either version 2 of that License or (at your option) any
103827 + * later version.
103828 + *
103829 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103830 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103831 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103832 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103833 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103834 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103835 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103836 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103837 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103838 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103839 + */
103840 +
103841 +/******************************************************************************
103842 + @File lnxwrp_fsl_fman.h
103843 +
103844 + @Description Linux internal kernel API
103845 +*//***************************************************************************/
103846 +
103847 +#ifndef __LNXWRP_FSL_FMAN_H
103848 +#define __LNXWRP_FSL_FMAN_H
103849 +
103850 +#include <linux/types.h>
103851 +#include <linux/device.h> /* struct device */
103852 +#include <linux/fsl_qman.h> /* struct qman_fq */
103853 +#include "dpaa_integration_ext.h"
103854 +#include "fm_port_ext.h"
103855 +#include "fm_mac_ext.h"
103856 +#include "fm_macsec_ext.h"
103857 +#include "fm_rtc_ext.h"
103858 +
103859 +/**************************************************************************//**
103860 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
103861 +
103862 + @Description FM API functions, definitions and enums.
103863 +
103864 + @{
103865 +*//***************************************************************************/
103866 +
103867 +/**************************************************************************//**
103868 + @Group FM_LnxKern_ctrl_grp Control Unit
103869 +
103870 + @Description Control Unit
103871 +
103872 + Internal Kernel Control Unit API
103873 + @{
103874 +*//***************************************************************************/
103875 +
103876 +/*****************************************************************************/
103877 +/* Internal Linux kernel routines */
103878 +/*****************************************************************************/
103879 +
103880 +/**************************************************************************//**
103881 + @Description MACSEC Exceptions wrapper
103882 +*//***************************************************************************/
103883 +typedef enum fm_macsec_exception {
103884 + SINGLE_BIT_ECC = e_FM_MACSEC_EX_SINGLE_BIT_ECC,
103885 + MULTI_BIT_ECC = e_FM_MACSEC_EX_MULTI_BIT_ECC
103886 +} fm_macsec_exception;
103887 +
103888 +/**************************************************************************//**
103889 + @Description Unknown sci frame treatment wrapper
103890 +*//***************************************************************************/
103891 +typedef enum fm_macsec_unknown_sci_frame_treatment {
103892 + SCI_DISCARD_BOTH = e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH,
103893 + SCI_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
103894 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED,
103895 + SCI_DELIVER_UNCTRL_DISCARD_CTRL = \
103896 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
103897 + SCI_DELIVER_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
103898 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED
103899 +} fm_macsec_unknown_sci_frame_treatment;
103900 +
103901 +/**************************************************************************//**
103902 + @Description Untag frame treatment wrapper
103903 +*//***************************************************************************/
103904 +typedef enum fm_macsec_untag_frame_treatment {
103905 + UNTAG_DELIVER_UNCTRL_DISCARD_CTRL = \
103906 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
103907 + UNTAG_DISCARD_BOTH = e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH,
103908 + UNTAG_DISCARD_UNCTRL_DELIVER_CTRL_UNMODIFIED = \
103909 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED
103910 +} fm_macsec_untag_frame_treatment;
103911 +
103912 +/**************************************************************************//**
103913 +@Description MACSEC SECY Cipher Suite wrapper
103914 +*//***************************************************************************/
103915 +typedef enum fm_macsec_secy_cipher_suite {
103916 + SECY_GCM_AES_128 = e_FM_MACSEC_SECY_GCM_AES_128, /**< GCM-AES-128 */
103917 +#if (DPAA_VERSION >= 11)
103918 + SECY_GCM_AES_256 = e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
103919 +#endif /* (DPAA_VERSION >= 11) */
103920 +} fm_macsec_secy_cipher_suite;
103921 +
103922 +/**************************************************************************//**
103923 + @Description MACSEC SECY Exceptions wrapper
103924 +*//***************************************************************************/
103925 +typedef enum fm_macsec_secy_exception {
103926 + SECY_EX_FRAME_DISCARDED = e_FM_MACSEC_SECY_EX_FRAME_DISCARDED
103927 +} fm_macsec_secy_exception;
103928 +
103929 +/**************************************************************************//**
103930 + @Description MACSEC SECY Events wrapper
103931 +*//***************************************************************************/
103932 +typedef enum fm_macsec_secy_event {
103933 + SECY_EV_NEXT_PN = e_FM_MACSEC_SECY_EV_NEXT_PN
103934 +} fm_macsec_secy_event;
103935 +
103936 +/**************************************************************************//**
103937 + @Description Valid frame behaviors wrapper
103938 +*//***************************************************************************/
103939 +typedef enum fm_macsec_valid_frame_behavior {
103940 + VALID_FRAME_BEHAVIOR_DISABLE = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE,
103941 + VALID_FRAME_BEHAVIOR_CHECK = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK,
103942 + VALID_FRAME_BEHAVIOR_STRICT = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
103943 +} fm_macsec_valid_frame_behavior;
103944 +
103945 +/**************************************************************************//**
103946 + @Description SCI insertion modes wrapper
103947 +*//***************************************************************************/
103948 +typedef enum fm_macsec_sci_insertion_mode {
103949 + SCI_INSERTION_MODE_EXPLICIT_SECTAG = \
103950 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG,
103951 + SCI_INSERTION_MODE_EXPLICIT_MAC_SA = \
103952 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA,
103953 + SCI_INSERTION_MODE_IMPLICT_PTP = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP
103954 +} fm_macsec_sci_insertion_mode;
103955 +
103956 +typedef macsecSAKey_t macsec_sa_key_t;
103957 +typedef macsecSCI_t macsec_sci_t;
103958 +typedef macsecAN_t macsec_an_t;
103959 +typedef t_Handle handle_t;
103960 +
103961 +/**************************************************************************//**
103962 + @Function fm_macsec_secy_exception_callback wrapper
103963 + @Description Exceptions user callback routine, will be called upon an
103964 + exception passing the exception identification.
103965 + @Param[in] app_h A handle to an application layer object; This handle
103966 + will be passed by the driver upon calling this callback.
103967 + @Param[in] exception The exception.
103968 +*//***************************************************************************/
103969 +typedef void (fm_macsec_secy_exception_callback) (handle_t app_h,
103970 + fm_macsec_secy_exception exception);
103971 +
103972 +/**************************************************************************//**
103973 + @Function fm_macsec_secy_event_callback wrapper
103974 + @Description Events user callback routine, will be called upon an
103975 + event passing the event identification.
103976 + @Param[in] app_h A handle to an application layer object; This handle
103977 + will be passed by the driver upon calling this callback.
103978 + @Param[in] event The event.
103979 +*//***************************************************************************/
103980 +typedef void (fm_macsec_secy_event_callback) (handle_t app_h,
103981 + fm_macsec_secy_event event);
103982 +
103983 +/**************************************************************************//**
103984 + @Function fm_macsec_exception_callback wrapper
103985 + @Description Exceptions user callback routine, will be called upon an
103986 + exception passing the exception identification.
103987 + @Param[in] app_h A handle to an application layer object; This handle
103988 + will be passed by the driver upon calling this callback.
103989 + @Param[in] exception The exception.
103990 +*//***************************************************************************/
103991 +typedef void (fm_macsec_exception_callback) (handle_t app_h,
103992 + fm_macsec_exception exception);
103993 +
103994 +/**************************************************************************//**
103995 + @Description MACSEC SecY SC Params wrapper
103996 +*//***************************************************************************/
103997 +struct fm_macsec_secy_sc_params {
103998 + macsec_sci_t sci;
103999 + fm_macsec_secy_cipher_suite cipher_suite;
104000 +};
104001 +
104002 +/**************************************************************************//**
104003 + @Description FM MACSEC SecY config input wrapper
104004 +*//***************************************************************************/
104005 +struct fm_macsec_secy_params {
104006 + handle_t fm_macsec_h;
104007 + struct fm_macsec_secy_sc_params tx_sc_params;
104008 + uint32_t num_receive_channels;
104009 + fm_macsec_secy_exception_callback *exception_f;
104010 + fm_macsec_secy_event_callback *event_f;
104011 + handle_t app_h;
104012 +};
104013 +
104014 +/**************************************************************************//**
104015 + @Description FM MACSEC config input wrapper
104016 +*//***************************************************************************/
104017 +struct fm_macsec_params {
104018 + handle_t fm_h;
104019 + bool guest_mode;
104020 +
104021 + union {
104022 + struct {
104023 + uint8_t fm_mac_id;
104024 + } guest_params;
104025 +
104026 + struct {
104027 + uintptr_t base_addr;
104028 + handle_t fm_mac_h;
104029 + fm_macsec_exception_callback *exception_f;
104030 + handle_t app_h;
104031 + } non_guest_params;
104032 + };
104033 +
104034 +};
104035 +
104036 +/**************************************************************************//**
104037 + @Description FM device opaque structure used for type checking
104038 +*//***************************************************************************/
104039 +struct fm;
104040 +
104041 +/**************************************************************************//**
104042 + @Description FM MAC device opaque structure used for type checking
104043 +*//***************************************************************************/
104044 +struct fm_mac_dev;
104045 +
104046 +/**************************************************************************//**
104047 + @Description FM MACSEC device opaque structure used for type checking
104048 +*//***************************************************************************/
104049 +struct fm_macsec_dev;
104050 +struct fm_macsec_secy_dev;
104051 +
104052 +/**************************************************************************//**
104053 + @Description A structure ..,
104054 +*//***************************************************************************/
104055 +struct fm_port;
104056 +
104057 +typedef int (*alloc_pcd_fqids)(struct device *dev, uint32_t num,
104058 + uint8_t alignment, uint32_t *base_fqid);
104059 +
104060 +typedef int (*free_pcd_fqids)(struct device *dev, uint32_t base_fqid);
104061 +
104062 +struct fm_port_pcd_param {
104063 + alloc_pcd_fqids cba;
104064 + free_pcd_fqids cbf;
104065 + struct device *dev;
104066 +};
104067 +
104068 +/**************************************************************************//**
104069 + @Description A structure of information about each of the external
104070 + buffer pools used by the port,
104071 +*//***************************************************************************/
104072 +struct fm_port_pool_param {
104073 + uint8_t id; /**< External buffer pool id */
104074 + uint16_t size; /**< External buffer pool buffer size */
104075 +};
104076 +
104077 +/**************************************************************************//**
104078 + @Description structure for additional port parameters
104079 +*//***************************************************************************/
104080 +struct fm_port_params {
104081 + uint32_t errq; /**< Error Queue Id. */
104082 + uint32_t defq; /**< For Tx and HC - Default Confirmation queue,
104083 + 0 means no Tx conf for processed frames.
104084 + For Rx and OP - default Rx queue. */
104085 + uint8_t num_pools; /**< Number of pools use by this port */
104086 + struct fm_port_pool_param pool_param[FM_PORT_MAX_NUM_OF_EXT_POOLS];
104087 + /**< Parameters for each pool */
104088 + uint16_t priv_data_size; /**< Area that user may save for his own
104089 + need (E.g. save the SKB) */
104090 + bool parse_results; /**< Put the parser-results in the Rx/Tx buffer */
104091 + bool hash_results; /**< Put the hash-results in the Rx/Tx buffer */
104092 + bool time_stamp; /**< Put the time-stamp in the Rx/Tx buffer */
104093 + bool frag_enable; /**< Fragmentation support, for OP only */
104094 + uint16_t data_align; /**< value for selecting a data alignment (must be a power of 2);
104095 + if write optimization is used, must be >= 16. */
104096 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
104097 + Note that this field impacts the size of the buffer-prefix
104098 + (i.e. it pushes the data offset); */
104099 +};
104100 +
104101 +/**************************************************************************//**
104102 + @Function fm_bind
104103 +
104104 + @Description Bind to a specific FM device.
104105 +
104106 + @Param[in] fm_dev - the OF handle of the FM device.
104107 +
104108 + @Return A handle of the FM device.
104109 +
104110 + @Cautions Allowed only after the port was created.
104111 +*//***************************************************************************/
104112 +struct fm *fm_bind(struct device *fm_dev);
104113 +
104114 +/**************************************************************************//**
104115 + @Function fm_unbind
104116 +
104117 + @Description Un-bind from a specific FM device.
104118 +
104119 + @Param[in] fm - A handle of the FM device.
104120 +
104121 + @Cautions Allowed only after the port was created.
104122 +*//***************************************************************************/
104123 +void fm_unbind(struct fm *fm);
104124 +
104125 +void *fm_get_handle(struct fm *fm);
104126 +void *fm_get_rtc_handle(struct fm *fm);
104127 +struct resource *fm_get_mem_region(struct fm *fm);
104128 +
104129 +/**************************************************************************//**
104130 + @Function fm_port_bind
104131 +
104132 + @Description Bind to a specific FM-port device (may be Rx or Tx port).
104133 +
104134 + @Param[in] fm_port_dev - the OF handle of the FM port device.
104135 +
104136 + @Return A handle of the FM port device.
104137 +
104138 + @Cautions Allowed only after the port was created.
104139 +*//***************************************************************************/
104140 +struct fm_port *fm_port_bind(struct device *fm_port_dev);
104141 +
104142 +/**************************************************************************//**
104143 + @Function fm_port_unbind
104144 +
104145 + @Description Un-bind from a specific FM-port device (may be Rx or Tx port).
104146 +
104147 + @Param[in] port - A handle of the FM port device.
104148 +
104149 + @Cautions Allowed only after the port was created.
104150 +*//***************************************************************************/
104151 +void fm_port_unbind(struct fm_port *port);
104152 +
104153 +/**************************************************************************//**
104154 + @Function fm_set_rx_port_params
104155 +
104156 + @Description Configure parameters for a specific Rx FM-port device.
104157 +
104158 + @Param[in] port - A handle of the FM port device.
104159 + @Param[in] params - Rx port parameters
104160 +
104161 + @Cautions Allowed only after the port is binded.
104162 +*//***************************************************************************/
104163 +void fm_set_rx_port_params(struct fm_port *port,
104164 + struct fm_port_params *params);
104165 +
104166 +/**************************************************************************//**
104167 + @Function fm_port_pcd_bind
104168 +
104169 + @Description Bind as a listener on a port PCD.
104170 +
104171 + @Param[in] port - A handle of the FM port device.
104172 + @Param[in] params - PCD port parameters
104173 +
104174 + @Cautions Allowed only after the port is binded.
104175 +*//***************************************************************************/
104176 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params);
104177 +
104178 +/**************************************************************************//**
104179 + @Function fm_port_get_buff_layout_ext_params
104180 +
104181 + @Description Get data_align and manip_extra_space from the device tree
104182 + chosen node if applied.
104183 + This function will only update these two parameters.
104184 + When this port has no such parameters in the device tree
104185 + values will be set to 0.
104186 +
104187 + @Param[in] port - A handle of the FM port device.
104188 + @Param[in] params - PCD port parameters
104189 +
104190 + @Cautions Allowed only after the port is binded.
104191 +*//***************************************************************************/
104192 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params);
104193 +
104194 +/**************************************************************************//**
104195 + @Function fm_get_tx_port_channel
104196 +
104197 + @Description Get qman-channel number for this Tx port.
104198 +
104199 + @Param[in] port - A handle of the FM port device.
104200 +
104201 + @Return qman-channel number for this Tx port.
104202 +
104203 + @Cautions Allowed only after the port is binded.
104204 +*//***************************************************************************/
104205 +uint16_t fm_get_tx_port_channel(struct fm_port *port);
104206 +
104207 +/**************************************************************************//**
104208 + @Function fm_set_tx_port_params
104209 +
104210 + @Description Configure parameters for a specific Tx FM-port device
104211 +
104212 + @Param[in] port - A handle of the FM port device.
104213 + @Param[in] params - Tx port parameters
104214 +
104215 + @Cautions Allowed only after the port is binded.
104216 +*//***************************************************************************/
104217 +void fm_set_tx_port_params(struct fm_port *port, struct fm_port_params *params);
104218 +
104219 +
104220 +/**************************************************************************//**
104221 + @Function fm_mac_set_handle
104222 +
104223 + @Description Set mac handle
104224 +
104225 + @Param[in] h_lnx_wrp_fm_dev - A handle of the LnxWrp FM device.
104226 + @Param[in] h_fm_mac - A handle of the LnxWrp FM MAC device.
104227 + @Param[in] mac_id - MAC id.
104228 +*//***************************************************************************/
104229 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev, t_Handle h_fm_mac,
104230 + int mac_id);
104231 +
104232 +/**************************************************************************//**
104233 + @Function fm_port_enable
104234 +
104235 + @Description Enable specific FM-port device (may be Rx or Tx port).
104236 +
104237 + @Param[in] port - A handle of the FM port device.
104238 +
104239 + @Cautions Allowed only after the port is initialized.
104240 +*//***************************************************************************/
104241 +int fm_port_enable(struct fm_port *port);
104242 +
104243 +/**************************************************************************//**
104244 + @Function fm_port_disable
104245 +
104246 + @Description Disable specific FM-port device (may be Rx or Tx port).
104247 +
104248 + @Param[in] port - A handle of the FM port device.
104249 +
104250 + @Cautions Allowed only after the port is initialized.
104251 +*//***************************************************************************/
104252 +int fm_port_disable(struct fm_port *port);
104253 +
104254 +void *fm_port_get_handle(const struct fm_port *port);
104255 +
104256 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
104257 + const void *data);
104258 +
104259 +/**************************************************************************//**
104260 + @Function fm_port_get_base_address
104261 +
104262 + @Description Get base address of this port. Useful for accessing
104263 + port-specific registers (i.e., not common ones).
104264 +
104265 + @Param[in] port - A handle of the FM port device.
104266 +
104267 + @Param[out] base_addr - The port's base addr (virtual address).
104268 +*//***************************************************************************/
104269 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr);
104270 +
104271 +/**************************************************************************//**
104272 + @Function fm_mutex_lock
104273 +
104274 + @Description Lock function required before any FMD/LLD call.
104275 +*//***************************************************************************/
104276 +void fm_mutex_lock(void);
104277 +
104278 +/**************************************************************************//**
104279 + @Function fm_mutex_unlock
104280 +
104281 + @Description Unlock function required after any FMD/LLD call.
104282 +*//***************************************************************************/
104283 +void fm_mutex_unlock(void);
104284 +
104285 +/**************************************************************************//**
104286 + @Function fm_get_max_frm
104287 +
104288 + @Description Get the maximum frame size
104289 +*//***************************************************************************/
104290 +int fm_get_max_frm(void);
104291 +
104292 +/**************************************************************************//**
104293 + @Function fm_get_rx_extra_headroom
104294 +
104295 + @Description Get the extra headroom size
104296 +*//***************************************************************************/
104297 +int fm_get_rx_extra_headroom(void);
104298 +
104299 +/**************************************************************************//**
104300 +@Function fm_port_set_rate_limit
104301 +
104302 +@Description Configure Shaper parameter on FM-port device (Tx port).
104303 +
104304 +@Param[in] port - A handle of the FM port device.
104305 +@Param[in] max_burst_size - Value of maximum burst size allowed.
104306 +@Param[in] rate_limit - The required rate value.
104307 +
104308 +@Cautions Allowed only after the port is initialized.
104309 +*//***************************************************************************/
104310 +int fm_port_set_rate_limit(struct fm_port *port,
104311 + uint16_t max_burst_size,
104312 + uint32_t rate_limit);
104313 +/**************************************************************************//**
104314 +@Function fm_port_set_rate_limit
104315 +
104316 +@Description Delete Shaper configuration on FM-port device (Tx port).
104317 +
104318 +@Param[in] port - A handle of the FM port device.
104319 +
104320 +@Cautions Allowed only after the port is initialized.
104321 +*//***************************************************************************/
104322 +int fm_port_del_rate_limit(struct fm_port *port);
104323 +
104324 +struct auto_res_tables_sizes
104325 +{
104326 + uint16_t max_num_of_arp_entries;
104327 + uint16_t max_num_of_echo_ipv4_entries;
104328 + uint16_t max_num_of_ndp_entries;
104329 + uint16_t max_num_of_echo_ipv6_entries;
104330 + uint16_t max_num_of_snmp_ipv4_entries;
104331 + uint16_t max_num_of_snmp_ipv6_entries;
104332 + uint16_t max_num_of_snmp_oid_entries;
104333 + uint16_t max_num_of_snmp_char; /* total amount of character needed
104334 + for the snmp table */
104335 + uint16_t max_num_of_ip_prot_filtering;
104336 + uint16_t max_num_of_tcp_port_filtering;
104337 + uint16_t max_num_of_udp_port_filtering;
104338 +};
104339 +/* ARP */
104340 +struct auto_res_arp_entry
104341 +{
104342 + uint32_t ip_address;
104343 + uint8_t mac[6];
104344 + bool is_vlan;
104345 + uint16_t vid;
104346 +};
104347 +struct auto_res_arp_info
104348 +{
104349 + uint8_t table_size;
104350 + struct auto_res_arp_entry *auto_res_table;
104351 + bool enable_conflict_detection; /* when TRUE
104352 + Conflict Detection will be checked and wake the host if
104353 + needed */
104354 +};
104355 +
104356 +/* NDP */
104357 +struct auto_res_ndp_entry
104358 +{
104359 + uint32_t ip_address[4];
104360 + uint8_t mac[6];
104361 + bool is_vlan;
104362 + uint16_t vid;
104363 +};
104364 +struct auto_res_ndp_info
104365 +{
104366 + uint32_t multicast_group;
104367 + uint8_t table_size_assigned;
104368 + struct auto_res_ndp_entry *auto_res_table_assigned; /* This list
104369 + refer to solicitation IP addresses. Note that all IP adresses
104370 + must be from the same multicast group. This will be checked and
104371 + if not operation will fail. */
104372 + uint8_t table_size_tmp;
104373 + struct auto_res_ndp_entry *auto_res_table_tmp; /* This list
104374 + refer to temp IP addresses. Note that all temp IP adresses must
104375 + be from the same multicast group. This will be checked and if
104376 + not operation will fail. */
104377 +
104378 + bool enable_conflict_detection; /* when TRUE
104379 + Conflict Detection will be checked and wake the host if
104380 + needed */
104381 +};
104382 +
104383 +/* ICMP ECHO */
104384 +struct auto_res_echo_ipv4_info
104385 +{
104386 + uint8_t table_size;
104387 + struct auto_res_arp_entry *auto_res_table;
104388 +};
104389 +
104390 +struct auto_res_echo_ipv6_info
104391 +{
104392 + uint8_t table_size;
104393 + struct auto_res_ndp_entry *auto_res_table;
104394 +};
104395 +
104396 +/* SNMP */
104397 +struct auto_res_snmp_entry
104398 +{
104399 + uint16_t oidSize;
104400 + uint8_t *oidVal; /* only the oid string */
104401 + uint16_t resSize;
104402 + uint8_t *resVal; /* resVal will be the entire reply,
104403 + i.e. "Type|Length|Value" */
104404 +};
104405 +
104406 +/**************************************************************************//**
104407 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
104408 + Refer to the FMan Controller spec for more details.
104409 +*//***************************************************************************/
104410 +struct auto_res_snmp_ipv4addr_tbl_entry
104411 +{
104412 + uint32_t ipv4addr; /*!< 32 bit IPv4 Address. */
104413 + bool is_vlan;
104414 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104415 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104416 +};
104417 +
104418 +/**************************************************************************//**
104419 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
104420 + Refer to the FMan Controller spec for more details.
104421 +*//***************************************************************************/
104422 +struct auto_res_snmp_ipv6addr_tbl_entry
104423 +{
104424 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
104425 + bool isVlan;
104426 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104427 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104428 +};
104429 +
104430 +struct auto_res_snmp_info
104431 +{
104432 + uint16_t control; /**< Control bits [0-15]. */
104433 + uint16_t max_snmp_msg_length; /**< Maximal allowed SNMP message length. */
104434 + uint16_t num_ipv4_addresses; /**< Number of entries in IPv4 addresses table. */
104435 + uint16_t num_ipv6_addresses; /**< Number of entries in IPv6 addresses table. */
104436 + struct auto_res_snmp_ipv4addr_tbl_entry *ipv4addr_tbl; /**< Pointer to IPv4 addresses table. */
104437 + struct auto_res_snmp_ipv6addr_tbl_entry *ipv6addr_tbl; /**< Pointer to IPv6 addresses table. */
104438 + char *community_read_write_string;
104439 + char *community_read_only_string;
104440 + struct auto_res_snmp_entry *oid_table;
104441 + uint32_t oid_table_size;
104442 + uint32_t *statistics;
104443 +};
104444 +
104445 +/* Filtering */
104446 +struct auto_res_port_filtering_entry
104447 +{
104448 + uint16_t src_port;
104449 + uint16_t dst_port;
104450 + uint16_t src_port_mask;
104451 + uint16_t dst_port_mask;
104452 +};
104453 +struct auto_res_filtering_info
104454 +{
104455 + /* IP protocol filtering parameters */
104456 + uint8_t ip_prot_table_size;
104457 + uint8_t *ip_prot_table_ptr;
104458 + bool ip_prot_pass_on_hit; /* when TRUE, miss in the table will
104459 + cause the packet to be droped, hit will pass the packet to
104460 + UDP/TCP filters if needed and if not to the classification
104461 + tree. If the classification tree will pass the packet to a
104462 + queue it will cause a wake interupt. When FALSE it the other
104463 + way around. */
104464 + /* UDP port filtering parameters */
104465 + uint8_t udp_ports_table_size;
104466 + struct auto_res_port_filtering_entry *udp_ports_table_ptr;
104467 + bool udp_port_pass_on_hit; /* when TRUE, miss in the table will
104468 + cause the packet to be droped, hit will pass the packet to
104469 + classification tree. If the classification tree will pass the
104470 + packet to a queue it will cause a wake interupt. When FALSE it
104471 + the other way around. */
104472 + /* TCP port filtering parameters */
104473 + uint16_t tcp_flags_mask;
104474 + uint8_t tcp_ports_table_size;
104475 + struct auto_res_port_filtering_entry *tcp_ports_table_ptr;
104476 + bool tcp_port_pass_on_hit; /* when TRUE, miss in the table will
104477 + cause the packet to be droped, hit will pass the packet to
104478 + classification tree. If the classification tree will pass the
104479 + packet to a queue it will cause a wake interupt. When FALSE it
104480 + the other way around. */
104481 +};
104482 +
104483 +struct auto_res_port_params
104484 +{
104485 + t_Handle h_FmPortTx;
104486 + struct auto_res_arp_info *p_auto_res_arp_info;
104487 + struct auto_res_echo_ipv4_info *p_auto_res_echo_ipv4_info;
104488 + struct auto_res_ndp_info *p_auto_res_ndp_info;
104489 + struct auto_res_echo_ipv6_info *p_auto_res_echo_ipv6_info;
104490 + struct auto_res_snmp_info *p_auto_res_snmp_info;
104491 + struct auto_res_filtering_info *p_auto_res_filtering_info;
104492 +};
104493 +
104494 +struct auto_res_port_stats
104495 +{
104496 + uint32_t arp_ar_cnt;
104497 + uint32_t echo_icmpv4_ar_cnt;
104498 + uint32_t ndp_ar_cnt;
104499 + uint32_t echo_icmpv6_ar_cnt;
104500 +};
104501 +
104502 +int fm_port_config_autores_for_deepsleep_support(struct fm_port *port,
104503 + struct auto_res_tables_sizes *params);
104504 +
104505 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
104506 + struct auto_res_port_params *params);
104507 +
104508 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
104509 + struct fm_port *port_tx);
104510 +
104511 +bool fm_port_is_in_auto_res_mode(struct fm_port *port);
104512 +
104513 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
104514 + struct fm_port *port);
104515 +
104516 +int fm_port_get_autores_stats(struct fm_port *port, struct auto_res_port_stats
104517 + *stats);
104518 +
104519 +int fm_port_resume(struct fm_port *port);
104520 +
104521 +int fm_port_suspend(struct fm_port *port);
104522 +
104523 +#ifdef CONFIG_FMAN_PFC
104524 +/**************************************************************************//**
104525 +@Function fm_port_set_pfc_priorities_mapping_to_qman_wq
104526 +
104527 +@Description Associate a QMan Work Queue with a PFC priority on this
104528 + FM-port device (Tx port).
104529 +
104530 +@Param[in] port - A handle of the FM port device.
104531 +
104532 +@Param[in] prio - The PFC priority.
104533 +
104534 +@Param[in] wq - The Work Queue associated with the PFC priority.
104535 +
104536 +@Cautions Allowed only after the port is initialized.
104537 +*//***************************************************************************/
104538 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
104539 + uint8_t prio, uint8_t wq);
104540 +#endif
104541 +
104542 +/**************************************************************************//**
104543 +@Function fm_mac_set_exception
104544 +
104545 +@Description Set MAC exception state.
104546 +
104547 +@Param[in] fm_mac_dev - A handle of the FM MAC device.
104548 +@Param[in] exception - FM MAC exception type.
104549 +@Param[in] enable - new state.
104550 +
104551 +*//***************************************************************************/
104552 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
104553 + e_FmMacExceptions exception, bool enable);
104554 +
104555 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev);
104556 +
104557 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params);
104558 +
104559 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
104560 + int len);
104561 +
104562 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable);
104563 +
104564 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable);
104565 +
104566 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable);
104567 +
104568 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev);
104569 +
104570 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version);
104571 +
104572 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev);
104573 +
104574 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev);
104575 +
104576 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev);
104577 +
104578 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
104579 + bool enable);
104580 +
104581 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
104582 + t_EnetAddr *mac_addr);
104583 +
104584 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
104585 + t_EnetAddr *mac_addr);
104586 +
104587 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
104588 + uint8_t *addr);
104589 +
104590 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
104591 + bool link, int speed, bool duplex);
104592 +
104593 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
104594 +
104595 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
104596 +
104597 +int fm_mac_set_rx_pause_frames(
104598 + struct fm_mac_dev *fm_mac_dev, bool en);
104599 +
104600 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
104601 + bool en);
104602 +
104603 +int fm_rtc_enable(struct fm *fm_dev);
104604 +
104605 +int fm_rtc_disable(struct fm *fm_dev);
104606 +
104607 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts);
104608 +
104609 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts);
104610 +
104611 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift);
104612 +
104613 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift);
104614 +
104615 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
104616 + uint64_t time);
104617 +
104618 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
104619 + uint64_t fiper);
104620 +
104621 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
104622 + bool en);
104623 +
104624 +/**************************************************************************//**
104625 +@Function fm_macsec_set_exception
104626 +
104627 +@Description Set MACSEC exception state.
104628 +
104629 +@Param[in] fm_macsec_dev - A handle of the FM MACSEC device.
104630 +@Param[in] exception - FM MACSEC exception type.
104631 +@Param[in] enable - new state.
104632 +
104633 +*//***************************************************************************/
104634 +
104635 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
104636 + fm_macsec_exception exception, bool enable);
104637 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev);
104638 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params);
104639 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev);
104640 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
104641 + *fm_macsec_dev,
104642 + fm_macsec_unknown_sci_frame_treatment treat_mode);
104643 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104644 + bool deliver_uncontrolled);
104645 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104646 + bool discard_uncontrolled);
104647 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104648 + fm_macsec_untag_frame_treatment treat_mode);
104649 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
104650 + uint32_t pnExhThr);
104651 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev);
104652 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev);
104653 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
104654 + fm_macsec_exception exception, bool enable);
104655 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
104656 + int *macsec_revision);
104657 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev);
104658 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev);
104659 +
104660 +
104661 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104662 + fm_macsec_secy_exception exception,
104663 + bool enable);
104664 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104665 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params);
104666 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104667 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104668 + fm_macsec_sci_insertion_mode sci_insertion_mode);
104669 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104670 + bool protect_frames);
104671 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104672 + bool replay_protect, uint32_t replay_window);
104673 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104674 + fm_macsec_valid_frame_behavior validate_frames);
104675 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104676 + bool confidentiality_enable,
104677 + uint32_t confidentiality_offset);
104678 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104679 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104680 + fm_macsec_secy_event event,
104681 + bool enable);
104682 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104683 + struct fm_macsec_secy_sc_params *params);
104684 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104685 + struct rx_sc_dev *sc);
104686 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104687 + struct rx_sc_dev *sc, macsec_an_t an,
104688 + uint32_t lowest_pn, macsec_sa_key_t key);
104689 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104690 + struct rx_sc_dev *sc, macsec_an_t an);
104691 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104692 + struct rx_sc_dev *sc,
104693 + macsec_an_t an);
104694 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104695 + struct rx_sc_dev *sc,
104696 + macsec_an_t an);
104697 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104698 + struct rx_sc_dev *sc,
104699 + macsec_an_t an, uint32_t updt_next_pn);
104700 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104701 + struct rx_sc_dev *sc,
104702 + macsec_an_t an, uint32_t updt_lowest_pn);
104703 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104704 + struct rx_sc_dev *sc,
104705 + macsec_an_t an, macsec_sa_key_t key);
104706 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104707 + macsec_an_t an, macsec_sa_key_t key);
104708 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104709 + macsec_an_t an);
104710 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104711 + macsec_an_t next_active_an,
104712 + macsec_sa_key_t key);
104713 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104714 + macsec_an_t an);
104715 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104716 + macsec_an_t *p_an);
104717 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104718 + struct rx_sc_dev *sc, uint32_t *sc_phys_id);
104719 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104720 + uint32_t *sc_phys_id);
104721 +
104722 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
104723 +/** @} */ /* end of FM_LnxKern_grp group */
104724 +
104725 +/* default values for initializing PTP 1588 timer clock */
104726 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT 2 /* power of 2 for better performance */
104727 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_NS (1 << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT) /* 4ns,250MHz */
104728 +
104729 +#endif /* __LNXWRP_FSL_FMAN_H */
104730 --- /dev/null
104731 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
104732 @@ -0,0 +1,50 @@
104733 +/*
104734 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104735 + *
104736 + * Redistribution and use in source and binary forms, with or without
104737 + * modification, are permitted provided that the following conditions are met:
104738 + * * Redistributions of source code must retain the above copyright
104739 + * notice, this list of conditions and the following disclaimer.
104740 + * * Redistributions in binary form must reproduce the above copyright
104741 + * notice, this list of conditions and the following disclaimer in the
104742 + * documentation and/or other materials provided with the distribution.
104743 + * * Neither the name of Freescale Semiconductor nor the
104744 + * names of its contributors may be used to endorse or promote products
104745 + * derived from this software without specific prior written permission.
104746 + *
104747 + *
104748 + * ALTERNATIVELY, this software may be distributed under the terms of the
104749 + * GNU General Public License ("GPL") as published by the Free Software
104750 + * Foundation, either version 2 of that License or (at your option) any
104751 + * later version.
104752 + *
104753 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104754 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104755 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104756 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104757 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104758 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104759 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104760 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104761 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104762 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104763 + */
104764 +
104765 +#ifndef __XX_H
104766 +#define __XX_H
104767 +
104768 +#include "xx_ext.h"
104769 +
104770 +void * xx_Malloc(uint32_t n);
104771 +void xx_Free(void *p);
104772 +
104773 +void *xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t align);
104774 +void xx_FreeSmart(void *p);
104775 +
104776 +/* never used: */
104777 +#define GetDeviceName(irq) ((char *)NULL)
104778 +
104779 +int GetDeviceIrqNum(int irq);
104780 +
104781 +
104782 +#endif /* __XX_H */
104783 --- /dev/null
104784 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
104785 @@ -0,0 +1,10 @@
104786 +#
104787 +# Makefile for the Freescale Ethernet controllers
104788 +#
104789 +ccflags-y += -DVERSION=\"\"
104790 +#
104791 +#Include netcomm SW specific definitions
104792 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
104793 +#
104794 +
104795 +obj-y += sys_io.o
104796 --- /dev/null
104797 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
104798 @@ -0,0 +1,171 @@
104799 +/*
104800 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104801 + *
104802 + * Redistribution and use in source and binary forms, with or without
104803 + * modification, are permitted provided that the following conditions are met:
104804 + * * Redistributions of source code must retain the above copyright
104805 + * notice, this list of conditions and the following disclaimer.
104806 + * * Redistributions in binary form must reproduce the above copyright
104807 + * notice, this list of conditions and the following disclaimer in the
104808 + * documentation and/or other materials provided with the distribution.
104809 + * * Neither the name of Freescale Semiconductor nor the
104810 + * names of its contributors may be used to endorse or promote products
104811 + * derived from this software without specific prior written permission.
104812 + *
104813 + *
104814 + * ALTERNATIVELY, this software may be distributed under the terms of the
104815 + * GNU General Public License ("GPL") as published by the Free Software
104816 + * Foundation, either version 2 of that License or (at your option) any
104817 + * later version.
104818 + *
104819 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104820 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104821 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104822 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104823 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104824 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104825 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104826 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104827 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104828 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104829 + */
104830 +
104831 +#include <linux/version.h>
104832 +
104833 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
104834 +#define MODVERSIONS
104835 +#endif
104836 +#ifdef MODVERSIONS
104837 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
104838 +#include <linux/modversions.h>
104839 +#else
104840 +#include <config/modversions.h>
104841 +#endif /* LINUX_VERSION_CODE */
104842 +#endif /* MODVERSIONS */
104843 +
104844 +#include <linux/module.h>
104845 +#include <linux/kernel.h>
104846 +
104847 +#include <asm/io.h>
104848 +
104849 +#include "std_ext.h"
104850 +#include "error_ext.h"
104851 +#include "string_ext.h"
104852 +#include "list_ext.h"
104853 +#include "sys_io_ext.h"
104854 +
104855 +
104856 +#define __ERR_MODULE__ MODULE_UNKNOWN
104857 +
104858 +
104859 +typedef struct {
104860 + uint64_t virtAddr;
104861 + uint64_t physAddr;
104862 + uint32_t size;
104863 + t_List node;
104864 +} t_IoMap;
104865 +#define IOMAP_OBJECT(ptr) LIST_OBJECT(ptr, t_IoMap, node)
104866 +
104867 +LIST(mapsList);
104868 +
104869 +
104870 +static void EnqueueIoMap(t_IoMap *p_IoMap)
104871 +{
104872 + uint32_t intFlags;
104873 +
104874 + intFlags = XX_DisableAllIntr();
104875 + LIST_AddToTail(&p_IoMap->node, &mapsList);
104876 + XX_RestoreAllIntr(intFlags);
104877 +}
104878 +
104879 +static t_IoMap * FindIoMapByVirtAddr(uint64_t addr)
104880 +{
104881 + t_IoMap *p_IoMap;
104882 + t_List *p_Pos;
104883 +
104884 + LIST_FOR_EACH(p_Pos, &mapsList)
104885 + {
104886 + p_IoMap = IOMAP_OBJECT(p_Pos);
104887 + if ((addr >= p_IoMap->virtAddr) && (addr < p_IoMap->virtAddr+p_IoMap->size))
104888 + return p_IoMap;
104889 + }
104890 +
104891 + return NULL;
104892 +}
104893 +
104894 +static t_IoMap * FindIoMapByPhysAddr(uint64_t addr)
104895 +{
104896 + t_IoMap *p_IoMap;
104897 + t_List *p_Pos;
104898 +
104899 + LIST_FOR_EACH(p_Pos, &mapsList)
104900 + {
104901 + p_IoMap = IOMAP_OBJECT(p_Pos);
104902 + if ((addr >= p_IoMap->physAddr) && (addr < p_IoMap->physAddr+p_IoMap->size))
104903 + return p_IoMap;
104904 + }
104905 +
104906 + return NULL;
104907 +}
104908 +
104909 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size)
104910 +{
104911 + t_IoMap *p_IoMap;
104912 +
104913 + p_IoMap = (t_IoMap*)XX_Malloc(sizeof(t_IoMap));
104914 + if (!p_IoMap)
104915 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
104916 + memset(p_IoMap, 0, sizeof(t_IoMap));
104917 +
104918 + p_IoMap->virtAddr = virtAddr;
104919 + p_IoMap->physAddr = physAddr;
104920 + p_IoMap->size = size;
104921 +
104922 + INIT_LIST(&p_IoMap->node);
104923 + EnqueueIoMap(p_IoMap);
104924 +
104925 + return E_OK;
104926 +}
104927 +
104928 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr)
104929 +{
104930 + t_IoMap *p_IoMap = FindIoMapByVirtAddr(virtAddr);
104931 + if (!p_IoMap)
104932 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
104933 +
104934 + LIST_Del(&p_IoMap->node);
104935 + XX_Free(p_IoMap);
104936 +
104937 + return E_OK;
104938 +}
104939 +
104940 +uint64_t SYS_PhysToVirt(uint64_t addr)
104941 +{
104942 + t_IoMap *p_IoMap = FindIoMapByPhysAddr(addr);
104943 + if (p_IoMap)
104944 + {
104945 + /* This is optimization - put the latest in the list-head - like a cache */
104946 + if (mapsList.p_Next != &p_IoMap->node)
104947 + {
104948 + uint32_t intFlags = XX_DisableAllIntr();
104949 + LIST_DelAndInit(&p_IoMap->node);
104950 + LIST_Add(&p_IoMap->node, &mapsList);
104951 + XX_RestoreAllIntr(intFlags);
104952 + }
104953 + return (uint64_t)(addr - p_IoMap->physAddr + p_IoMap->virtAddr);
104954 + }
104955 + return PTR_TO_UINT(phys_to_virt((unsigned long)addr));
104956 +}
104957 +
104958 +uint64_t SYS_VirtToPhys(uint64_t addr)
104959 +{
104960 + t_IoMap *p_IoMap;
104961 +
104962 + if (addr == 0)
104963 + return 0;
104964 +
104965 + p_IoMap = FindIoMapByVirtAddr(addr);
104966 + if (p_IoMap)
104967 + return (uint64_t)(addr - p_IoMap->virtAddr + p_IoMap->physAddr);
104968 + return (uint64_t)virt_to_phys(UINT_TO_PTR(addr));
104969 +}
104970 --- /dev/null
104971 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
104972 @@ -0,0 +1,19 @@
104973 +#
104974 +# Makefile for the Freescale Ethernet controllers
104975 +#
104976 +ccflags-y += -DVERSION=\"\"
104977 +#
104978 +#Include netcomm SW specific definitions
104979 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
104980 +
104981 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
104982 +
104983 +ccflags-y += -I$(NCSW_FM_INC)
104984 +ccflags-y += -I$(NET_DPA)
104985 +
104986 +obj-y += fsl-ncsw-PFM.o
104987 +obj-$(CONFIG_FSL_SDK_FMAN_TEST) += fman_test.o
104988 +
104989 +fsl-ncsw-PFM-objs := lnxwrp_fm.o lnxwrp_fm_port.o lnxwrp_ioctls_fm.o \
104990 + lnxwrp_sysfs.o lnxwrp_sysfs_fm.o lnxwrp_sysfs_fm_port.o
104991 +obj-$(CONFIG_COMPAT) += lnxwrp_ioctls_fm_compat.o
104992 --- /dev/null
104993 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
104994 @@ -0,0 +1,1665 @@
104995 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
104996 + * All rights reserved.
104997 + *
104998 + * Redistribution and use in source and binary forms, with or without
104999 + * modification, are permitted provided that the following conditions are met:
105000 + * * Redistributions of source code must retain the above copyright
105001 + * notice, this list of conditions and the following disclaimer.
105002 + * * Redistributions in binary form must reproduce the above copyright
105003 + * notice, this list of conditions and the following disclaimer in the
105004 + * documentation and/or other materials provided with the distribution.
105005 + * * Neither the name of Freescale Semiconductor nor the
105006 + * names of its contributors may be used to endorse or promote products
105007 + * derived from this software without specific prior written permission.
105008 + *
105009 + *
105010 + * ALTERNATIVELY, this software may be distributed under the terms of the
105011 + * GNU General Public License ("GPL") as published by the Free Software
105012 + * Foundation, either version 2 of that License or (at your option) any
105013 + * later version.
105014 + *
105015 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105016 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105017 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105018 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105019 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105020 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105021 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105022 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105023 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105024 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105025 + */
105026 +
105027 +/*
105028 + @File fman_test.c
105029 + @Authors Pistirica Sorin Andrei
105030 + @Description FM Linux test environment
105031 +*/
105032 +
105033 +#include <linux/kernel.h>
105034 +#include <linux/module.h>
105035 +#include <linux/fs.h>
105036 +#include <linux/cdev.h>
105037 +#include <linux/device.h>
105038 +#include <linux/io.h>
105039 +#include <linux/ioport.h>
105040 +#include <linux/of_platform.h>
105041 +#include <linux/ip.h>
105042 +#include <linux/compat.h>
105043 +#include <linux/uaccess.h>
105044 +#include <linux/errno.h>
105045 +#include <linux/netdevice.h>
105046 +#include <linux/spinlock.h>
105047 +#include <linux/types.h>
105048 +#include <linux/fsl_qman.h>
105049 +#include <linux/fsl_bman.h>
105050 +
105051 +/* private headers */
105052 +#include "fm_ext.h"
105053 +#include "lnxwrp_fsl_fman.h"
105054 +#include "fm_port_ext.h"
105055 +#if (DPAA_VERSION == 11)
105056 +#include "../../Peripherals/FM/MAC/memac.h"
105057 +#endif
105058 +#include "fm_test_ioctls.h"
105059 +#include "fsl_fman_test.h"
105060 +
105061 +#include "dpaa_eth.h"
105062 +#include "dpaa_eth_common.h"
105063 +
105064 +#define FMT_FRM_WATERMARK 0xdeadbeefdeadbeeaLL
105065 +
105066 +struct fmt_frame_s {
105067 + ioc_fmt_buff_desc_t buff;
105068 + struct list_head list;
105069 +};
105070 +
105071 +struct fmt_fqs_s {
105072 + struct qman_fq fq_base;
105073 + bool init;
105074 + struct fmt_port_s *fmt_port_priv;
105075 +};
105076 +
105077 +struct fmt_port_pcd_s {
105078 + int num_queues;
105079 + struct fmt_fqs_s *fmt_pcd_fqs;
105080 + uint32_t fqid_base;
105081 +};
105082 +
105083 +/* char dev structure: fm test port */
105084 +struct fmt_port_s {
105085 + bool valid;
105086 + uint8_t id;
105087 + ioc_fmt_port_type port_type;
105088 + ioc_diag_mode diag;
105089 + bool compat_test_type;
105090 +
105091 + /* fm ports */
105092 + /* ! for oh ports p_tx_fm_port_dev == p_rx_fm_port_dev &&
105093 + * p_tx_port == p_rx_port */
105094 + /* t_LnxWrpFmPortDev */
105095 + struct fm_port *p_tx_port;
105096 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
105097 + void *p_tx_fm_port_dev;
105098 + /* t_LnxWrpFmPortDev */
105099 + struct fm_port *p_rx_port;
105100 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
105101 + void *p_rx_fm_port_dev;
105102 +
105103 + void *p_mac_dev;
105104 + uint64_t fm_phys_base_addr;
105105 +
105106 + /* read/write queue manipulation */
105107 + spinlock_t rx_q_lock;
105108 + struct list_head rx_q;
105109 +
105110 + /* tx queuee for injecting traffic */
105111 + int num_of_tx_fqs;
105112 + struct fmt_fqs_s p_tx_fqs[FMAN_TEST_MAX_TX_FQS];
105113 +
105114 + /* pcd private queues manipulation */
105115 + struct fmt_port_pcd_s fmt_port_pcd;
105116 +
105117 + /* debugging stuff */
105118 +
105119 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105120 + atomic_t enqueue_to_qman_frm;
105121 + atomic_t enqueue_to_rxq;
105122 + atomic_t dequeue_from_rxq;
105123 + atomic_t not_enqueue_to_rxq_wrong_frm;
105124 +#endif
105125 +
105126 +};
105127 +
105128 +/* The devices. */
105129 +struct fmt_s {
105130 + int major;
105131 + struct fmt_port_s ports[IOC_FMT_MAX_NUM_OF_PORTS];
105132 + struct class *fmt_class;
105133 +};
105134 +
105135 +/* fm test structure */
105136 +static struct fmt_s fm_test;
105137 +
105138 +#if (DPAA_VERSION == 11)
105139 +struct mac_priv_s {
105140 + t_Handle mac;
105141 +};
105142 +#endif
105143 +
105144 +#define DTSEC_BASE_ADDR 0x000e0000
105145 +#define DTSEC_MEM_RANGE 0x00002000
105146 +#define MAC_1G_MACCFG1 0x00000100
105147 +#define MAC_1G_LOOP_MASK 0x00000100
105148 +static int set_1gmac_loopback(
105149 + struct fmt_port_s *fmt_port,
105150 + bool en)
105151 +{
105152 +#if (DPAA_VERSION <= 10)
105153 + uint32_t dtsec_idx = fmt_port->id; /* dtsec for which port */
105154 + uint32_t dtsec_idx_off = dtsec_idx * DTSEC_MEM_RANGE;
105155 + phys_addr_t maccfg1_hw;
105156 + void *maccfg1_map;
105157 + uint32_t maccfg1_val;
105158 +
105159 + /* compute the maccfg1 register address */
105160 + maccfg1_hw = fmt_port->fm_phys_base_addr +
105161 + (phys_addr_t)(DTSEC_BASE_ADDR +
105162 + dtsec_idx_off +
105163 + MAC_1G_MACCFG1);
105164 +
105165 + /* map register */
105166 + maccfg1_map = ioremap(maccfg1_hw, sizeof(u32));
105167 +
105168 + /* set register */
105169 + maccfg1_val = in_be32(maccfg1_map);
105170 + if (en)
105171 + maccfg1_val |= MAC_1G_LOOP_MASK;
105172 + else
105173 + maccfg1_val &= ~MAC_1G_LOOP_MASK;
105174 + out_be32(maccfg1_map, maccfg1_val);
105175 +
105176 + /* unmap register */
105177 + iounmap(maccfg1_map);
105178 +#else
105179 + struct mac_device *mac_dev;
105180 + struct mac_priv_s *priv;
105181 + t_Memac *p_memac;
105182 +
105183 + if (!fmt_port)
105184 + return -EINVAL;
105185 +
105186 + mac_dev = (struct mac_device *)fmt_port->p_mac_dev;
105187 +
105188 + if (!mac_dev)
105189 + return -EINVAL;
105190 +
105191 + priv = macdev_priv(mac_dev);
105192 +
105193 + if (!priv)
105194 + return -EINVAL;
105195 +
105196 + p_memac = priv->mac;
105197 +
105198 + if (!p_memac)
105199 + return -EINVAL;
105200 +
105201 + memac_set_loopback(p_memac->p_MemMap, en);
105202 +#endif
105203 + return 0;
105204 +}
105205 +
105206 +/* TODO: re-write this function */
105207 +static int set_10gmac_int_loopback(
105208 + struct fmt_port_s *fmt_port,
105209 + bool en)
105210 +{
105211 +#ifndef FM_10G_MAC_NO_CTRL_LOOPBACK
105212 +#define FM_10GMAC0_OFFSET 0x000f0000
105213 +#define FM_10GMAC_CMD_CONF_CTRL_OFFSET 0x8
105214 +#define CMD_CFG_LOOPBACK_EN 0x00000400
105215 +
105216 + uint64_t base_addr, reg_addr;
105217 + uint32_t tmp_val;
105218 +
105219 + base_addr = fmt_port->fm_phys_base_addr + (FM_10GMAC0_OFFSET +
105220 + ((fmt_port->id-FM_MAX_NUM_OF_1G_RX_PORTS)*0x2000));
105221 +
105222 + base_addr = PTR_TO_UINT(ioremap(base_addr, 0x1000));
105223 +
105224 + reg_addr = base_addr + FM_10GMAC_CMD_CONF_CTRL_OFFSET;
105225 + tmp_val = GET_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)));
105226 + if (en)
105227 + tmp_val |= CMD_CFG_LOOPBACK_EN;
105228 + else
105229 + tmp_val &= ~CMD_CFG_LOOPBACK_EN;
105230 + WRITE_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)), tmp_val);
105231 +
105232 + iounmap(UINT_TO_PTR(base_addr));
105233 +
105234 + return 0;
105235 +#else
105236 + _fmt_err("TGEC don't have internal-loopback.\n");
105237 + return -EPERM;
105238 +#endif
105239 +}
105240 +
105241 +static int set_mac_int_loopback(struct fmt_port_s *fmt_port, bool en)
105242 +{
105243 + int _err = 0;
105244 +
105245 + switch (fmt_port->port_type) {
105246 +
105247 + case e_IOC_FMT_PORT_T_RXTX:
105248 + /* 1G port */
105249 + if (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS)
105250 + _err = set_1gmac_loopback(fmt_port, en);
105251 + /* 10g port */
105252 + else if ((fmt_port->id >= FM_MAX_NUM_OF_1G_RX_PORTS) &&
105253 + (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS +
105254 + FM_MAX_NUM_OF_10G_RX_PORTS)) {
105255 +
105256 + _err = set_10gmac_int_loopback(fmt_port, en);
105257 + } else
105258 + _err = -EINVAL;
105259 + break;
105260 + /* op port does not have MAC (loopback mode) */
105261 + case e_IOC_FMT_PORT_T_OP:
105262 +
105263 + _err = 0;
105264 + break;
105265 + default:
105266 +
105267 + _err = -EPERM;
105268 + break;
105269 + }
105270 +
105271 + return _err;
105272 +}
105273 +
105274 +static void enqueue_fmt_frame(
105275 + struct fmt_port_s *fmt_port,
105276 + struct fmt_frame_s *p_fmt_frame)
105277 +{
105278 + spinlock_t *rx_q_lock = NULL;
105279 +
105280 + rx_q_lock = &fmt_port->rx_q_lock;
105281 +
105282 + spin_lock(rx_q_lock);
105283 + list_add_tail(&p_fmt_frame->list, &fmt_port->rx_q);
105284 + spin_unlock(rx_q_lock);
105285 +
105286 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105287 + atomic_inc(&fmt_port->enqueue_to_rxq);
105288 +#endif
105289 +}
105290 +
105291 +static struct fmt_frame_s *dequeue_fmt_frame(
105292 + struct fmt_port_s *fmt_port)
105293 +{
105294 + struct fmt_frame_s *p_fmt_frame = NULL;
105295 + spinlock_t *rx_q_lock = NULL;
105296 +
105297 + rx_q_lock = &fmt_port->rx_q_lock;
105298 +
105299 + spin_lock(rx_q_lock);
105300 +
105301 +#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
105302 +
105303 + if (!list_empty(&fmt_port->rx_q)) {
105304 + p_fmt_frame = list_last_entry(&fmt_port->rx_q,
105305 + struct fmt_frame_s,
105306 + list);
105307 + list_del(&p_fmt_frame->list);
105308 +
105309 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105310 + atomic_inc(&fmt_port->dequeue_from_rxq);
105311 +#endif
105312 + }
105313 +
105314 + spin_unlock(rx_q_lock);
105315 +
105316 + return p_fmt_frame;
105317 +}
105318 +
105319 +/* eth-dev -to- fmt port association */
105320 +struct fmt_port_s *match_dpa_to_fmt_port(
105321 + struct dpa_priv_s *dpa_priv) {
105322 + struct mac_device *mac_dev = dpa_priv->mac_dev;
105323 + struct fm_port *fm_port = (struct fm_port *) mac_dev;
105324 + struct fmt_port_s *fmt_port = NULL;
105325 + int i;
105326 +
105327 + _fmt_dbgr("calling...\n");
105328 +
105329 + /* find the FM-test-port object */
105330 + for (i = 0; i < IOC_FMT_MAX_NUM_OF_PORTS; i++)
105331 + if ((fm_test.ports[i].p_mac_dev &&
105332 + mac_dev == fm_test.ports[i].p_mac_dev) ||
105333 + fm_port == fm_test.ports[i].p_tx_port) {
105334 +
105335 + fmt_port = &fm_test.ports[i];
105336 + break;
105337 + }
105338 +
105339 + _fmt_dbgr("called\n");
105340 + return fmt_port;
105341 +}
105342 +
105343 +void dump_frame(
105344 + uint8_t *buffer,
105345 + uint32_t size)
105346 +{
105347 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105348 + unsigned int i;
105349 +
105350 + for (i = 0; i < size; i++) {
105351 + if (i%16 == 0)
105352 + printk(KERN_DEBUG "\n");
105353 + printk(KERN_DEBUG "%2x ", *(buffer+i));
105354 + }
105355 +#endif
105356 + return;
105357 +}
105358 +
105359 +bool test_and_steal_frame(struct fmt_port_s *fmt_port,
105360 + uint32_t fqid,
105361 + uint8_t *buffer,
105362 + uint32_t size)
105363 +{
105364 + struct fmt_frame_s *p_fmt_frame = NULL;
105365 + bool test_and_steal_frame_frame;
105366 + uint32_t data_offset;
105367 + uint32_t i;
105368 +
105369 + _fmt_dbgr("calling...\n");
105370 +
105371 + if (!fmt_port || !fmt_port->p_rx_fm_port_dev)
105372 + return false;
105373 +
105374 + /* check watermark */
105375 + test_and_steal_frame_frame = false;
105376 + for (i = 0; i < size; i++) {
105377 + uint64_t temp = *((uint64_t *)(buffer + i));
105378 +
105379 + if (temp == (uint64_t) FMT_FRM_WATERMARK) {
105380 + _fmt_dbgr("watermark found!\n");
105381 + test_and_steal_frame_frame = true;
105382 + break;
105383 + }
105384 + }
105385 +
105386 + if (!test_and_steal_frame_frame) {
105387 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105388 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
105389 +#endif
105390 + _fmt_dbgr("NOT watermark found!\n");
105391 + return false;
105392 + }
105393 +
105394 + /* do not enqueue the tx conf/err frames */
105395 + if ((fqid == FMT_TX_CONF_Q) || (fqid == FMT_TX_ERR_Q))
105396 + goto _test_and_steal_frame_return_true;
105397 +
105398 + _fmt_dbgr("on port %d got FMUC frame\n", fmt_port->id);
105399 + data_offset = FM_PORT_GetBufferDataOffset(
105400 + fmt_port->p_rx_fm_port_dev);
105401 +
105402 + p_fmt_frame = kmalloc(sizeof(struct fmt_frame_s), GFP_KERNEL);
105403 +
105404 + /* dump frame... no more space left on device */
105405 + if (p_fmt_frame == NULL) {
105406 + _fmt_err("no space left on device!\n");
105407 + goto _test_and_steal_frame_return_true;
105408 + }
105409 +
105410 + memset(p_fmt_frame, 0, sizeof(struct fmt_frame_s));
105411 + p_fmt_frame->buff.p_data = kmalloc(size * sizeof(uint8_t), GFP_KERNEL);
105412 +
105413 + /* No more space left on device*/
105414 + if (p_fmt_frame->buff.p_data == NULL) {
105415 + _fmt_err("no space left on device!\n");
105416 + kfree(p_fmt_frame);
105417 + goto _test_and_steal_frame_return_true;
105418 + }
105419 +
105420 + p_fmt_frame->buff.size = size-data_offset;
105421 + p_fmt_frame->buff.qid = fqid;
105422 +
105423 + memcpy(p_fmt_frame->buff.p_data,
105424 + (uint8_t *)PTR_MOVE(buffer, data_offset),
105425 + p_fmt_frame->buff.size);
105426 +
105427 + memcpy(p_fmt_frame->buff.buff_context.fm_prs_res,
105428 + FM_PORT_GetBufferPrsResult(fmt_port->p_rx_fm_port_dev,
105429 + (char *)buffer),
105430 + 32);
105431 +
105432 + /* enqueue frame - this frame will go to us */
105433 + enqueue_fmt_frame(fmt_port, p_fmt_frame);
105434 +
105435 +_test_and_steal_frame_return_true:
105436 + return true;
105437 +}
105438 +
105439 +static int fmt_fq_release(const struct qm_fd *fd)
105440 +{
105441 + struct dpa_bp *_dpa_bp;
105442 + struct bm_buffer _bmb;
105443 +
105444 + if (fd->format == qm_fd_contig) {
105445 + _dpa_bp = dpa_bpid2pool(fd->bpid);
105446 + BUG_ON(IS_ERR(_dpa_bp));
105447 +
105448 + _bmb.hi = fd->addr_hi;
105449 + _bmb.lo = fd->addr_lo;
105450 +
105451 + while (bman_release(_dpa_bp->pool, &_bmb, 1, 0))
105452 + cpu_relax();
105453 +
105454 + } else {
105455 + _fmt_err("frame not supported !\n");
105456 + return -1;
105457 + }
105458 +
105459 + return 0;
105460 +}
105461 +
105462 +/* sync it w/ dpaa_eth.c: DPA_BP_HEAD */
105463 +#define DPA_BP_HEADROOM (DPA_TX_PRIV_DATA_SIZE + \
105464 + fm_get_rx_extra_headroom() + \
105465 + DPA_PARSE_RESULTS_SIZE + \
105466 + DPA_HASH_RESULTS_SIZE)
105467 +#define MAC_HEADER_LENGTH 14
105468 +#define L2_AND_HEADROOM_OFF ((DPA_BP_HEADROOM) + (MAC_HEADER_LENGTH))
105469 +
105470 +/* dpa ingress hooks definition */
105471 +enum dpaa_eth_hook_result fmt_rx_default_hook(
105472 + struct sk_buff *skb,
105473 + struct net_device *net_dev,
105474 + u32 fqid)
105475 +{
105476 + struct dpa_priv_s *dpa_priv = NULL;
105477 + struct fmt_port_s *fmt_port = NULL;
105478 + uint8_t *buffer;
105479 + uint32_t buffer_len;
105480 +
105481 + _fmt_dbgr("calling...\n");
105482 +
105483 + dpa_priv = netdev_priv(net_dev);
105484 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105485 +
105486 + /* conversion from skb to fd:
105487 + * skb cames processed for L3, so we need to go back for
105488 + * layer 2 offset */
105489 + buffer = (uint8_t *)(skb->data - ((int)L2_AND_HEADROOM_OFF));
105490 + buffer_len = skb->len + ((int)L2_AND_HEADROOM_OFF);
105491 +
105492 + /* if is not out frame let dpa to handle it */
105493 + if (test_and_steal_frame(fmt_port,
105494 + FMT_RX_DFLT_Q,
105495 + buffer,
105496 + buffer_len))
105497 + goto _fmt_rx_default_hook_stolen;
105498 +
105499 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105500 + return DPAA_ETH_CONTINUE;
105501 +
105502 +_fmt_rx_default_hook_stolen:
105503 + dev_kfree_skb(skb);
105504 +
105505 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105506 + return DPAA_ETH_STOLEN;
105507 +}
105508 +
105509 +enum dpaa_eth_hook_result fmt_rx_error_hook(
105510 + struct net_device *net_dev,
105511 + const struct qm_fd *fd,
105512 + u32 fqid)
105513 +{
105514 + struct dpa_priv_s *dpa_priv = NULL;
105515 + struct dpa_bp *dpa_bp = NULL;
105516 + struct fmt_port_s *fmt_port = NULL;
105517 + void *fd_virt_addr = NULL;
105518 + dma_addr_t addr = qm_fd_addr(fd);
105519 +
105520 + _fmt_dbgr("calling...\n");
105521 +
105522 + dpa_priv = netdev_priv(net_dev);
105523 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105524 +
105525 + /* dpaa doesn't do this... we have to do it here */
105526 + dpa_bp = dpa_bpid2pool(fd->bpid);
105527 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
105528 +
105529 + fd_virt_addr = phys_to_virt(addr);
105530 + /* if is not out frame let dpa to handle it */
105531 + if (test_and_steal_frame(fmt_port,
105532 + FMT_RX_ERR_Q,
105533 + fd_virt_addr,
105534 + fd->length20 + fd->offset)) {
105535 + goto _fmt_rx_error_hook_stolen;
105536 + }
105537 +
105538 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105539 + return DPAA_ETH_CONTINUE;
105540 +
105541 +_fmt_rx_error_hook_stolen:
105542 + /* the frame data doesn't matter,
105543 + * so, no mapping is needed */
105544 + fmt_fq_release(fd);
105545 +
105546 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105547 + return DPAA_ETH_STOLEN;
105548 +}
105549 +
105550 +enum dpaa_eth_hook_result fmt_tx_confirm_hook(
105551 + struct net_device *net_dev,
105552 + const struct qm_fd *fd,
105553 + u32 fqid)
105554 +{
105555 + struct dpa_priv_s *dpa_priv = NULL;
105556 + struct fmt_port_s *fmt_port = NULL;
105557 + dma_addr_t addr = qm_fd_addr(fd);
105558 + void *fd_virt_addr = NULL;
105559 + uint32_t fd_len = 0;
105560 +
105561 + _fmt_dbgr("calling...\n");
105562 +
105563 + dpa_priv = netdev_priv(net_dev);
105564 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105565 +
105566 + fd_virt_addr = phys_to_virt(addr);
105567 + fd_len = fd->length20 + fd->offset;
105568 +
105569 + if (fd_len > fm_get_max_frm()) {
105570 + _fmt_err("tx confirm bad frame size: %u!\n", fd_len);
105571 + goto _fmt_tx_confirm_hook_continue;
105572 + }
105573 +
105574 + if (test_and_steal_frame(fmt_port,
105575 + FMT_TX_CONF_Q,
105576 + fd_virt_addr,
105577 + fd_len))
105578 + goto _fmt_tx_confirm_hook_stolen;
105579 +
105580 +_fmt_tx_confirm_hook_continue:
105581 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105582 + return DPAA_ETH_CONTINUE;
105583 +
105584 +_fmt_tx_confirm_hook_stolen:
105585 + kfree(fd_virt_addr);
105586 +
105587 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105588 + return DPAA_ETH_STOLEN;
105589 +}
105590 +
105591 +enum dpaa_eth_hook_result fmt_tx_confirm_error_hook(
105592 + struct net_device *net_dev,
105593 + const struct qm_fd *fd,
105594 + u32 fqid)
105595 +{
105596 + struct dpa_priv_s *dpa_priv = NULL;
105597 + struct fmt_port_s *fmt_port = NULL;
105598 + dma_addr_t addr = qm_fd_addr(fd);
105599 + void *fd_virt_addr = NULL;
105600 + uint32_t fd_len = 0;
105601 +
105602 + _fmt_dbgr("calling...\n");
105603 +
105604 + dpa_priv = netdev_priv(net_dev);
105605 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105606 +
105607 + fd_virt_addr = phys_to_virt(addr);
105608 + fd_len = fd->length20 + fd->offset;
105609 +
105610 + if (fd_len > fm_get_max_frm()) {
105611 + _fmt_err("tx confirm err bad frame size: %u !\n", fd_len);
105612 + goto _priv_ingress_tx_err_continue;
105613 + }
105614 +
105615 + if (test_and_steal_frame(fmt_port, FMT_TX_ERR_Q, fd_virt_addr, fd_len))
105616 + goto _priv_ingress_tx_err_stolen;
105617 +
105618 +_priv_ingress_tx_err_continue:
105619 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105620 + return DPAA_ETH_CONTINUE;
105621 +
105622 +_priv_ingress_tx_err_stolen:
105623 + kfree(fd_virt_addr);
105624 +
105625 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105626 + return DPAA_ETH_STOLEN;
105627 +}
105628 +
105629 +/* egress callbacks definition */
105630 +enum qman_cb_dqrr_result fmt_egress_dqrr(
105631 + struct qman_portal *portal,
105632 + struct qman_fq *fq,
105633 + const struct qm_dqrr_entry *dqrr)
105634 +{
105635 + /* this callback should never be called */
105636 + BUG();
105637 + return qman_cb_dqrr_consume;
105638 +}
105639 +
105640 +static void fmt_egress_error_dqrr(
105641 + struct qman_portal *p,
105642 + struct qman_fq *fq,
105643 + const struct qm_mr_entry *msg)
105644 +{
105645 + uint8_t *fd_virt_addr = NULL;
105646 +
105647 + /* tx failure, on the ern callback - release buffer */
105648 + fd_virt_addr = (uint8_t *)phys_to_virt(qm_fd_addr(&msg->ern.fd));
105649 + kfree(fd_virt_addr);
105650 +
105651 + return;
105652 +}
105653 +
105654 +static const struct qman_fq fmt_egress_fq = {
105655 + .cb = { .dqrr = fmt_egress_dqrr,
105656 + .ern = fmt_egress_error_dqrr,
105657 + .fqs = NULL}
105658 +};
105659 +
105660 +int fmt_fq_alloc(
105661 + struct fmt_fqs_s *fmt_fqs,
105662 + const struct qman_fq *qman_fq,
105663 + uint32_t fqid, uint32_t flags,
105664 + uint16_t channel, uint8_t wq)
105665 +{
105666 + int _errno = 0;
105667 +
105668 + _fmt_dbg("calling...\n");
105669 +
105670 + fmt_fqs->fq_base = *qman_fq;
105671 +
105672 + if (fqid == 0) {
105673 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
105674 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
105675 + } else
105676 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
105677 +
105678 + fmt_fqs->init = !(flags & QMAN_FQ_FLAG_NO_MODIFY);
105679 +
105680 + _errno = qman_create_fq(fqid, flags, &fmt_fqs->fq_base);
105681 + if (_errno < 0) {
105682 + _fmt_err("frame queues create failed.\n");
105683 + return -EINVAL;
105684 + }
105685 +
105686 + if (fmt_fqs->init) {
105687 + struct qm_mcc_initfq initfq;
105688 +
105689 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
105690 + initfq.fqd.dest.channel = channel;
105691 + initfq.fqd.dest.wq = wq;
105692 +
105693 + _errno = qman_init_fq(&fmt_fqs->fq_base,
105694 + QMAN_INITFQ_FLAG_SCHED,
105695 + &initfq);
105696 + if (_errno < 0) {
105697 + _fmt_err("frame queues init erorr.\n");
105698 + qman_destroy_fq(&fmt_fqs->fq_base, 0);
105699 + return -EINVAL;
105700 + }
105701 + }
105702 +
105703 + _fmt_dbg("called.\n");
105704 + return 0;
105705 +}
105706 +
105707 +static int fmt_fq_free(struct fmt_fqs_s *fmt_fq)
105708 +{
105709 + int _err = 0;
105710 +
105711 + _fmt_dbg("calling...\n");
105712 +
105713 + if (fmt_fq->init) {
105714 + _err = qman_retire_fq(&fmt_fq->fq_base, NULL);
105715 + if (unlikely(_err < 0))
105716 + _fmt_err("qman_retire_fq(%u) = %d\n",
105717 + qman_fq_fqid(&fmt_fq->fq_base), _err);
105718 +
105719 + _err = qman_oos_fq(&fmt_fq->fq_base);
105720 + if (unlikely(_err < 0))
105721 + _fmt_err("qman_oos_fq(%u) = %d\n",
105722 + qman_fq_fqid(&fmt_fq->fq_base), _err);
105723 + }
105724 +
105725 + qman_destroy_fq(&fmt_fq->fq_base, 0);
105726 +
105727 + _fmt_dbg("called.\n");
105728 + return _err;
105729 +}
105730 +
105731 +/* private pcd dqrr calbacks */
105732 +static enum qman_cb_dqrr_result fmt_pcd_dqrr(
105733 + struct qman_portal *portal,
105734 + struct qman_fq *fq,
105735 + const struct qm_dqrr_entry *dq)
105736 +{
105737 + struct dpa_bp *dpa_bp = NULL;
105738 + dma_addr_t addr = qm_fd_addr(&dq->fd);
105739 + uint8_t *fd_virt_addr = NULL;
105740 + struct fmt_port_s *fmt_port;
105741 + struct fmt_port_pcd_s *fmt_port_pcd;
105742 + uint32_t relative_fqid = 0;
105743 + uint32_t fd_len = 0;
105744 +
105745 + _fmt_dbgr("calling...\n");
105746 +
105747 + /* upcast - from pcd_alloc_fq */
105748 + fmt_port = ((struct fmt_fqs_s *)fq)->fmt_port_priv;
105749 + if (!fmt_port) {
105750 + _fmt_err(" wrong fmt port -to- fq match.\n");
105751 + goto _fmt_pcd_dqrr_return;
105752 + }
105753 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
105754 +
105755 + relative_fqid = dq->fqid - fmt_port_pcd->fqid_base;
105756 + _fmt_dbgr("pcd dqrr got frame on relative fq:%u@base:%u\n",
105757 + relative_fqid, fmt_port_pcd->fqid_base);
105758 +
105759 + fd_len = dq->fd.length20 + dq->fd.offset;
105760 +
105761 + if (fd_len > fm_get_max_frm()) {
105762 + _fmt_err("pcd dqrr wrong frame size: %u (%u:%u)!\n",
105763 + fd_len, dq->fd.length20, dq->fd.offset);
105764 + goto _fmt_pcd_dqrr_return;
105765 + }
105766 +
105767 + dpa_bp = dpa_bpid2pool(dq->fd.bpid);
105768 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
105769 +
105770 + fd_virt_addr = phys_to_virt(addr);
105771 + if (!test_and_steal_frame(fmt_port, relative_fqid, fd_virt_addr,
105772 + fd_len)) {
105773 +
105774 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105775 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
105776 +#endif
105777 + _fmt_wrn("pcd dqrr unrecognized frame@fqid: %u,"
105778 + " frame len: %u (dropped).\n",
105779 + dq->fqid, dq->fd.length20);
105780 + dump_frame(fd_virt_addr, fd_len);
105781 + }
105782 +
105783 +_fmt_pcd_dqrr_return:
105784 + /* no need to map again here */
105785 + fmt_fq_release(&dq->fd);
105786 +
105787 + _fmt_dbgr("calle.\n");
105788 + return qman_cb_dqrr_consume;
105789 +}
105790 +
105791 +static void fmt_pcd_err_dqrr(
105792 + struct qman_portal *qm,
105793 + struct qman_fq *fq,
105794 + const struct qm_mr_entry *msg)
105795 +{
105796 + _fmt_err("this callback should never be called.\n");
105797 + BUG();
105798 + return;
105799 +}
105800 +
105801 +static void fmt_pcd_fqs_dqrr(
105802 + struct qman_portal *qm,
105803 + struct qman_fq *fq,
105804 + const struct qm_mr_entry *msg)
105805 +{
105806 + _fmt_dbg(" fq state(0x%x)@fqid(%u.\n", msg->fq.fqs, msg->fq.fqid);
105807 + return;
105808 +}
105809 +
105810 +/* private pcd queue template */
105811 +static const struct qman_fq pcd_fq = {
105812 + .cb = { .dqrr = fmt_pcd_dqrr,
105813 + .ern = fmt_pcd_err_dqrr,
105814 + .fqs = fmt_pcd_fqs_dqrr}
105815 +};
105816 +
105817 +/* defined as weak in dpaa driver. */
105818 +/* ! parameters come from IOCTL call - US */
105819 +int dpa_alloc_pcd_fqids(
105820 + struct device *dev,
105821 + uint32_t num, uint8_t alignment,
105822 + uint32_t *base_fqid)
105823 +{
105824 + int _err = 0, i;
105825 + struct net_device *net_dev = NULL;
105826 + struct dpa_priv_s *dpa_priv = NULL;
105827 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
105828 + struct fmt_fqs_s *fmt_fqs = NULL;
105829 + struct fmt_port_s *fmt_port = NULL;
105830 + int num_allocated = 0;
105831 +
105832 + _fmt_dbg("calling...\n");
105833 +
105834 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
105835 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
105836 +
105837 + if (!netif_msg_probe(dpa_priv)) {
105838 + _fmt_err("dpa not probe.\n");
105839 + _err = -ENODEV;
105840 + goto _pcd_alloc_fqs_err;
105841 + }
105842 +
105843 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105844 + if (!fmt_port) {
105845 + _fmt_err("fmt port not found.");
105846 + _err = -EINVAL;
105847 + goto _pcd_alloc_fqs_err;
105848 + }
105849 +
105850 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
105851 +
105852 + num_allocated = qman_alloc_fqid_range(base_fqid, num, alignment, 0);
105853 +
105854 + if ((num_allocated <= 0) ||
105855 + (num_allocated < num) ||
105856 + (alignment && (*base_fqid) % alignment)) {
105857 + *base_fqid = 0;
105858 + _fmt_err("Failed to alloc pcd fqs rang.\n");
105859 + _err = -EINVAL;
105860 + goto _pcd_alloc_fqs_err;
105861 + }
105862 +
105863 + _fmt_dbg("wanted %d fqs(align %d), got %d fqids@%u.\n",
105864 + num, alignment, num_allocated, *base_fqid);
105865 +
105866 + /* alloc pcd queues */
105867 + fmt_port_pcd->fmt_pcd_fqs = kmalloc(num_allocated *
105868 + sizeof(struct fmt_fqs_s),
105869 + GFP_KERNEL);
105870 + fmt_port_pcd->num_queues = num_allocated;
105871 + fmt_port_pcd->fqid_base = *base_fqid;
105872 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
105873 +
105874 + /* alloc the pcd queues */
105875 + for (i = 0; i < num_allocated; i++, fmt_fqs++) {
105876 + _err = fmt_fq_alloc(
105877 + fmt_fqs,
105878 + &pcd_fq,
105879 + (*base_fqid) + i, QMAN_FQ_FLAG_NO_ENQUEUE,
105880 + dpa_priv->channel, 7);
105881 +
105882 + if (_err < 0)
105883 + goto _pcd_alloc_fqs_err;
105884 +
105885 + /* upcast to identify from where the frames came from */
105886 + fmt_fqs->fmt_port_priv = fmt_port;
105887 + }
105888 +
105889 + _fmt_dbg("called.\n");
105890 + return _err;
105891 +_pcd_alloc_fqs_err:
105892 + if (num_allocated > 0)
105893 + qman_release_fqid_range(*base_fqid, num_allocated);
105894 + /*TODO: free fmt_pcd_fqs if are any */
105895 +
105896 + _fmt_dbg("called(_err:%d).\n", _err);
105897 + return _err;
105898 +}
105899 +
105900 +/* defined as weak in dpaa driver. */
105901 +int dpa_free_pcd_fqids(
105902 + struct device *dev,
105903 + uint32_t base_fqid)
105904 +{
105905 +
105906 + int _err = 0, i;
105907 + struct net_device *net_dev = NULL;
105908 + struct dpa_priv_s *dpa_priv = NULL;
105909 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
105910 + struct fmt_fqs_s *fmt_fqs = NULL;
105911 + struct fmt_port_s *fmt_port = NULL;
105912 + int num_allocated = 0;
105913 +
105914 + _fmt_dbg("calling...\n");
105915 +
105916 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
105917 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
105918 +
105919 + if (!netif_msg_probe(dpa_priv)) {
105920 + _fmt_err("dpa not probe.\n");
105921 + _err = -ENODEV;
105922 + goto _pcd_free_fqs_err;
105923 + }
105924 +
105925 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105926 + if (!fmt_port) {
105927 + _fmt_err("fmt port not found.");
105928 + _err = -EINVAL;
105929 + goto _pcd_free_fqs_err;
105930 + }
105931 +
105932 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
105933 + num_allocated = fmt_port_pcd->num_queues;
105934 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
105935 +
105936 + for (i = 0; i < num_allocated; i++, fmt_fqs++)
105937 + fmt_fq_free(fmt_fqs);
105938 +
105939 + qman_release_fqid_range(base_fqid,num_allocated);
105940 +
105941 + kfree(fmt_port_pcd->fmt_pcd_fqs);
105942 + memset(fmt_port_pcd, 0, sizeof(*fmt_port_pcd));
105943 +
105944 + /* debugging stuff */
105945 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105946 + _fmt_dbg(" portid: %u.\n", fmt_port->id);
105947 + _fmt_dbg(" frames enqueue to qman: %u.\n",
105948 + atomic_read(&fmt_port->enqueue_to_qman_frm));
105949 + _fmt_dbg(" frames enqueue to rxq: %u.\n",
105950 + atomic_read(&fmt_port->enqueue_to_rxq));
105951 + _fmt_dbg(" frames dequeue from rxq: %u.\n",
105952 + atomic_read(&fmt_port->dequeue_from_rxq));
105953 + _fmt_dbg(" frames not enqueue to rxq - wrong frm: %u.\n",
105954 + atomic_read(&fmt_port->not_enqueue_to_rxq_wrong_frm));
105955 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
105956 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
105957 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
105958 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
105959 +#endif
105960 + return 0;
105961 +
105962 +_pcd_free_fqs_err:
105963 + return _err;
105964 +}
105965 +
105966 +static int fmt_port_init(
105967 + struct fmt_port_s *fmt_port,
105968 + ioc_fmt_port_param_t *p_Params)
105969 +{
105970 + struct device_node *fm_node, *fm_port_node;
105971 + const uint32_t *uint32_prop;
105972 + int _errno = 0, lenp = 0, i;
105973 + static struct of_device_id fm_node_of_match[] = {
105974 + { .compatible = "fsl,fman", },
105975 + { /* end of list */ },
105976 + };
105977 +
105978 + _fmt_dbg("calling...\n");
105979 +
105980 + /* init send/receive tu US list */
105981 + INIT_LIST_HEAD(&fmt_port->rx_q);
105982 +
105983 + /* check parameters */
105984 + if (p_Params->num_tx_queues > FMAN_TEST_MAX_TX_FQS ||
105985 + p_Params->fm_port_id > IOC_FMT_MAX_NUM_OF_PORTS) {
105986 + _fmt_dbg("wrong test parameters.\n");
105987 + return -EINVAL;
105988 + }
105989 +
105990 + /* set port parameters */
105991 + fmt_port->num_of_tx_fqs = p_Params->num_tx_queues;
105992 + fmt_port->id = p_Params->fm_port_id;
105993 + fmt_port->port_type = p_Params->fm_port_type;
105994 + fmt_port->diag = e_IOC_DIAG_MODE_NONE;
105995 +
105996 + /* init debugging stuff */
105997 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105998 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
105999 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
106000 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
106001 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
106002 +#endif
106003 +
106004 + /* TODO: This should be done at probe time not at runtime
106005 + * very ugly function */
106006 + /* fill fmt port properties from dts */
106007 + for_each_matching_node(fm_node, fm_node_of_match) {
106008 +
106009 + uint32_prop = (uint32_t *)of_get_property(fm_node,
106010 + "cell-index", &lenp);
106011 + if (unlikely(uint32_prop == NULL)) {
106012 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
106013 + fm_node->full_name);
106014 + return -EINVAL;
106015 + }
106016 + if (WARN_ON(lenp != sizeof(uint32_t))) {
106017 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
106018 + fm_node->full_name);
106019 + return -EINVAL;
106020 + }
106021 +
106022 + if (*uint32_prop == p_Params->fm_id) {
106023 + struct resource res;
106024 +
106025 + /* Get the FM address */
106026 + _errno = of_address_to_resource(fm_node, 0, &res);
106027 + if (unlikely(_errno < 0)) {
106028 + _fmt_wrn("of_address_to_resource() = %u.\n", _errno);
106029 + return -EINVAL;
106030 + }
106031 +
106032 + fmt_port->fm_phys_base_addr = res.start;
106033 +
106034 + for_each_child_of_node(fm_node, fm_port_node) {
106035 + struct platform_device *of_dev;
106036 +
106037 + if (!of_device_is_available(fm_port_node))
106038 + continue;
106039 +
106040 + uint32_prop = (uint32_t *)of_get_property(
106041 + fm_port_node,
106042 + "cell-index",
106043 + &lenp);
106044 + if (uint32_prop == NULL)
106045 + continue;
106046 +
106047 + if (of_device_is_compatible(fm_port_node,
106048 + "fsl,fman-port-oh") &&
106049 + (fmt_port->port_type == e_IOC_FMT_PORT_T_OP)) {
106050 +
106051 + if (*uint32_prop == fmt_port->id) {
106052 + of_dev = of_find_device_by_node(fm_port_node);
106053 + if (unlikely(of_dev == NULL)) {
106054 + _fmt_wrn("fm id invalid\n");
106055 + return -EINVAL;
106056 + }
106057 +
106058 + fmt_port->p_tx_port =
106059 + fm_port_bind(&of_dev->dev);
106060 + fmt_port->p_tx_fm_port_dev =
106061 + (void *)fm_port_get_handle(
106062 + fmt_port->p_tx_port);
106063 + fmt_port->p_rx_port =
106064 + fmt_port->p_tx_port;
106065 + fmt_port->p_rx_fm_port_dev =
106066 + fmt_port->p_tx_fm_port_dev;
106067 + fmt_port->p_mac_dev = NULL;
106068 + break;
106069 + }
106070 + } else if ((*uint32_prop == fmt_port->id) &&
106071 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
106072 +
106073 + of_dev = of_find_device_by_node(fm_port_node);
106074 + if (unlikely(of_dev == NULL)) {
106075 + _fmt_wrn("dtb fm id invalid value");
106076 + return -EINVAL;
106077 + }
106078 +
106079 + if (of_device_is_compatible(fm_port_node,
106080 + "fsl,fman-port-1g-tx")) {
106081 + fmt_port->p_tx_port =
106082 + fm_port_bind(&of_dev->dev);
106083 + fmt_port->p_tx_fm_port_dev = (void *)
106084 + fm_port_get_handle(
106085 + fmt_port->p_tx_port);
106086 + } else if (of_device_is_compatible(fm_port_node,
106087 + "fsl,fman-port-1g-rx")) {
106088 + fmt_port->p_rx_port =
106089 + fm_port_bind(&of_dev->dev);
106090 + fmt_port->p_rx_fm_port_dev = (void *)
106091 + fm_port_get_handle(
106092 + fmt_port->p_rx_port);
106093 + } else if (of_device_is_compatible(fm_port_node,
106094 + "fsl,fman-1g-mac") ||
106095 + of_device_is_compatible(fm_port_node,
106096 + "fsl,fman-memac"))
106097 + fmt_port->p_mac_dev =
106098 + (typeof(fmt_port->p_mac_dev))
106099 + dev_get_drvdata(&of_dev->dev);
106100 + else
106101 + continue;
106102 +
106103 + if (fmt_port->p_tx_fm_port_dev &&
106104 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
106105 + break;
106106 + } else if (((*uint32_prop + FM_MAX_NUM_OF_1G_RX_PORTS) ==
106107 + fmt_port->id) &&
106108 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
106109 +
106110 + of_dev = of_find_device_by_node(fm_port_node);
106111 + if (unlikely(of_dev == NULL)) {
106112 + _fmt_wrn("dtb fm id invalid value\n");
106113 + return -EINVAL;
106114 + }
106115 +
106116 + if (of_device_is_compatible(fm_port_node,
106117 + "fsl,fman-port-10g-tx")) {
106118 + fmt_port->p_tx_port =
106119 + fm_port_bind(&of_dev->dev);
106120 + fmt_port->p_tx_fm_port_dev = (void *)
106121 + fm_port_get_handle(
106122 + fmt_port->p_tx_port);
106123 + } else if (of_device_is_compatible(fm_port_node,
106124 + "fsl,fman-port-10g-rx")) {
106125 + fmt_port->p_rx_port =
106126 + fm_port_bind(&of_dev->dev);
106127 + fmt_port->p_rx_fm_port_dev = (void *)
106128 + fm_port_get_handle(
106129 + fmt_port->p_rx_port);
106130 + } else if (of_device_is_compatible(fm_port_node,
106131 + "fsl,fman-10g-mac") ||
106132 + of_device_is_compatible(fm_port_node,
106133 + "fsl,fman-memac"))
106134 + fmt_port->p_mac_dev =
106135 + (typeof(fmt_port->p_mac_dev))
106136 + dev_get_drvdata(&of_dev->dev);
106137 + else
106138 + continue;
106139 +
106140 + if (fmt_port->p_tx_fm_port_dev &&
106141 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
106142 + break;
106143 + }
106144 + } /* for_each_child */
106145 + }
106146 + } /* for each matching node */
106147 +
106148 + if (fmt_port->p_tx_fm_port_dev == 0 ||
106149 + fmt_port->p_rx_fm_port_dev == 0) {
106150 +
106151 + _fmt_err("bad fm port pointers.\n");
106152 + return -EINVAL;
106153 + }
106154 +
106155 + _fmt_dbg("alloc %u tx queues.\n", fmt_port->num_of_tx_fqs);
106156 +
106157 + /* init fman test egress dynamic frame queues */
106158 + for (i = 0; i < fmt_port->num_of_tx_fqs; i++) {
106159 + int _errno;
106160 + _errno = fmt_fq_alloc(
106161 + &fmt_port->p_tx_fqs[i],
106162 + &fmt_egress_fq,
106163 + 0,
106164 + QMAN_FQ_FLAG_TO_DCPORTAL,
106165 + fm_get_tx_port_channel(fmt_port->p_tx_port),
106166 + i);
106167 +
106168 + if (_errno < 0) {
106169 + _fmt_err("tx queues allocation failed.\n");
106170 + /* TODO: memory leak here if 1 queue is allocated and
106171 + * next queues are failing ... */
106172 + return -EINVAL;
106173 + }
106174 + }
106175 +
106176 + /* port is valid and ready to use. */
106177 + fmt_port->valid = TRUE;
106178 +
106179 + _fmt_dbg("called.\n");
106180 + return 0;
106181 +}
106182 +
106183 +/* fm test chardev functions */
106184 +static int fmt_open(struct inode *inode, struct file *file)
106185 +{
106186 + unsigned int minor = iminor(inode);
106187 +
106188 + _fmt_dbg("calling...\n");
106189 +
106190 + if (file->private_data != NULL)
106191 + return 0;
106192 +
106193 + /* The minor represent the port number.
106194 + * Set the port structure accordingly, thus all the operations
106195 + * will be done on this port. */
106196 + if ((minor >= DEV_FM_TEST_PORTS_MINOR_BASE) &&
106197 + (minor < DEV_FM_TEST_MAX_MINORS))
106198 + file->private_data = &fm_test.ports[minor];
106199 + else
106200 + return -ENXIO;
106201 +
106202 + _fmt_dbg("called.\n");
106203 + return 0;
106204 +}
106205 +
106206 +static int fmt_close(struct inode *inode, struct file *file)
106207 +{
106208 + struct fmt_port_s *fmt_port = NULL;
106209 + struct fmt_frame_s *fmt_frame = NULL;
106210 +
106211 + int err = 0;
106212 +
106213 + _fmt_dbg("calling...\n");
106214 +
106215 + fmt_port = file->private_data;
106216 + if (!fmt_port)
106217 + return -ENODEV;
106218 +
106219 + /* Close the current test port by invalidating it. */
106220 + fmt_port->valid = FALSE;
106221 +
106222 + /* clean the fmt port queue */
106223 + while ((fmt_frame = dequeue_fmt_frame(fmt_port)) != NULL) {
106224 + if (fmt_frame && fmt_frame->buff.p_data){
106225 + kfree(fmt_frame->buff.p_data);
106226 + kfree(fmt_frame);
106227 + }
106228 + }
106229 +
106230 + /* !!! the qman queues are cleaning from fm_ioctl...
106231 + * - very ugly */
106232 +
106233 + _fmt_dbg("called.\n");
106234 + return err;
106235 +}
106236 +
106237 +static int fmt_ioctls(unsigned int minor,
106238 + struct file *file,
106239 + unsigned int cmd,
106240 + unsigned long arg,
106241 + bool compat)
106242 +{
106243 + struct fmt_port_s *fmt_port = NULL;
106244 +
106245 + _fmt_dbg("IOCTL minor:%u "
106246 + " arg:0x%08lx ioctl cmd (0x%08x):(0x%02x:0x%02x.\n",
106247 + minor, arg, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106248 +
106249 + fmt_port = file->private_data;
106250 + if (!fmt_port) {
106251 + _fmt_err("invalid fmt port.\n");
106252 + return -ENODEV;
106253 + }
106254 +
106255 + /* set test type properly */
106256 + if (compat)
106257 + fmt_port->compat_test_type = true;
106258 + else
106259 + fmt_port->compat_test_type = false;
106260 +
106261 + switch (cmd) {
106262 + case FMT_PORT_IOC_INIT:
106263 + {
106264 + ioc_fmt_port_param_t param;
106265 +
106266 + if (fmt_port->valid) {
106267 + _fmt_wrn("port is already initialized.\n");
106268 + return -EFAULT;
106269 + }
106270 +#if defined(CONFIG_COMPAT)
106271 + if (compat) {
106272 + if (copy_from_user(&param,
106273 + (ioc_fmt_port_param_t *)compat_ptr(arg),
106274 + sizeof(ioc_fmt_port_param_t)))
106275 +
106276 + return -EFAULT;
106277 + } else
106278 +#endif
106279 + {
106280 + if (copy_from_user(&param,
106281 + (ioc_fmt_port_param_t *) arg,
106282 + sizeof(ioc_fmt_port_param_t)))
106283 +
106284 + return -EFAULT;
106285 + }
106286 +
106287 + return fmt_port_init(fmt_port, &param);
106288 + }
106289 +
106290 + case FMT_PORT_IOC_SET_DIAG_MODE:
106291 + if (get_user(fmt_port->diag, (ioc_diag_mode *)arg))
106292 + return -EFAULT;
106293 +
106294 + if (fmt_port->diag == e_IOC_DIAG_MODE_CTRL_LOOPBACK)
106295 + return set_mac_int_loopback(fmt_port, TRUE);
106296 + else
106297 + return set_mac_int_loopback(fmt_port, FALSE);
106298 + break;
106299 +
106300 + case FMT_PORT_IOC_SET_DPAECHO_MODE:
106301 + case FMT_PORT_IOC_SET_IP_HEADER_MANIP:
106302 + default:
106303 + _fmt_wrn("ioctl unimplemented minor:%u@ioctl"
106304 + " cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
106305 + minor, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106306 + return -EFAULT;
106307 + }
106308 +
106309 + return 0;
106310 +}
106311 +
106312 +#ifdef CONFIG_COMPAT
106313 +static long fmt_compat_ioctl(
106314 + struct file *file,
106315 + unsigned int cmd,
106316 + unsigned long arg)
106317 +{
106318 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106319 +
106320 + _fmt_dbg("calling...\n");
106321 + return fmt_ioctls(minor, file, cmd, arg, true);
106322 +}
106323 +#endif
106324 +
106325 +static long fmt_ioctl(
106326 + struct file *file,
106327 + unsigned int cmd,
106328 + unsigned long arg)
106329 +{
106330 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106331 + unsigned int res;
106332 +
106333 + _fmt_dbg("calling...\n");
106334 +
106335 + fm_mutex_lock();
106336 + res = fmt_ioctls(minor, file, cmd, arg, false);
106337 + fm_mutex_unlock();
106338 +
106339 + _fmt_dbg("called.\n");
106340 +
106341 + return res;
106342 +}
106343 +
106344 +#ifdef CONFIG_COMPAT
106345 +void copy_compat_test_frame_buffer(
106346 + ioc_fmt_buff_desc_t *buff,
106347 + ioc_fmt_compat_buff_desc_t *compat_buff)
106348 +{
106349 + compat_buff->qid = buff->qid;
106350 + compat_buff->p_data = ptr_to_compat(buff->p_data);
106351 + compat_buff->size = buff->size;
106352 + compat_buff->status = buff->status;
106353 +
106354 + compat_buff->buff_context.p_user_priv =
106355 + ptr_to_compat(buff->buff_context.p_user_priv);
106356 + memcpy(compat_buff->buff_context.fm_prs_res,
106357 + buff->buff_context.fm_prs_res,
106358 + FM_PRS_MAX * sizeof(uint8_t));
106359 + memcpy(compat_buff->buff_context.fm_time_stamp,
106360 + buff->buff_context.fm_time_stamp,
106361 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
106362 +}
106363 +#endif
106364 +
106365 +ssize_t fmt_read(
106366 + struct file *file,
106367 + char __user *buf,
106368 + size_t size,
106369 + loff_t *ppos)
106370 +{
106371 + struct fmt_port_s *fmt_port = NULL;
106372 + struct fmt_frame_s *p_fmt_frame = NULL;
106373 + ssize_t cnt = 0;
106374 +
106375 + fmt_port = file->private_data;
106376 + if (!fmt_port || !fmt_port->valid) {
106377 + _fmt_err("fmt port not valid!\n");
106378 + return -ENODEV;
106379 + }
106380 +
106381 + p_fmt_frame = dequeue_fmt_frame(fmt_port);
106382 + if (p_fmt_frame == NULL)
106383 + return 0;
106384 +
106385 + _fmt_dbgr("calling...\n");
106386 +
106387 +#ifdef CONFIG_COMPAT
106388 + if (fmt_port->compat_test_type){
106389 + cnt = sizeof(ioc_fmt_compat_buff_desc_t);
106390 + }
106391 + else
106392 +#endif
106393 + {
106394 + cnt = sizeof(ioc_fmt_buff_desc_t);
106395 + }
106396 +
106397 + if (size < cnt) {
106398 + _fmt_err("illegal buffer-size!\n");
106399 + cnt = 0;
106400 + goto _fmt_read_return;
106401 + }
106402 +
106403 + /* Copy structure */
106404 +#ifdef CONFIG_COMPAT
106405 + if (fmt_port->compat_test_type) {
106406 + {
106407 + ioc_fmt_compat_buff_desc_t compat_buff;
106408 + copy_compat_test_frame_buffer(&p_fmt_frame->buff,
106409 + &compat_buff);
106410 +
106411 + if (copy_to_user(buf, &compat_buff, cnt)) {
106412 + _fmt_err("copy_to_user failed!\n");
106413 + goto _fmt_read_return;
106414 + }
106415 + }
106416 +
106417 + ((ioc_fmt_compat_buff_desc_t *)buf)->p_data =
106418 + ptr_to_compat(buf+sizeof(ioc_fmt_compat_buff_desc_t));
106419 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
106420 + } else
106421 +#endif
106422 + {
106423 + if (copy_to_user(buf, &p_fmt_frame->buff, cnt)) {
106424 + _fmt_err("copy_to_user failed!\n");
106425 + goto _fmt_read_return;
106426 + }
106427 +
106428 + ((ioc_fmt_buff_desc_t *)buf)->p_data =
106429 + buf + sizeof(ioc_fmt_buff_desc_t);
106430 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
106431 + }
106432 +
106433 + if (size < cnt) {
106434 + _fmt_err("illegal buffer-size!\n");
106435 + goto _fmt_read_return;
106436 + }
106437 +
106438 + /* copy frame */
106439 +#ifdef CONFIG_COMPAT
106440 + if (fmt_port->compat_test_type) {
106441 + if (copy_to_user(buf+sizeof(ioc_fmt_compat_buff_desc_t),
106442 + p_fmt_frame->buff.p_data, cnt)) {
106443 + _fmt_err("copy_to_user failed!\n");
106444 + goto _fmt_read_return;
106445 + }
106446 + } else
106447 +#endif
106448 + {
106449 + if (copy_to_user(buf+sizeof(ioc_fmt_buff_desc_t),
106450 + p_fmt_frame->buff.p_data, cnt)) {
106451 + _fmt_err("copy_to_user failed!\n");
106452 + goto _fmt_read_return;
106453 + }
106454 + }
106455 +
106456 +_fmt_read_return:
106457 + kfree(p_fmt_frame->buff.p_data);
106458 + kfree(p_fmt_frame);
106459 +
106460 + _fmt_dbgr("called.\n");
106461 + return cnt;
106462 +}
106463 +
106464 +ssize_t fmt_write(
106465 + struct file *file,
106466 + const char __user *buf,
106467 + size_t size,
106468 + loff_t *ppos)
106469 +{
106470 + struct fmt_port_s *fmt_port = NULL;
106471 + ioc_fmt_buff_desc_t buff_desc;
106472 +#ifdef CONFIG_COMPAT
106473 + ioc_fmt_compat_buff_desc_t buff_desc_compat;
106474 +#endif
106475 + uint8_t *p_data = NULL;
106476 + uint32_t data_offset;
106477 + int _errno;
106478 + t_DpaaFD fd;
106479 +
106480 + _fmt_dbgr("calling...\n");
106481 +
106482 + fmt_port = file->private_data;
106483 + if (!fmt_port || !fmt_port->valid) {
106484 + _fmt_err("fmt port not valid.\n");
106485 + return -EINVAL;
106486 + }
106487 +
106488 + /* If Compat (32B UserSpace - 64B KernelSpace) */
106489 +#ifdef CONFIG_COMPAT
106490 + if (fmt_port->compat_test_type) {
106491 + if (size < sizeof(ioc_fmt_compat_buff_desc_t)) {
106492 + _fmt_err("invalid buff_desc size.\n");
106493 + return -EFAULT;
106494 + }
106495 +
106496 + if (copy_from_user(&buff_desc_compat, buf,
106497 + sizeof(ioc_fmt_compat_buff_desc_t)))
106498 + return -EFAULT;
106499 +
106500 + buff_desc.qid = buff_desc_compat.qid;
106501 + buff_desc.p_data = compat_ptr(buff_desc_compat.p_data);
106502 + buff_desc.size = buff_desc_compat.size;
106503 + buff_desc.status = buff_desc_compat.status;
106504 +
106505 + buff_desc.buff_context.p_user_priv =
106506 + compat_ptr(buff_desc_compat.buff_context.p_user_priv);
106507 + memcpy(buff_desc.buff_context.fm_prs_res,
106508 + buff_desc_compat.buff_context.fm_prs_res,
106509 + FM_PRS_MAX * sizeof(uint8_t));
106510 + memcpy(buff_desc.buff_context.fm_time_stamp,
106511 + buff_desc_compat.buff_context.fm_time_stamp,
106512 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
106513 + } else
106514 +#endif
106515 + {
106516 + if (size < sizeof(ioc_fmt_buff_desc_t)) {
106517 + _fmt_err("invalid buff_desc size.\n");
106518 + return -EFAULT;
106519 + }
106520 +
106521 + if (copy_from_user(&buff_desc, (ioc_fmt_buff_desc_t *)buf,
106522 + sizeof(ioc_fmt_buff_desc_t)))
106523 + return -EFAULT;
106524 + }
106525 +
106526 + data_offset = FM_PORT_GetBufferDataOffset(fmt_port->p_tx_fm_port_dev);
106527 + p_data = kmalloc(buff_desc.size+data_offset, GFP_KERNEL);
106528 + if (!p_data)
106529 + return -ENOMEM;
106530 +
106531 + /* If Compat (32UserSpace - 64KernelSpace) the buff_desc.p_data is ok */
106532 + if (copy_from_user((uint8_t *)PTR_MOVE(p_data, data_offset),
106533 + buff_desc.p_data,
106534 + buff_desc.size)) {
106535 + kfree(p_data);
106536 + return -EFAULT;
106537 + }
106538 +
106539 + /* TODO: dma_map_single here (cannot access the bpool struct) */
106540 +
106541 + /* prepare fd */
106542 + memset(&fd, 0, sizeof(fd));
106543 + DPAA_FD_SET_ADDR(&fd, p_data);
106544 + DPAA_FD_SET_OFFSET(&fd, data_offset);
106545 + DPAA_FD_SET_LENGTH(&fd, buff_desc.size);
106546 +
106547 + _errno = qman_enqueue(&fmt_port->p_tx_fqs[buff_desc.qid].fq_base,
106548 + (struct qm_fd *)&fd, 0);
106549 + if (_errno) {
106550 + buff_desc.status = (uint32_t)_errno;
106551 + if (copy_to_user((ioc_fmt_buff_desc_t *)buf, &buff_desc,
106552 + sizeof(ioc_fmt_buff_desc_t))) {
106553 + kfree(p_data);
106554 + return -EFAULT;
106555 + }
106556 + }
106557 +
106558 + /* for debugging */
106559 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106560 + atomic_inc(&fmt_port->enqueue_to_qman_frm);
106561 +#endif
106562 + _fmt_dbgr("called.\n");
106563 + return buff_desc.size;
106564 +}
106565 +
106566 +/* fm test character device definition */
106567 +static const struct file_operations fmt_fops =
106568 +{
106569 + .owner = THIS_MODULE,
106570 +#ifdef CONFIG_COMPAT
106571 + .compat_ioctl = fmt_compat_ioctl,
106572 +#endif
106573 + .unlocked_ioctl = fmt_ioctl,
106574 + .open = fmt_open,
106575 + .release = fmt_close,
106576 + .read = fmt_read,
106577 + .write = fmt_write,
106578 +};
106579 +
106580 +static int fmt_init(void)
106581 +{
106582 + int id;
106583 +
106584 + _fmt_dbg("calling...\n");
106585 +
106586 + /* Register to the /dev for IOCTL API */
106587 + /* Register dynamically a new major number for the character device: */
106588 + fm_test.major = register_chrdev(0, DEV_FM_TEST_NAME, &fmt_fops);
106589 + if (fm_test.major <= 0) {
106590 + _fmt_wrn("Failed to allocate major number for device %s.\n",
106591 + DEV_FM_TEST_NAME);
106592 + return -ENODEV;
106593 + }
106594 +
106595 + /* Creating class for FMan_test */
106596 + fm_test.fmt_class = class_create(THIS_MODULE, DEV_FM_TEST_NAME);
106597 + if (IS_ERR(fm_test.fmt_class)) {
106598 + unregister_chrdev(fm_test.major, DEV_FM_TEST_NAME);
106599 + _fmt_wrn("Error creating %s class.\n", DEV_FM_TEST_NAME);
106600 + return -ENODEV;
106601 + }
106602 +
106603 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
106604 + if (NULL == device_create(fm_test.fmt_class, NULL,
106605 + MKDEV(fm_test.major,
106606 + DEV_FM_TEST_PORTS_MINOR_BASE + id), NULL,
106607 + DEV_FM_TEST_NAME "%d", id)) {
106608 +
106609 + _fmt_err("Error creating %s device.\n",
106610 + DEV_FM_TEST_NAME);
106611 + return -ENODEV;
106612 + }
106613 +
106614 + return 0;
106615 +}
106616 +
106617 +static void fmt_free(void)
106618 +{
106619 + int id;
106620 +
106621 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
106622 + device_destroy(fm_test.fmt_class, MKDEV(fm_test.major,
106623 + DEV_FM_TEST_PORTS_MINOR_BASE + id));
106624 + class_destroy(fm_test.fmt_class);
106625 +}
106626 +
106627 +static int __init __cold fmt_load(void)
106628 +{
106629 + struct dpaa_eth_hooks_s priv_dpaa_eth_hooks;
106630 +
106631 + /* set dpaa hooks for default queues */
106632 + memset(&priv_dpaa_eth_hooks, 0, sizeof(priv_dpaa_eth_hooks));
106633 + priv_dpaa_eth_hooks.rx_default = fmt_rx_default_hook;
106634 + priv_dpaa_eth_hooks.rx_error = fmt_rx_error_hook;
106635 + priv_dpaa_eth_hooks.tx_confirm = fmt_tx_confirm_hook;
106636 + priv_dpaa_eth_hooks.tx_error = fmt_tx_confirm_error_hook;
106637 +
106638 + fsl_dpaa_eth_set_hooks(&priv_dpaa_eth_hooks);
106639 +
106640 + /* initialize the fman test environment */
106641 + if (fmt_init() < 0) {
106642 + _fmt_err("Failed to init FM-test modul.\n");
106643 + fmt_free();
106644 + return -ENODEV;
106645 + }
106646 +
106647 + _fmt_inf("FSL FM test module loaded.\n");
106648 +
106649 + return 0;
106650 +}
106651 +
106652 +static void __exit __cold fmt_unload(void)
106653 +{
106654 + fmt_free();
106655 + _fmt_inf("FSL FM test module unloaded.\n");
106656 +}
106657 +
106658 +module_init(fmt_load);
106659 +module_exit(fmt_unload);
106660 --- /dev/null
106661 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
106662 @@ -0,0 +1,2908 @@
106663 +/*
106664 + * Copyright 2008-2012 Freescale Semiconductor Inc.
106665 + *
106666 + * Redistribution and use in source and binary forms, with or without
106667 + * modification, are permitted provided that the following conditions are met:
106668 + * * Redistributions of source code must retain the above copyright
106669 + * notice, this list of conditions and the following disclaimer.
106670 + * * Redistributions in binary form must reproduce the above copyright
106671 + * notice, this list of conditions and the following disclaimer in the
106672 + * documentation and/or other materials provided with the distribution.
106673 + * * Neither the name of Freescale Semiconductor nor the
106674 + * names of its contributors may be used to endorse or promote products
106675 + * derived from this software without specific prior written permission.
106676 + *
106677 + *
106678 + * ALTERNATIVELY, this software may be distributed under the terms of the
106679 + * GNU General Public License ("GPL") as published by the Free Software
106680 + * Foundation, either version 2 of that License or (at your option) any
106681 + * later version.
106682 + *
106683 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
106684 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
106685 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
106686 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
106687 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
106688 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
106689 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
106690 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
106691 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
106692 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106693 + */
106694 +
106695 +/*
106696 + @File lnxwrp_fm.c
106697 + @Author Shlomi Gridish
106698 + @Description FM Linux wrapper functions.
106699 +*/
106700 +
106701 +#include <linux/version.h>
106702 +#include <linux/slab.h>
106703 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
106704 +#define MODVERSIONS
106705 +#endif
106706 +#ifdef MODVERSIONS
106707 +#include <config/modversions.h>
106708 +#endif /* MODVERSIONS */
106709 +#include <linux/kernel.h>
106710 +#include <linux/module.h>
106711 +#include <linux/fs.h>
106712 +#include <linux/cdev.h>
106713 +#include <linux/device.h>
106714 +#include <linux/irq.h>
106715 +#include <linux/interrupt.h>
106716 +#include <linux/io.h>
106717 +#include <linux/ioport.h>
106718 +#include <linux/of_platform.h>
106719 +#include <linux/of_address.h>
106720 +#include <linux/of_irq.h>
106721 +#include <linux/clk.h>
106722 +#include <asm/uaccess.h>
106723 +#include <asm/errno.h>
106724 +#ifndef CONFIG_FMAN_ARM
106725 +#include <sysdev/fsl_soc.h>
106726 +#include <linux/fsl/guts.h>
106727 +#include <linux/fsl/svr.h>
106728 +#endif
106729 +#include <linux/stat.h> /* For file access mask */
106730 +#include <linux/skbuff.h>
106731 +#include <linux/proc_fs.h>
106732 +
106733 +/* NetCommSw Headers --------------- */
106734 +#include "std_ext.h"
106735 +#include "error_ext.h"
106736 +#include "sprint_ext.h"
106737 +#include "debug_ext.h"
106738 +#include "sys_io_ext.h"
106739 +
106740 +#include "fm_ioctls.h"
106741 +
106742 +#include "lnxwrp_fm.h"
106743 +#include "lnxwrp_resources.h"
106744 +#include "lnxwrp_sysfs_fm.h"
106745 +#include "lnxwrp_sysfs_fm_port.h"
106746 +#include "lnxwrp_exp_sym.h"
106747 +#include "fm_common.h"
106748 +#include "../../sdk_fman/Peripherals/FM/fm.h"
106749 +#define __ERR_MODULE__ MODULE_FM
106750 +
106751 +extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
106752 + e_FmPortType portType,
106753 + uint8_t portId);
106754 +
106755 +#define PROC_PRINT(args...) offset += sprintf(buf+offset,args)
106756 +
106757 +#define ADD_ADV_CONFIG_NO_RET(_func, _param) \
106758 + do { \
106759 + if (i<max){ \
106760 + p_Entry = &p_Entrys[i]; \
106761 + p_Entry->p_Function = _func; \
106762 + _param \
106763 + i++; \
106764 + } \
106765 + else \
106766 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
106767 + ("Number of advanced-configuration entries exceeded"));\
106768 + } while (0)
106769 +
106770 +/* Bootarg used to override the Kconfig FSL_FM_MAX_FRAME_SIZE value */
106771 +#define FSL_FM_MAX_FRM_BOOTARG "fsl_fm_max_frm"
106772 +
106773 +/* Bootarg used to override FSL_FM_RX_EXTRA_HEADROOM Kconfig value */
106774 +#define FSL_FM_RX_EXTRA_HEADROOM_BOOTARG "fsl_fm_rx_extra_headroom"
106775 +
106776 +/* Minimum and maximum value for the fsl_fm_rx_extra_headroom bootarg */
106777 +#define FSL_FM_RX_EXTRA_HEADROOM_MIN 16
106778 +#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384
106779 +
106780 +#define FSL_FM_PAUSE_TIME_ENABLE 0xf000
106781 +#define FSL_FM_PAUSE_TIME_DISABLE 0
106782 +#define FSL_FM_PAUSE_THRESH_DEFAULT 0
106783 +
106784 +/*
106785 + * Max frame size, across all interfaces.
106786 + * Configurable from Kconfig or bootargs, to avoid allocating
106787 + * oversized (socket) buffers when not using jumbo frames.
106788 + * Must be large enough to accommodate the network MTU, but small enough
106789 + * to avoid wasting skb memory.
106790 + *
106791 + * Could be overridden once, at boot-time, via the
106792 + * fm_set_max_frm() callback.
106793 + */
106794 +int fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
106795 +
106796 +/*
106797 + * Extra headroom for Rx buffers.
106798 + * FMan is instructed to allocate, on the Rx path, this amount of
106799 + * space at the beginning of a data buffer, beside the DPA private
106800 + * data area and the IC fields.
106801 + * Does not impact Tx buffer layout.
106802 + *
106803 + * Configurable from Kconfig or bootargs. Zero by default, it's needed
106804 + * on particular forwarding scenarios that add extra headers to the
106805 + * forwarded frame.
106806 + */
106807 +int fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
106808 +
106809 +#ifdef CONFIG_FMAN_PFC
106810 +static int fsl_fm_pfc_quanta[] = {
106811 + CONFIG_FMAN_PFC_QUANTA_0,
106812 + CONFIG_FMAN_PFC_QUANTA_1,
106813 + CONFIG_FMAN_PFC_QUANTA_2,
106814 + CONFIG_FMAN_PFC_QUANTA_3
106815 +};
106816 +#endif
106817 +
106818 +static t_LnxWrpFm lnxWrpFm;
106819 +
106820 +int fm_get_max_frm()
106821 +{
106822 + return fsl_fm_max_frm;
106823 +}
106824 +EXPORT_SYMBOL(fm_get_max_frm);
106825 +
106826 +int fm_get_rx_extra_headroom()
106827 +{
106828 + return ALIGN(fsl_fm_rx_extra_headroom, 16);
106829 +}
106830 +EXPORT_SYMBOL(fm_get_rx_extra_headroom);
106831 +
106832 +static int __init fm_set_max_frm(char *str)
106833 +{
106834 + int ret = 0;
106835 +
106836 + ret = get_option(&str, &fsl_fm_max_frm);
106837 + if (ret != 1) {
106838 + /*
106839 + * This will only work if CONFIG_EARLY_PRINTK is compiled in,
106840 + * and something like "earlyprintk=serial,uart0,115200" is
106841 + * specified in the bootargs
106842 + */
106843 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
106844 + "will use the default FSL_FM_MAX_FRAME_SIZE (%d) "
106845 + "from Kconfig.\n", FSL_FM_MAX_FRM_BOOTARG,
106846 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
106847 +
106848 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
106849 + return 1;
106850 + }
106851 +
106852 + /* Don't allow invalid bootargs; fallback to the Kconfig value */
106853 + if (fsl_fm_max_frm < 64 || fsl_fm_max_frm > 9600) {
106854 + printk(KERN_WARNING "Invalid %s=%d in bootargs, valid range is "
106855 + "64-9600. Falling back to the FSL_FM_MAX_FRAME_SIZE (%d) "
106856 + "from Kconfig.\n",
106857 + FSL_FM_MAX_FRM_BOOTARG, fsl_fm_max_frm,
106858 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
106859 +
106860 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
106861 + return 1;
106862 + }
106863 +
106864 + printk(KERN_INFO "Using fsl_fm_max_frm=%d from bootargs\n",
106865 + fsl_fm_max_frm);
106866 + return 0;
106867 +}
106868 +early_param(FSL_FM_MAX_FRM_BOOTARG, fm_set_max_frm);
106869 +
106870 +static int __init fm_set_rx_extra_headroom(char *str)
106871 +{
106872 + int ret;
106873 +
106874 + ret = get_option(&str, &fsl_fm_rx_extra_headroom);
106875 +
106876 + if (ret != 1) {
106877 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
106878 + "will use the default FSL_FM_RX_EXTRA_HEADROOM (%d) "
106879 + "from Kconfig.\n", FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
106880 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
106881 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
106882 +
106883 + return 1;
106884 + }
106885 +
106886 + if (fsl_fm_rx_extra_headroom < FSL_FM_RX_EXTRA_HEADROOM_MIN ||
106887 + fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX) {
106888 + printk(KERN_WARNING "Invalid value for %s=%d prop in "
106889 + "bootargs; will use the default "
106890 + "FSL_FM_RX_EXTRA_HEADROOM (%d) from Kconfig.\n",
106891 + FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
106892 + fsl_fm_rx_extra_headroom,
106893 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
106894 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
106895 + }
106896 +
106897 + printk(KERN_INFO "Using fsl_fm_rx_extra_headroom=%d from bootargs\n",
106898 + fsl_fm_rx_extra_headroom);
106899 +
106900 + return 0;
106901 +}
106902 +early_param(FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, fm_set_rx_extra_headroom);
106903 +
106904 +static irqreturn_t fm_irq(int irq, void *_dev)
106905 +{
106906 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
106907 +#ifdef CONFIG_PM_SLEEP
106908 + t_Fm *p_Fm = (t_Fm*)p_LnxWrpFmDev->h_Dev;
106909 +#endif
106910 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
106911 + return IRQ_NONE;
106912 +
106913 +#ifdef CONFIG_PM_SLEEP
106914 + if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP)
106915 + {
106916 + pm_wakeup_event(p_LnxWrpFmDev->dev, 200);
106917 + }
106918 +#endif
106919 + FM_EventIsr(p_LnxWrpFmDev->h_Dev);
106920 + return IRQ_HANDLED;
106921 +}
106922 +
106923 +static irqreturn_t fm_err_irq(int irq, void *_dev)
106924 +{
106925 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
106926 +
106927 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
106928 + return IRQ_NONE;
106929 +
106930 + if (FM_ErrorIsr(p_LnxWrpFmDev->h_Dev) == E_OK)
106931 + return IRQ_HANDLED;
106932 +
106933 + return IRQ_NONE;
106934 +}
106935 +
106936 +/* used to protect FMD/LLD from concurrent calls in functions fm_mutex_lock / fm_mutex_unlock */
106937 +static struct mutex lnxwrp_mutex;
106938 +
106939 +static t_LnxWrpFmDev * CreateFmDev(uint8_t id)
106940 +{
106941 + t_LnxWrpFmDev *p_LnxWrpFmDev;
106942 + int j;
106943 +
106944 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)XX_Malloc(sizeof(t_LnxWrpFmDev));
106945 + if (!p_LnxWrpFmDev)
106946 + {
106947 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
106948 + return NULL;
106949 + }
106950 +
106951 + memset(p_LnxWrpFmDev, 0, sizeof(t_LnxWrpFmDev));
106952 + p_LnxWrpFmDev->fmDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106953 + memset(p_LnxWrpFmDev->fmDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106954 + p_LnxWrpFmDev->fmPcdDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106955 + memset(p_LnxWrpFmDev->fmPcdDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106956 + p_LnxWrpFmDev->hcPort.settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106957 + memset(p_LnxWrpFmDev->hcPort.settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106958 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
106959 + {
106960 + p_LnxWrpFmDev->rxPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106961 + memset(p_LnxWrpFmDev->rxPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106962 + }
106963 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
106964 + {
106965 + p_LnxWrpFmDev->txPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106966 + memset(p_LnxWrpFmDev->txPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106967 + }
106968 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
106969 + {
106970 + p_LnxWrpFmDev->opPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106971 + memset(p_LnxWrpFmDev->opPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106972 + }
106973 +
106974 + return p_LnxWrpFmDev;
106975 +}
106976 +
106977 +static void DestroyFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
106978 +{
106979 + int j;
106980 +
106981 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
106982 + if (p_LnxWrpFmDev->opPorts[j].settings.advConfig)
106983 + XX_Free(p_LnxWrpFmDev->opPorts[j].settings.advConfig);
106984 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
106985 + if (p_LnxWrpFmDev->txPorts[j].settings.advConfig)
106986 + XX_Free(p_LnxWrpFmDev->txPorts[j].settings.advConfig);
106987 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
106988 + if (p_LnxWrpFmDev->rxPorts[j].settings.advConfig)
106989 + XX_Free(p_LnxWrpFmDev->rxPorts[j].settings.advConfig);
106990 + if (p_LnxWrpFmDev->hcPort.settings.advConfig)
106991 + XX_Free(p_LnxWrpFmDev->hcPort.settings.advConfig);
106992 + if (p_LnxWrpFmDev->fmPcdDevSettings.advConfig)
106993 + XX_Free(p_LnxWrpFmDev->fmPcdDevSettings.advConfig);
106994 + if (p_LnxWrpFmDev->fmDevSettings.advConfig)
106995 + XX_Free(p_LnxWrpFmDev->fmDevSettings.advConfig);
106996 +
106997 + XX_Free(p_LnxWrpFmDev);
106998 +}
106999 +
107000 +static t_Error FillRestFmInfo(t_LnxWrpFmDev *p_LnxWrpFmDev)
107001 +{
107002 +#define FM_BMI_PPIDS_OFFSET 0x00080304
107003 +#define FM_DMA_PLR_OFFSET 0x000c2060
107004 +#define FM_FPM_IP_REV_1_OFFSET 0x000c30c4
107005 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
107006 +#define DMA_LOW_LIODN_MASK 0x00000FFF
107007 +#define DMA_LIODN_SHIFT 16
107008 +
107009 +typedef _Packed struct {
107010 + uint32_t plr[32];
107011 +} _PackedType t_Plr;
107012 +
107013 +typedef _Packed struct {
107014 + volatile uint32_t fmbm_ppid[63];
107015 +} _PackedType t_Ppids;
107016 +
107017 + t_Plr *p_Plr;
107018 + t_Ppids *p_Ppids;
107019 + int i,j;
107020 + uint32_t fmRev;
107021 +
107022 + static const uint8_t phys1GRxPortId[] = {0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
107023 + static const uint8_t phys10GRxPortId[] = {0x10,0x11};
107024 +#if (DPAA_VERSION >= 11)
107025 + static const uint8_t physOhPortId[] = {/* 0x1, */0x2,0x3,0x4,0x5,0x6,0x7};
107026 +#else
107027 + static const uint8_t physOhPortId[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7};
107028 +#endif
107029 + static const uint8_t phys1GTxPortId[] = {0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f};
107030 + static const uint8_t phys10GTxPortId[] = {0x30,0x31};
107031 +
107032 + fmRev = (uint32_t)(*((volatile uint32_t *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_FPM_IP_REV_1_OFFSET)));
107033 + fmRev &= 0xffff;
107034 +
107035 + p_Plr = (t_Plr *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_DMA_PLR_OFFSET);
107036 +#ifdef MODULE
107037 + for (i=0;i<FM_MAX_NUM_OF_PARTITIONS/2;i++)
107038 + p_Plr->plr[i] = 0;
107039 +#endif /* MODULE */
107040 +
107041 + for (i=0; i<FM_MAX_NUM_OF_PARTITIONS; i++)
107042 + {
107043 + uint16_t liodnBase = (uint16_t)((i%2) ?
107044 + (p_Plr->plr[i/2] & DMA_LOW_LIODN_MASK) :
107045 + ((p_Plr->plr[i/2] & DMA_HIGH_LIODN_MASK) >> DMA_LIODN_SHIFT));
107046 +#ifdef FM_PARTITION_ARRAY
107047 + /* TODO: this was .liodnPerPartition[i] = liodnBase; is the index meaning the same? */
107048 + p_LnxWrpFmDev->fmDevSettings.param.liodnBasePerPort[i] = liodnBase;
107049 +#endif /* FM_PARTITION_ARRAY */
107050 +
107051 + if ((i >= phys1GRxPortId[0]) &&
107052 + (i <= phys1GRxPortId[FM_MAX_NUM_OF_1G_RX_PORTS-1]))
107053 + {
107054 + for (j=0; j<ARRAY_SIZE(phys1GRxPortId); j++)
107055 + if (phys1GRxPortId[j] == i)
107056 + break;
107057 + ASSERT_COND(j<ARRAY_SIZE(phys1GRxPortId));
107058 + p_LnxWrpFmDev->rxPorts[j].settings.param.liodnBase = liodnBase;
107059 + }
107060 + else if (FM_MAX_NUM_OF_10G_RX_PORTS &&
107061 + (i >= phys10GRxPortId[0]) &&
107062 + (i <= phys10GRxPortId[FM_MAX_NUM_OF_10G_RX_PORTS-1]))
107063 + {
107064 + for (j=0; j<ARRAY_SIZE(phys10GRxPortId); j++)
107065 + if (phys10GRxPortId[j] == i)
107066 + break;
107067 + ASSERT_COND(j<ARRAY_SIZE(phys10GRxPortId));
107068 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+j].settings.param.liodnBase = liodnBase;
107069 + }
107070 + else if ((i >= physOhPortId[0]) &&
107071 + (i <= physOhPortId[FM_MAX_NUM_OF_OH_PORTS-1]))
107072 + {
107073 + for (j=0; j<ARRAY_SIZE(physOhPortId); j++)
107074 + if (physOhPortId[j] == i)
107075 + break;
107076 + ASSERT_COND(j<ARRAY_SIZE(physOhPortId));
107077 + if (j == 0)
107078 + p_LnxWrpFmDev->hcPort.settings.param.liodnBase = liodnBase;
107079 + else
107080 + p_LnxWrpFmDev->opPorts[j - 1].settings.param.liodnBase = liodnBase;
107081 + }
107082 + else if ((i >= phys1GTxPortId[0]) &&
107083 + (i <= phys1GTxPortId[FM_MAX_NUM_OF_1G_TX_PORTS-1]))
107084 + {
107085 + for (j=0; j<ARRAY_SIZE(phys1GTxPortId); j++)
107086 + if (phys1GTxPortId[j] == i)
107087 + break;
107088 + ASSERT_COND(j<ARRAY_SIZE(phys1GTxPortId));
107089 + p_LnxWrpFmDev->txPorts[j].settings.param.liodnBase = liodnBase;
107090 + }
107091 + else if (FM_MAX_NUM_OF_10G_TX_PORTS &&
107092 + (i >= phys10GTxPortId[0]) &&
107093 + (i <= phys10GTxPortId[FM_MAX_NUM_OF_10G_TX_PORTS-1]))
107094 + {
107095 + for (j=0; j<ARRAY_SIZE(phys10GTxPortId); j++)
107096 + if (phys10GTxPortId[j] == i)
107097 + break;
107098 + ASSERT_COND(j<ARRAY_SIZE(phys10GTxPortId));
107099 + p_LnxWrpFmDev->txPorts[FM_MAX_NUM_OF_1G_TX_PORTS+j].settings.param.liodnBase = liodnBase;
107100 + }
107101 + }
107102 +
107103 + p_Ppids = (t_Ppids *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_BMI_PPIDS_OFFSET);
107104 +
107105 + for (i=0; i<FM_MAX_NUM_OF_1G_RX_PORTS; i++)
107106 + p_LnxWrpFmDev->rxPorts[i].settings.param.specificParams.rxParams.liodnOffset =
107107 + p_Ppids->fmbm_ppid[phys1GRxPortId[i]-1];
107108 +
107109 + for (i=0; i<FM_MAX_NUM_OF_10G_RX_PORTS; i++)
107110 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+i].settings.param.specificParams.rxParams.liodnOffset =
107111 + p_Ppids->fmbm_ppid[phys10GRxPortId[i]-1];
107112 +
107113 + return E_OK;
107114 +}
107115 +
107116 +/* Structure that defines QE firmware binary files.
107117 + *
107118 + * See Documentation/powerpc/qe_firmware.txt for a description of these
107119 + * fields.
107120 + */
107121 +struct qe_firmware {
107122 + struct qe_header {
107123 + __be32 length; /* Length of the entire structure, in bytes */
107124 + u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */
107125 + u8 version; /* Version of this layout. First ver is '1' */
107126 + } header;
107127 + u8 id[62]; /* Null-terminated identifier string */
107128 + u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */
107129 + u8 count; /* Number of microcode[] structures */
107130 + struct {
107131 + __be16 model; /* The SOC model */
107132 + u8 major; /* The SOC revision major */
107133 + u8 minor; /* The SOC revision minor */
107134 + } __attribute__ ((packed)) soc;
107135 + u8 padding[4]; /* Reserved, for alignment */
107136 + __be64 extended_modes; /* Extended modes */
107137 + __be32 vtraps[8]; /* Virtual trap addresses */
107138 + u8 reserved[4]; /* Reserved, for future expansion */
107139 + struct qe_microcode {
107140 + u8 id[32]; /* Null-terminated identifier */
107141 + __be32 traps[16]; /* Trap addresses, 0 == ignore */
107142 + __be32 eccr; /* The value for the ECCR register */
107143 + __be32 iram_offset; /* Offset into I-RAM for the code */
107144 + __be32 count; /* Number of 32-bit words of the code */
107145 + __be32 code_offset; /* Offset of the actual microcode */
107146 + u8 major; /* The microcode version major */
107147 + u8 minor; /* The microcode version minor */
107148 + u8 revision; /* The microcode version revision */
107149 + u8 padding; /* Reserved, for alignment */
107150 + u8 reserved[4]; /* Reserved, for future expansion */
107151 + } __attribute__ ((packed)) microcode[1];
107152 + /* All microcode binaries should be located here */
107153 + /* CRC32 should be located here, after the microcode binaries */
107154 +} __attribute__ ((packed));
107155 +
107156 +
107157 +/**
107158 + * FindFmanMicrocode - find the Fman microcode
107159 + *
107160 + * This function returns a pointer to the QE Firmware blob that holds
107161 + * the Fman microcode. We use the QE Firmware structure because Fman microcode
107162 + * is similar to QE microcode, so there's no point in defining a new layout.
107163 + *
107164 + * Current versions of U-Boot embed the Fman firmware into the device tree,
107165 + * so we check for that first. Each Fman node in the device tree contains a
107166 + * node or a pointer to node that holds the firmware. Technically, we should
107167 + * be fetching the firmware node for the current Fman, but we don't have that
107168 + * information any more, so we assume that there is only one firmware node in
107169 + * the device tree, and that all Fmen use the same firmware.
107170 + */
107171 +static const struct qe_firmware *FindFmanMicrocode(void)
107172 +{
107173 + static const struct qe_firmware *P4080_UCPatch;
107174 + struct device_node *np;
107175 +
107176 + if (P4080_UCPatch)
107177 + return P4080_UCPatch;
107178 +
107179 + /* The firmware should be inside the device tree. */
107180 + np = of_find_compatible_node(NULL, NULL, "fsl,fman-firmware");
107181 + if (np) {
107182 + P4080_UCPatch = of_get_property(np, "fsl,firmware", NULL);
107183 + of_node_put(np);
107184 + if (P4080_UCPatch)
107185 + return P4080_UCPatch;
107186 + else
107187 + REPORT_ERROR(WARNING, E_NOT_FOUND, ("firmware node is incomplete"));
107188 + }
107189 +
107190 + /* Returning NULL here forces the reuse of the IRAM content */
107191 + return NULL;
107192 +}
107193 +#define SVR_SECURITY_MASK 0x00080000
107194 +#define SVR_PERSONALITY_MASK 0x0000FF00
107195 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
107196 +#define SVR_B4860_REV1_VALUE 0x86800010
107197 +#define SVR_B4860_REV2_VALUE 0x86800020
107198 +#define SVR_T4240_VALUE 0x82400000
107199 +#define SVR_T4120_VALUE 0x82400100
107200 +#define SVR_T4160_VALUE 0x82410000
107201 +#define SVR_T4080_VALUE 0x82410200
107202 +#define SVR_T4_DEVICE_ID 0x82400000
107203 +#define SVR_DEVICE_ID_MASK 0xFFF00000
107204 +
107205 +#define OF_DEV_ID_NUM 2 /* one used, another one zeroed */
107206 +
107207 +/* searches for a subnode with the given name/compatible */
107208 +static bool HasFmPcdOfNode(struct device_node *fm_node,
107209 + struct of_device_id *ids,
107210 + const char *name,
107211 + const char *compatible)
107212 +{
107213 + struct device_node *dev_node;
107214 + bool ret = false;
107215 +
107216 + memset(ids, 0, OF_DEV_ID_NUM*sizeof(struct of_device_id));
107217 + if (WARN_ON(strlen(name) >= sizeof(ids[0].name)))
107218 + return false;
107219 + strcpy(ids[0].name, name);
107220 + if (WARN_ON(strlen(compatible) >= sizeof(ids[0].compatible)))
107221 + return false;
107222 + strcpy(ids[0].compatible, compatible);
107223 + for_each_child_of_node(fm_node, dev_node)
107224 + if (of_match_node(ids, dev_node) != NULL)
107225 + ret = true;
107226 + return ret;
107227 +}
107228 +
107229 +static t_LnxWrpFmDev * ReadFmDevTreeNode (struct platform_device *of_dev)
107230 +{
107231 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107232 + struct device_node *fm_node, *dev_node;
107233 + struct of_device_id ids[OF_DEV_ID_NUM];
107234 + struct resource res;
107235 + struct clk *clk;
107236 + u32 clk_rate;
107237 + const uint32_t *uint32_prop;
107238 + int _errno=0, lenp;
107239 + uint32_t tmp_prop;
107240 +
107241 + fm_node = of_node_get(of_dev->dev.of_node);
107242 +
107243 + uint32_prop = (uint32_t *)of_get_property(fm_node, "cell-index", &lenp);
107244 + if (unlikely(uint32_prop == NULL)) {
107245 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_get_property(%s, cell-index) failed", fm_node->full_name));
107246 + return NULL;
107247 + }
107248 + tmp_prop = be32_to_cpu(*uint32_prop);
107249 +
107250 + if (WARN_ON(lenp != sizeof(uint32_t)))
107251 + return NULL;
107252 +
107253 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
107254 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
107255 + return NULL;
107256 + }
107257 + p_LnxWrpFmDev = CreateFmDev(tmp_prop);
107258 + if (!p_LnxWrpFmDev) {
107259 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
107260 + return NULL;
107261 + }
107262 + p_LnxWrpFmDev->dev = &of_dev->dev;
107263 + p_LnxWrpFmDev->id = tmp_prop;
107264 +
107265 + /* Get the FM interrupt */
107266 + p_LnxWrpFmDev->irq = of_irq_to_resource(fm_node, 0, NULL);
107267 + if (unlikely(p_LnxWrpFmDev->irq == /*NO_IRQ*/0)) {
107268 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107269 + DestroyFmDev(p_LnxWrpFmDev);
107270 + return NULL;
107271 + }
107272 +
107273 + /* Get the FM error interrupt */
107274 + p_LnxWrpFmDev->err_irq = of_irq_to_resource(fm_node, 1, NULL);
107275 +
107276 + if (unlikely(p_LnxWrpFmDev->err_irq == /*NO_IRQ*/0)) {
107277 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107278 + DestroyFmDev(p_LnxWrpFmDev);
107279 + return NULL;
107280 + }
107281 +
107282 + /* Get the FM address */
107283 + _errno = of_address_to_resource(fm_node, 0, &res);
107284 + if (unlikely(_errno < 0)) {
107285 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107286 + DestroyFmDev(p_LnxWrpFmDev);
107287 + return NULL;
107288 + }
107289 +
107290 +
107291 + p_LnxWrpFmDev->fmBaseAddr = 0;
107292 + p_LnxWrpFmDev->fmPhysBaseAddr = res.start;
107293 + p_LnxWrpFmDev->fmMemSize = res.end + 1 - res.start;
107294 +
107295 + clk = of_clk_get(fm_node, 0);
107296 + if (IS_ERR(clk)) {
107297 + dev_err(&of_dev->dev, "%s: Failed to get FM clock structure\n",
107298 + __func__);
107299 + of_node_put(fm_node);
107300 + DestroyFmDev(p_LnxWrpFmDev);
107301 + return NULL;
107302 + }
107303 +
107304 + clk_rate = clk_get_rate(clk);
107305 + if (!clk_rate) {
107306 + dev_err(&of_dev->dev, "%s: Failed to determine FM clock rate\n",
107307 + __func__);
107308 + of_node_put(fm_node);
107309 + DestroyFmDev(p_LnxWrpFmDev);
107310 + return NULL;
107311 + }
107312 +
107313 + p_LnxWrpFmDev->fmDevSettings.param.fmClkFreq = DIV_ROUND_UP(clk_rate, 1000000); /* In MHz, rounded */
107314 + /* Get the MURAM base address and size */
107315 + memset(ids, 0, sizeof(ids));
107316 + if (WARN_ON(strlen("muram") >= sizeof(ids[0].name)))
107317 + return NULL;
107318 + strcpy(ids[0].name, "muram");
107319 + if (WARN_ON(strlen("fsl,fman-muram") >= sizeof(ids[0].compatible)))
107320 + return NULL;
107321 + strcpy(ids[0].compatible, "fsl,fman-muram");
107322 + for_each_child_of_node(fm_node, dev_node) {
107323 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107324 + _errno = of_address_to_resource(dev_node, 0, &res);
107325 + if (unlikely(_errno < 0)) {
107326 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107327 + DestroyFmDev(p_LnxWrpFmDev);
107328 + return NULL;
107329 + }
107330 +
107331 + p_LnxWrpFmDev->fmMuramBaseAddr = 0;
107332 + p_LnxWrpFmDev->fmMuramPhysBaseAddr = res.start;
107333 + p_LnxWrpFmDev->fmMuramMemSize = res.end + 1 - res.start;
107334 +
107335 +#ifndef CONFIG_FMAN_ARM
107336 + {
107337 + uint32_t svr;
107338 + svr = mfspr(SPRN_SVR);
107339 +
107340 + if ((svr & ~SVR_VER_IGNORE_MASK) >= SVR_B4860_REV2_VALUE)
107341 + p_LnxWrpFmDev->fmMuramMemSize = 0x80000;
107342 + }
107343 +#endif
107344 + }
107345 + }
107346 +
107347 + /* Get the RTC base address and size */
107348 + memset(ids, 0, sizeof(ids));
107349 + if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name)))
107350 + return NULL;
107351 + strcpy(ids[0].name, "ptp-timer");
107352 + if (WARN_ON(strlen("fsl,fman-rtc") >= sizeof(ids[0].compatible)))
107353 + return NULL;
107354 + strcpy(ids[0].compatible, "fsl,fman-rtc");
107355 + for_each_child_of_node(fm_node, dev_node) {
107356 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107357 + _errno = of_address_to_resource(dev_node, 0, &res);
107358 + if (unlikely(_errno < 0)) {
107359 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107360 + DestroyFmDev(p_LnxWrpFmDev);
107361 + return NULL;
107362 + }
107363 +
107364 + p_LnxWrpFmDev->fmRtcBaseAddr = 0;
107365 + p_LnxWrpFmDev->fmRtcPhysBaseAddr = res.start;
107366 + p_LnxWrpFmDev->fmRtcMemSize = res.end + 1 - res.start;
107367 + }
107368 + }
107369 +
107370 +#if (DPAA_VERSION >= 11)
107371 + /* Get the VSP base address */
107372 + for_each_child_of_node(fm_node, dev_node) {
107373 + if (of_device_is_compatible(dev_node, "fsl,fman-vsps")) {
107374 + _errno = of_address_to_resource(dev_node, 0, &res);
107375 + if (unlikely(_errno < 0)) {
107376 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107377 + DestroyFmDev(p_LnxWrpFmDev);
107378 + return NULL;
107379 + }
107380 + p_LnxWrpFmDev->fmVspBaseAddr = 0;
107381 + p_LnxWrpFmDev->fmVspPhysBaseAddr = res.start;
107382 + p_LnxWrpFmDev->fmVspMemSize = res.end + 1 - res.start;
107383 + }
107384 + }
107385 +#endif
107386 +
107387 + /* Get all PCD nodes */
107388 + p_LnxWrpFmDev->prsActive = HasFmPcdOfNode(fm_node, ids, "parser", "fsl,fman-parser");
107389 + p_LnxWrpFmDev->kgActive = HasFmPcdOfNode(fm_node, ids, "keygen", "fsl,fman-keygen");
107390 + p_LnxWrpFmDev->ccActive = HasFmPcdOfNode(fm_node, ids, "cc", "fsl,fman-cc");
107391 + p_LnxWrpFmDev->plcrActive = HasFmPcdOfNode(fm_node, ids, "policer", "fsl,fman-policer");
107392 +
107393 + if (p_LnxWrpFmDev->prsActive || p_LnxWrpFmDev->kgActive ||
107394 + p_LnxWrpFmDev->ccActive || p_LnxWrpFmDev->plcrActive)
107395 + p_LnxWrpFmDev->pcdActive = TRUE;
107396 +
107397 + if (p_LnxWrpFmDev->pcdActive)
107398 + {
107399 + const char *str_prop = (char *)of_get_property(fm_node, "fsl,default-pcd", &lenp);
107400 + if (str_prop) {
107401 + if (strncmp(str_prop, "3-tuple", strlen("3-tuple")) == 0)
107402 + p_LnxWrpFmDev->defPcd = e_FM_PCD_3_TUPLE;
107403 + }
107404 + else
107405 + p_LnxWrpFmDev->defPcd = e_NO_PCD;
107406 + }
107407 +
107408 + of_node_put(fm_node);
107409 +
107410 + p_LnxWrpFmDev->hcCh =
107411 + qman_affine_channel(cpumask_first(qman_affine_cpus()));
107412 +
107413 + p_LnxWrpFmDev->active = TRUE;
107414 +
107415 + return p_LnxWrpFmDev;
107416 +}
107417 +
107418 +struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx)
107419 +{
107420 + struct device_node *dev_node;
107421 + const uint32_t *uint32_prop;
107422 + int lenp;
107423 + uint32_t tmp_prop;
107424 +
107425 + for_each_compatible_node(dev_node, NULL, "fsl,fman-extended-args") {
107426 + uint32_prop = (uint32_t *)of_get_property(dev_node, "cell-index", &lenp);
107427 + if (unlikely(uint32_prop == NULL)) {
107428 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
107429 + ("of_get_property(%s, cell-index) failed",
107430 + dev_node->full_name));
107431 + return NULL;
107432 + }
107433 + tmp_prop = be32_to_cpu(*uint32_prop);
107434 + if (WARN_ON(lenp != sizeof(uint32_t)))
107435 + return NULL;
107436 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
107437 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
107438 + return NULL;
107439 + }
107440 + if (fmIndx == tmp_prop)
107441 + return dev_node;
107442 + }
107443 +
107444 + return NULL;
107445 +}
107446 +
107447 +static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev)
107448 +{
107449 + struct device_node *dev_node;
107450 + t_Error err = E_INVALID_VALUE;
107451 + const uint32_t *uint32_prop;
107452 + const char *str_prop;
107453 + int lenp;
107454 + uint32_t tmp_prop;
107455 +
107456 + dev_node = GetFmAdvArgsDevTreeNode(p_LnxWrpFmDev->id);
107457 + if (!dev_node) /* no advance parameters for FMan */
107458 + return E_OK;
107459 +
107460 + str_prop = (char *)of_get_property(dev_node, "dma-aid-mode", &lenp);
107461 + if (str_prop) {
107462 + if (strcmp(str_prop, "port") == 0)
107463 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_PORT_ID);
107464 + else if (strcmp(str_prop, "tnum") == 0)
107465 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_TNUM);
107466 +
107467 + if (err != E_OK)
107468 + RETURN_ERROR(MINOR, err, NO_MSG);
107469 + }
107470 +
107471 + uint32_prop = (uint32_t *)of_get_property(dev_node,
107472 + "total-fifo-size", &lenp);
107473 + if (uint32_prop) {
107474 + tmp_prop = be32_to_cpu(*uint32_prop);
107475 + if (WARN_ON(lenp != sizeof(uint32_t)))
107476 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107477 +
107478 + if (FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev,
107479 + tmp_prop) != E_OK)
107480 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107481 + }
107482 +
107483 + uint32_prop = (uint32_t *)of_get_property(dev_node, "tnum-aging-period",
107484 + &lenp);
107485 + if (uint32_prop) {
107486 + tmp_prop = be32_to_cpu(*uint32_prop);
107487 + if (WARN_ON(lenp != sizeof(uint32_t)))
107488 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107489 +
107490 + err = FM_ConfigTnumAgingPeriod(p_LnxWrpFmDev->h_Dev,
107491 + (uint16_t)tmp_prop/*tnumAgingPeriod*/);
107492 +
107493 + if (err != E_OK)
107494 + RETURN_ERROR(MINOR, err, NO_MSG);
107495 + }
107496 +
107497 + of_node_put(dev_node);
107498 +
107499 + return E_OK;
107500 +}
107501 +
107502 +static void LnxwrpFmDevExceptionsCb(t_Handle h_App, e_FmExceptions exception)
107503 +{
107504 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
107505 +
107506 + ASSERT_COND(p_LnxWrpFmDev);
107507 +
107508 + DBG(INFO, ("got fm exception %d", exception));
107509 +
107510 + /* do nothing */
107511 + UNUSED(exception);
107512 +}
107513 +
107514 +static void LnxwrpFmDevBusErrorCb(t_Handle h_App,
107515 + e_FmPortType portType,
107516 + uint8_t portId,
107517 + uint64_t addr,
107518 + uint8_t tnum,
107519 + uint16_t liodn)
107520 +{
107521 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
107522 +
107523 + ASSERT_COND(p_LnxWrpFmDev);
107524 +
107525 + /* do nothing */
107526 + UNUSED(portType);UNUSED(portId);UNUSED(addr);UNUSED(tnum);UNUSED(liodn);
107527 +}
107528 +
107529 +static t_Error ConfigureFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107530 +{
107531 + struct resource *dev_res;
107532 + int _errno;
107533 +
107534 + if (!p_LnxWrpFmDev->active)
107535 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
107536 +
107537 +#ifndef MODULE
107538 + _errno = can_request_irq(p_LnxWrpFmDev->irq, 0);
107539 + if (unlikely(_errno < 0))
107540 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
107541 +#endif
107542 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, 0, "fman", p_LnxWrpFmDev);
107543 + if (unlikely(_errno < 0))
107544 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->irq, _errno));
107545 +
107546 + enable_irq_wake(p_LnxWrpFmDev->irq);
107547 +
107548 + if (p_LnxWrpFmDev->err_irq != 0) {
107549 +#ifndef MODULE
107550 + _errno = can_request_irq(p_LnxWrpFmDev->err_irq, 0);
107551 + if (unlikely(_errno < 0))
107552 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
107553 +#endif
107554 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, fm_err_irq, IRQF_SHARED, "fman-err", p_LnxWrpFmDev);
107555 + if (unlikely(_errno < 0))
107556 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->err_irq, _errno));
107557 +
107558 + enable_irq_wake(p_LnxWrpFmDev->err_irq);
107559 + }
107560 +
107561 + p_LnxWrpFmDev->res = devm_request_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize, "fman");
107562 + if (unlikely(p_LnxWrpFmDev->res == NULL))
107563 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_mem_region() failed"));
107564 +
107565 + p_LnxWrpFmDev->fmBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize));
107566 + if (unlikely(p_LnxWrpFmDev->fmBaseAddr == 0))
107567 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107568 +
107569 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmBaseAddr, (uint64_t)p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize) != E_OK)
107570 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM memory map"));
107571 +
107572 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize, "fman-muram");
107573 + if (unlikely(dev_res == NULL))
107574 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107575 +
107576 + p_LnxWrpFmDev->fmMuramBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize));
107577 + if (unlikely(p_LnxWrpFmDev->fmMuramBaseAddr == 0))
107578 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107579 +
107580 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmMuramBaseAddr, (uint64_t)p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize) != E_OK)
107581 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM MURAM memory map"));
107582 +
107583 + if (p_LnxWrpFmDev->fmRtcPhysBaseAddr)
107584 + {
107585 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-rtc");
107586 + if (unlikely(dev_res == NULL))
107587 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107588 +
107589 + p_LnxWrpFmDev->fmRtcBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize));
107590 + if (unlikely(p_LnxWrpFmDev->fmRtcBaseAddr == 0))
107591 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107592 +
107593 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmRtcBaseAddr, (uint64_t)p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize) != E_OK)
107594 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC memory map"));
107595 + }
107596 +
107597 +#if (DPAA_VERSION >= 11)
107598 + if (p_LnxWrpFmDev->fmVspPhysBaseAddr) {
107599 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize, "fman-vsp");
107600 + if (unlikely(dev_res == NULL))
107601 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107602 +
107603 + p_LnxWrpFmDev->fmVspBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize));
107604 + if (unlikely(p_LnxWrpFmDev->fmVspBaseAddr == 0))
107605 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107606 + }
107607 +#endif
107608 +
107609 + p_LnxWrpFmDev->fmDevSettings.param.baseAddr = p_LnxWrpFmDev->fmBaseAddr;
107610 + p_LnxWrpFmDev->fmDevSettings.param.fmId = p_LnxWrpFmDev->id;
107611 + p_LnxWrpFmDev->fmDevSettings.param.irq = NO_IRQ;
107612 + p_LnxWrpFmDev->fmDevSettings.param.errIrq = NO_IRQ;
107613 + p_LnxWrpFmDev->fmDevSettings.param.f_Exception = LnxwrpFmDevExceptionsCb;
107614 + p_LnxWrpFmDev->fmDevSettings.param.f_BusError = LnxwrpFmDevBusErrorCb;
107615 + p_LnxWrpFmDev->fmDevSettings.param.h_App = p_LnxWrpFmDev;
107616 +
107617 + return FillRestFmInfo(p_LnxWrpFmDev);
107618 +}
107619 +
107620 +#ifndef CONFIG_FMAN_ARM
107621 +/*
107622 + * Table for matching compatible strings, for device tree
107623 + * guts node, for QorIQ SOCs.
107624 + * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4
107625 + * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0"
107626 + * string would be used.
107627 +*/
107628 +static const struct of_device_id guts_device_ids[] = {
107629 + { .compatible = "fsl,qoriq-device-config-1.0", },
107630 + { .compatible = "fsl,qoriq-device-config-2.0", },
107631 + {}
107632 +};
107633 +
107634 +static unsigned int get_rcwsr(int regnum)
107635 +{
107636 + struct ccsr_guts __iomem *guts_regs = NULL;
107637 + struct device_node *guts_node;
107638 +
107639 + guts_node = of_find_matching_node(NULL, guts_device_ids);
107640 + if (!guts_node) {
107641 + pr_err("could not find GUTS node\n");
107642 + return 0;
107643 + }
107644 + guts_regs = of_iomap(guts_node, 0);
107645 + of_node_put(guts_node);
107646 + if (!guts_regs) {
107647 + pr_err("ioremap of GUTS node failed\n");
107648 + return 0;
107649 + }
107650 +
107651 + return ioread32be(&guts_regs->rcwsr[regnum]);
107652 +}
107653 +
107654 +#define FMAN1_ALL_MACS_MASK 0xFCC00000
107655 +#define FMAN2_ALL_MACS_MASK 0x000FCC00
107656 +
107657 +/**
107658 + * @Function ResetOnInitErrata_A007273
107659 + *
107660 + * @Description Workaround for Errata A-007273
107661 + * This workaround is required to avoid a FMan hang during reset on initialization.
107662 + * Enable all MACs in guts.devdisr2 register,
107663 + * then perform a regular FMan reset and then restore MACs to their original state.
107664 + *
107665 + * @Param[in] h_Fm - FM module descriptor
107666 + *
107667 + * @Return None.
107668 + */
107669 +void ResetOnInitErrata_A007273(t_Handle h_Fm)
107670 +{
107671 + struct ccsr_guts __iomem *guts_regs = NULL;
107672 + struct device_node *guts_node;
107673 + u32 devdisr2, enableMacs;
107674 +
107675 + /* Get guts registers */
107676 + guts_node = of_find_matching_node(NULL, guts_device_ids);
107677 + if (!guts_node) {
107678 + pr_err("could not find GUTS node\n");
107679 + return;
107680 + }
107681 + guts_regs = of_iomap(guts_node, 0);
107682 + of_node_put(guts_node);
107683 + if (!guts_regs) {
107684 + pr_err("ioremap of GUTS node failed\n");
107685 + return;
107686 + }
107687 +
107688 + /* Read current state */
107689 + devdisr2 = ioread32be(&guts_regs->devdisr2);
107690 +
107691 + if (FmGetId(h_Fm) == 0)
107692 + enableMacs = devdisr2 & ~FMAN1_ALL_MACS_MASK;
107693 + else
107694 + enableMacs = devdisr2 & ~FMAN2_ALL_MACS_MASK;
107695 +
107696 + /* Enable all MACs */
107697 + iowrite32be(enableMacs, &guts_regs->devdisr2);
107698 +
107699 + /* Perform standard FMan reset */
107700 + FmReset(h_Fm);
107701 +
107702 + /* Restore devdisr2 value */
107703 + iowrite32be(devdisr2, &guts_regs->devdisr2);
107704 +
107705 + iounmap(guts_regs);
107706 +}
107707 +#endif
107708 +
107709 +static t_Error InitFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107710 +{
107711 + const struct qe_firmware *fw;
107712 +
107713 + if (!p_LnxWrpFmDev->active)
107714 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
107715 +
107716 + if ((p_LnxWrpFmDev->h_MuramDev = FM_MURAM_ConfigAndInit(p_LnxWrpFmDev->fmMuramBaseAddr, p_LnxWrpFmDev->fmMuramMemSize)) == NULL)
107717 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM!"));
107718 +
107719 + /* Loading the fman-controller code */
107720 + fw = FindFmanMicrocode();
107721 +
107722 + if (!fw) {
107723 + /* this forces the reuse of the current IRAM content */
107724 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size = 0;
107725 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = NULL;
107726 + } else {
107727 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code =
107728 + (void *) fw + be32_to_cpu(fw->microcode[0].code_offset);
107729 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size =
107730 + sizeof(u32) * be32_to_cpu(fw->microcode[0].count);
107731 + DBG(INFO, ("Loading fman-controller code version %d.%d.%d",
107732 + fw->microcode[0].major,
107733 + fw->microcode[0].minor,
107734 + fw->microcode[0].revision));
107735 + }
107736 +
107737 +#ifdef CONFIG_FMAN_ARM
107738 + { /* endianness adjustments: byteswap the ucode retrieved from the f/w blob */
107739 + int i;
107740 + int usz = p_LnxWrpFmDev->fmDevSettings.param.firmware.size;
107741 + void * p_Code = p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code;
107742 + u32 *dest = kzalloc(usz, GFP_KERNEL);
107743 +
107744 + if (p_Code && dest)
107745 + for(i=0; i < usz / 4; ++i)
107746 + dest[i] = be32_to_cpu(((u32 *)p_Code)[i]);
107747 +
107748 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = dest;
107749 + }
107750 +#endif
107751 +
107752 + p_LnxWrpFmDev->fmDevSettings.param.h_FmMuram = p_LnxWrpFmDev->h_MuramDev;
107753 +
107754 +#if (DPAA_VERSION >= 11)
107755 + if (p_LnxWrpFmDev->fmVspBaseAddr) {
107756 + p_LnxWrpFmDev->fmDevSettings.param.vspBaseAddr = p_LnxWrpFmDev->fmVspBaseAddr;
107757 + p_LnxWrpFmDev->fmDevSettings.param.partVSPBase = 0;
107758 + p_LnxWrpFmDev->fmDevSettings.param.partNumOfVSPs = FM_VSP_MAX_NUM_OF_ENTRIES;
107759 + }
107760 +#endif
107761 +
107762 +#ifdef CONFIG_FMAN_ARM
107763 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
107764 +#else
107765 + if(p_LnxWrpFmDev->fmDevSettings.param.fmId == 0)
107766 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
107767 + !!(get_rcwsr(4) & 0x2); /* RCW[FM_MAC_RAT0] */
107768 + else
107769 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
107770 + !!(get_rcwsr(4) & 0x1); /* RCW[FM_MAC_RAT1] */
107771 +
107772 + {
107773 + /* T4 Devices ClkRatio is always 1 regardless of RCW[FM_MAC_RAT1] */
107774 + uint32_t svr;
107775 + svr = mfspr(SPRN_SVR);
107776 +
107777 + if ((svr & SVR_DEVICE_ID_MASK) == SVR_T4_DEVICE_ID)
107778 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
107779 + }
107780 +#endif /* CONFIG_FMAN_ARM */
107781 +
107782 + if ((p_LnxWrpFmDev->h_Dev = FM_Config(&p_LnxWrpFmDev->fmDevSettings.param)) == NULL)
107783 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM"));
107784 +
107785 +
107786 + if (FM_ConfigResetOnInit(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
107787 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107788 +
107789 +#ifndef CONFIG_FMAN_ARM
107790 +#ifdef FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
107791 + if (FM_ConfigResetOnInitOverrideCallback(p_LnxWrpFmDev->h_Dev, ResetOnInitErrata_A007273) != E_OK)
107792 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107793 +#endif /* FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 */
107794 +#endif /* CONFIG_FMAN_ARM */
107795 +
107796 +#ifdef CONFIG_FMAN_P1023
107797 + if (FM_ConfigDmaAidOverride(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
107798 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107799 +#endif
107800 +
107801 +
107802 + CheckNConfigFmAdvArgs(p_LnxWrpFmDev);
107803 +
107804 + if (FM_Init(p_LnxWrpFmDev->h_Dev) != E_OK)
107805 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107806 +
107807 + /* TODO: Why we mask these interrupts? */
107808 + if (p_LnxWrpFmDev->err_irq == 0) {
107809 + FM_SetException(p_LnxWrpFmDev->h_Dev, e_FM_EX_DMA_BUS_ERROR,FALSE);
107810 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_READ_ECC,FALSE);
107811 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SYSTEM_WRITE_ECC,FALSE);
107812 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_FM_WRITE_ECC,FALSE);
107813 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SINGLE_PORT_ECC, FALSE);
107814 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_STALL_ON_TASKS , FALSE);
107815 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_SINGLE_ECC, FALSE);
107816 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_DOUBLE_ECC,FALSE);
107817 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_SINGLE_ECC, FALSE);
107818 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DOUBLE_ECC,FALSE);
107819 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,FALSE);
107820 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_LIST_RAM_ECC,FALSE);
107821 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STORAGE_PROFILE_ECC, FALSE);
107822 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STATISTICS_RAM_ECC, FALSE);
107823 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_DISPATCH_RAM_ECC, FALSE);
107824 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_IRAM_ECC,FALSE);
107825 + /* TODO: FmDisableRamsEcc assert for ramsEccOwners.
107826 + * FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_MURAM_ECC,FALSE);*/
107827 + }
107828 +
107829 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
107830 + {
107831 + t_FmRtcParams fmRtcParam;
107832 +
107833 + memset(&fmRtcParam, 0, sizeof(fmRtcParam));
107834 + fmRtcParam.h_App = p_LnxWrpFmDev;
107835 + fmRtcParam.h_Fm = p_LnxWrpFmDev->h_Dev;
107836 + fmRtcParam.baseAddress = p_LnxWrpFmDev->fmRtcBaseAddr;
107837 +
107838 + if(!(p_LnxWrpFmDev->h_RtcDev = FM_RTC_Config(&fmRtcParam)))
107839 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-RTC"));
107840 +
107841 + if (FM_RTC_ConfigPeriod(p_LnxWrpFmDev->h_RtcDev, DPA_PTP_NOMINAL_FREQ_PERIOD_NS) != E_OK)
107842 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
107843 +
107844 + if (FM_RTC_Init(p_LnxWrpFmDev->h_RtcDev) != E_OK)
107845 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
107846 + }
107847 +
107848 + return E_OK;
107849 +}
107850 +
107851 +/* TODO: to be moved back here */
107852 +extern void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev);
107853 +
107854 +static void FreeFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107855 +{
107856 + if (!p_LnxWrpFmDev->active)
107857 + return;
107858 +
107859 + FreeFmPcdDev(p_LnxWrpFmDev);
107860 +
107861 + if (p_LnxWrpFmDev->h_RtcDev)
107862 + FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev);
107863 +
107864 + if (p_LnxWrpFmDev->h_Dev)
107865 + FM_Free(p_LnxWrpFmDev->h_Dev);
107866 +
107867 + if (p_LnxWrpFmDev->h_MuramDev)
107868 + FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev);
107869 +
107870 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
107871 + {
107872 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmRtcBaseAddr);
107873 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmRtcBaseAddr));
107874 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize);
107875 + }
107876 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmMuramBaseAddr);
107877 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmMuramBaseAddr));
107878 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize);
107879 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmBaseAddr);
107880 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr));
107881 + devm_release_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize);
107882 + if (p_LnxWrpFmDev->err_irq != 0) {
107883 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, p_LnxWrpFmDev);
107884 + }
107885 +
107886 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, p_LnxWrpFmDev);
107887 +}
107888 +
107889 +/* FMan character device file operations */
107890 +extern struct file_operations fm_fops;
107891 +
107892 +static int /*__devinit*/ fm_probe(struct platform_device *of_dev)
107893 +{
107894 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107895 +
107896 + if ((p_LnxWrpFmDev = ReadFmDevTreeNode(of_dev)) == NULL)
107897 + return -EIO;
107898 + if (ConfigureFmDev(p_LnxWrpFmDev) != E_OK)
107899 + return -EIO;
107900 + if (InitFmDev(p_LnxWrpFmDev) != E_OK)
107901 + return -EIO;
107902 +
107903 + /* IOCTL ABI checking */
107904 + LnxWrpPCDIOCTLEnumChecking();
107905 + LnxWrpPCDIOCTLTypeChecking();
107906 +
107907 + Sprint (p_LnxWrpFmDev->name, "%s%d", DEV_FM_NAME, p_LnxWrpFmDev->id);
107908 +
107909 + /* Register to the /dev for IOCTL API */
107910 + /* Register dynamically a new major number for the character device: */
107911 + if ((p_LnxWrpFmDev->major = register_chrdev(0, p_LnxWrpFmDev->name, &fm_fops)) <= 0) {
107912 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Failed to allocate a major number for device \"%s\"", p_LnxWrpFmDev->name));
107913 + return -EIO;
107914 + }
107915 +
107916 + /* Creating classes for FM */
107917 + DBG(TRACE ,("class_create fm_class"));
107918 + p_LnxWrpFmDev->fm_class = class_create(THIS_MODULE, p_LnxWrpFmDev->name);
107919 + if (IS_ERR(p_LnxWrpFmDev->fm_class)) {
107920 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
107921 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("class_create error fm_class"));
107922 + return -EIO;
107923 + }
107924 +
107925 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE), NULL,
107926 + "fm%d", p_LnxWrpFmDev->id);
107927 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE), NULL,
107928 + "fm%d-pcd", p_LnxWrpFmDev->id);
107929 + dev_set_drvdata(p_LnxWrpFmDev->dev, p_LnxWrpFmDev);
107930 +
107931 + /* create sysfs entries for stats and regs */
107932 + if ( fm_sysfs_create(p_LnxWrpFmDev->dev) !=0 )
107933 + {
107934 + FreeFmDev(p_LnxWrpFmDev);
107935 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unable to create sysfs entry - fm!!!"));
107936 + return -EIO;
107937 + }
107938 +
107939 +#ifdef CONFIG_PM
107940 + device_set_wakeup_capable(p_LnxWrpFmDev->dev, true);
107941 +#endif
107942 +
107943 + DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id));
107944 +
107945 + return 0;
107946 +}
107947 +
107948 +static int fm_remove(struct platform_device *of_dev)
107949 +{
107950 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107951 + struct device *dev;
107952 +
107953 + dev = &of_dev->dev;
107954 + p_LnxWrpFmDev = dev_get_drvdata(dev);
107955 +
107956 + fm_sysfs_destroy(dev);
107957 +
107958 + DBG(TRACE, ("destroy fm_class"));
107959 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE));
107960 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE));
107961 + class_destroy(p_LnxWrpFmDev->fm_class);
107962 +
107963 + /* Destroy chardev */
107964 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
107965 +
107966 + FreeFmDev(p_LnxWrpFmDev);
107967 +
107968 + DestroyFmDev(p_LnxWrpFmDev);
107969 +
107970 + dev_set_drvdata(dev, NULL);
107971 +
107972 + return 0;
107973 +}
107974 +
107975 +static const struct of_device_id fm_match[] = {
107976 + {
107977 + .compatible = "fsl,fman"
107978 + },
107979 + {}
107980 +};
107981 +#ifndef MODULE
107982 +MODULE_DEVICE_TABLE(of, fm_match);
107983 +#endif /* !MODULE */
107984 +
107985 +#ifdef CONFIG_PM
107986 +
107987 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
107988 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000
107989 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
107990 +
107991 +struct device *g_fm_dev;
107992 +
107993 +static int fm_soc_suspend(struct device *dev)
107994 +{
107995 + int err = 0;
107996 + uint32_t *fmclk;
107997 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
107998 + g_fm_dev = dev;
107999 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
108000 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
108001 + if (p_LnxWrpFmDev->h_DsarRxPort)
108002 + {
108003 +#ifdef CONFIG_FSL_QORIQ_PM
108004 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 1);
108005 +#endif
108006 + err = FM_PORT_EnterDsarFinal(p_LnxWrpFmDev->h_DsarRxPort,
108007 + p_LnxWrpFmDev->h_DsarTxPort);
108008 + }
108009 + return err;
108010 +}
108011 +
108012 +static int fm_soc_resume(struct device *dev)
108013 +{
108014 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
108015 + uint32_t *fmclk;
108016 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
108017 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
108018 + if (p_LnxWrpFmDev->h_DsarRxPort)
108019 + {
108020 +#ifdef CONFIG_FSL_QORIQ_PM
108021 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 0);
108022 +#endif
108023 + FM_PORT_ExitDsar(p_LnxWrpFmDev->h_DsarRxPort,
108024 + p_LnxWrpFmDev->h_DsarTxPort);
108025 + p_LnxWrpFmDev->h_DsarRxPort = 0;
108026 + p_LnxWrpFmDev->h_DsarTxPort = 0;
108027 + }
108028 + return 0;
108029 +}
108030 +
108031 +static const struct dev_pm_ops fm_pm_ops = {
108032 + .suspend = fm_soc_suspend,
108033 + .resume = fm_soc_resume,
108034 +};
108035 +
108036 +#define FM_PM_OPS (&fm_pm_ops)
108037 +
108038 +#else /* CONFIG_PM */
108039 +
108040 +#define FM_PM_OPS NULL
108041 +
108042 +#endif /* CONFIG_PM */
108043 +
108044 +static struct platform_driver fm_driver = {
108045 + .driver = {
108046 + .name = "fsl-fman",
108047 + .of_match_table = fm_match,
108048 + .owner = THIS_MODULE,
108049 + .pm = FM_PM_OPS,
108050 + },
108051 + .probe = fm_probe,
108052 + .remove = fm_remove
108053 +};
108054 +
108055 +t_Handle LNXWRP_FM_Init(void)
108056 +{
108057 + memset(&lnxWrpFm, 0, sizeof(lnxWrpFm));
108058 + mutex_init(&lnxwrp_mutex);
108059 +
108060 + /* Register to the DTB for basic FM API */
108061 + platform_driver_register(&fm_driver);
108062 +
108063 + return &lnxWrpFm;
108064 +}
108065 +
108066 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm)
108067 +{
108068 + platform_driver_unregister(&fm_driver);
108069 + mutex_destroy(&lnxwrp_mutex);
108070 +
108071 + return E_OK;
108072 +}
108073 +
108074 +
108075 +struct fm * fm_bind(struct device *fm_dev)
108076 +{
108077 + return (struct fm *)(dev_get_drvdata(get_device(fm_dev)));
108078 +}
108079 +EXPORT_SYMBOL(fm_bind);
108080 +
108081 +void fm_unbind(struct fm *fm)
108082 +{
108083 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108084 +
108085 + put_device(p_LnxWrpFmDev->dev);
108086 +}
108087 +EXPORT_SYMBOL(fm_unbind);
108088 +
108089 +struct resource * fm_get_mem_region(struct fm *fm)
108090 +{
108091 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108092 +
108093 + return p_LnxWrpFmDev->res;
108094 +}
108095 +EXPORT_SYMBOL(fm_get_mem_region);
108096 +
108097 +void * fm_get_handle(struct fm *fm)
108098 +{
108099 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108100 +
108101 + return (void *)p_LnxWrpFmDev->h_Dev;
108102 +}
108103 +EXPORT_SYMBOL(fm_get_handle);
108104 +
108105 +void * fm_get_rtc_handle(struct fm *fm)
108106 +{
108107 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108108 +
108109 + return (void *)p_LnxWrpFmDev->h_RtcDev;
108110 +}
108111 +EXPORT_SYMBOL(fm_get_rtc_handle);
108112 +
108113 +struct fm_port * fm_port_bind (struct device *fm_port_dev)
108114 +{
108115 + return (struct fm_port *)(dev_get_drvdata(get_device(fm_port_dev)));
108116 +}
108117 +EXPORT_SYMBOL(fm_port_bind);
108118 +
108119 +void fm_port_unbind(struct fm_port *port)
108120 +{
108121 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108122 +
108123 + put_device(p_LnxWrpFmPortDev->dev);
108124 +}
108125 +EXPORT_SYMBOL(fm_port_unbind);
108126 +
108127 +void *fm_port_get_handle(const struct fm_port *port)
108128 +{
108129 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108130 +
108131 + return (void *)p_LnxWrpFmPortDev->h_Dev;
108132 +}
108133 +EXPORT_SYMBOL(fm_port_get_handle);
108134 +
108135 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
108136 + const void *data)
108137 +{
108138 + return FM_PORT_GetBufferTimeStamp(fm_port_get_handle(port),
108139 + (void *)data);
108140 +}
108141 +EXPORT_SYMBOL(fm_port_get_buffer_time_stamp);
108142 +
108143 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr)
108144 +{
108145 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108146 +
108147 + *base_addr = p_LnxWrpFmPortDev->settings.param.baseAddr;
108148 +}
108149 +EXPORT_SYMBOL(fm_port_get_base_addr);
108150 +
108151 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params)
108152 +{
108153 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108154 +
108155 + p_LnxWrpFmPortDev->pcd_owner_params.cba = params->cba;
108156 + p_LnxWrpFmPortDev->pcd_owner_params.cbf = params->cbf;
108157 + p_LnxWrpFmPortDev->pcd_owner_params.dev = params->dev;
108158 +}
108159 +EXPORT_SYMBOL(fm_port_pcd_bind);
108160 +
108161 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params)
108162 +{
108163 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108164 + struct device_node *fm_node, *port_node;
108165 + const uint32_t *uint32_prop;
108166 + int lenp;
108167 +
108168 + params->data_align = 0;
108169 + params->manip_extra_space = 0;
108170 +
108171 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
108172 + if (!fm_node) /* no advance parameters for FMan */
108173 + return;
108174 +
108175 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
108176 + p_LnxWrpFmPortDev->settings.param.portType,
108177 + p_LnxWrpFmPortDev->settings.param.portId);
108178 + if (!port_node) /* no advance parameters for FMan-Port */
108179 + return;
108180 +
108181 + uint32_prop = (uint32_t *)of_get_property(port_node, "buffer-layout", &lenp);
108182 + if (uint32_prop) {
108183 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
108184 + return;
108185 +
108186 + params->manip_extra_space = (uint8_t)be32_to_cpu(uint32_prop[0]);
108187 + params->data_align = (uint16_t)be32_to_cpu(uint32_prop[1]);
108188 + }
108189 +
108190 + of_node_put(port_node);
108191 + of_node_put(fm_node);
108192 +}
108193 +EXPORT_SYMBOL(fm_port_get_buff_layout_ext_params);
108194 +
108195 +uint16_t fm_get_tx_port_channel(struct fm_port *port)
108196 +{
108197 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108198 +
108199 + return p_LnxWrpFmPortDev->txCh;
108200 +}
108201 +EXPORT_SYMBOL(fm_get_tx_port_channel);
108202 +
108203 +int fm_port_enable (struct fm_port *port)
108204 +{
108205 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108206 + t_Error err = FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108207 +
108208 + return GET_ERROR_TYPE(err);
108209 +}
108210 +EXPORT_SYMBOL(fm_port_enable);
108211 +
108212 +int fm_port_disable(struct fm_port *port)
108213 +{
108214 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108215 + t_Error err = FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108216 +
108217 + return GET_ERROR_TYPE(err);
108218 +}
108219 +EXPORT_SYMBOL(fm_port_disable);
108220 +
108221 +int fm_port_set_rate_limit(struct fm_port *port,
108222 + uint16_t max_burst_size,
108223 + uint32_t rate_limit)
108224 +{
108225 + t_FmPortRateLimit param;
108226 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108227 + int err = 0;
108228 +
108229 + param.maxBurstSize = max_burst_size;
108230 + param.rateLimit = rate_limit;
108231 + param.rateLimitDivider = 0;
108232 +
108233 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, &param);
108234 + return err;
108235 +}
108236 +EXPORT_SYMBOL(fm_port_set_rate_limit);
108237 +
108238 +int fm_port_del_rate_limit(struct fm_port *port)
108239 +{
108240 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108241 +
108242 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
108243 + return 0;
108244 +}
108245 +EXPORT_SYMBOL(fm_port_del_rate_limit);
108246 +
108247 +void FM_PORT_Dsar_DumpRegs(void);
108248 +int ar_showmem(struct file *file, const char __user *buffer,
108249 + unsigned long count, void *data)
108250 +{
108251 + FM_PORT_Dsar_DumpRegs();
108252 + return 2;
108253 +}
108254 +
108255 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
108256 + struct fm_port *port)
108257 +{
108258 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108259 + return &p_LnxWrpFmPortDev->dsar_table_sizes;
108260 +}
108261 +EXPORT_SYMBOL(fm_port_get_autores_maxsize);
108262 +
108263 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
108264 + struct auto_res_port_params *params)
108265 +{
108266 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108267 + t_LnxWrpFmDev* p_LnxWrpFmDev = (t_LnxWrpFmDev*)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
108268 + p_LnxWrpFmDev->h_DsarRxPort = p_LnxWrpFmPortDev->h_Dev;
108269 + p_LnxWrpFmDev->h_DsarTxPort = params->h_FmPortTx;
108270 +
108271 + /*Register other under /proc/autoresponse */
108272 + if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params)))
108273 + return -EFAULT;
108274 +
108275 + FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
108276 + return 0;
108277 +}
108278 +EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
108279 +
108280 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
108281 + struct fm_port *port_tx)
108282 +{
108283 +}
108284 +EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep);
108285 +
108286 +int fm_port_get_autores_stats(struct fm_port *port,
108287 + struct auto_res_port_stats *stats)
108288 +{
108289 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108290 + if (WARN_ON(sizeof(t_FmPortDsarStats) != sizeof(struct auto_res_port_stats)))
108291 + return -EFAULT;
108292 + return FM_PORT_GetDsarStats(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarStats*)stats);
108293 +}
108294 +EXPORT_SYMBOL(fm_port_get_autores_stats);
108295 +
108296 +int fm_port_suspend(struct fm_port *port)
108297 +{
108298 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108299 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108300 + return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108301 + else
108302 + return 0;
108303 +}
108304 +EXPORT_SYMBOL(fm_port_suspend);
108305 +
108306 +int fm_port_resume(struct fm_port *port)
108307 +{
108308 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108309 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108310 + return FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108311 + else
108312 + return 0;
108313 +}
108314 +EXPORT_SYMBOL(fm_port_resume);
108315 +
108316 +bool fm_port_is_in_auto_res_mode(struct fm_port *port)
108317 +{
108318 + return FM_PORT_IsInDsar(port);
108319 +}
108320 +EXPORT_SYMBOL(fm_port_is_in_auto_res_mode);
108321 +
108322 +#ifdef CONFIG_FMAN_PFC
108323 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
108324 + uint8_t prio, uint8_t wq)
108325 +{
108326 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108327 + int err;
108328 + int _errno;
108329 +
108330 + err = FM_PORT_SetPfcPrioritiesMappingToQmanWQ(p_LnxWrpFmPortDev->h_Dev,
108331 + prio, wq);
108332 + _errno = -GET_ERROR_TYPE(err);
108333 + if (unlikely(_errno < 0))
108334 + pr_err("FM_PORT_SetPfcPrioritiesMappingToQmanWQ() = 0x%08x\n", err);
108335 +
108336 + return _errno;
108337 +}
108338 +EXPORT_SYMBOL(fm_port_set_pfc_priorities_mapping_to_qman_wq);
108339 +#endif
108340 +
108341 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
108342 + e_FmMacExceptions exception, bool enable)
108343 +{
108344 + int err;
108345 + int _errno;
108346 +
108347 + err = FM_MAC_SetException(fm_mac_dev, exception, enable);
108348 +
108349 + _errno = -GET_ERROR_TYPE(err);
108350 + if (unlikely(_errno < 0))
108351 + pr_err("FM_MAC_SetException() = 0x%08x\n", err);
108352 +
108353 + return _errno;
108354 +}
108355 +EXPORT_SYMBOL(fm_mac_set_exception);
108356 +
108357 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev)
108358 +{
108359 + int err;
108360 + int _error;
108361 +
108362 + err = FM_MAC_Free(fm_mac_dev);
108363 + _error = -GET_ERROR_TYPE(err);
108364 +
108365 + if (unlikely(_error < 0))
108366 + pr_err("FM_MAC_Free() = 0x%08x\n", err);
108367 +
108368 + return _error;
108369 +}
108370 +EXPORT_SYMBOL(fm_mac_free);
108371 +
108372 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params)
108373 +{
108374 + struct fm_mac_dev *fm_mac_dev;
108375 +
108376 + fm_mac_dev = FM_MAC_Config(params);
108377 + if (unlikely(fm_mac_dev == NULL))
108378 + pr_err("FM_MAC_Config() failed\n");
108379 +
108380 + return fm_mac_dev;
108381 +}
108382 +EXPORT_SYMBOL(fm_mac_config);
108383 +
108384 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
108385 + int len)
108386 +{
108387 + int err;
108388 + int _errno;
108389 +
108390 + err = FM_MAC_ConfigMaxFrameLength(fm_mac_dev, len);
108391 + _errno = -GET_ERROR_TYPE(err);
108392 + if (unlikely(_errno < 0))
108393 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
108394 +
108395 + return _errno;
108396 +}
108397 +EXPORT_SYMBOL(fm_mac_config_max_frame_length);
108398 +
108399 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable)
108400 +{
108401 + int err;
108402 + int _errno;
108403 +
108404 + err = FM_MAC_ConfigPadAndCrc(fm_mac_dev, enable);
108405 + _errno = -GET_ERROR_TYPE(err);
108406 + if (unlikely(_errno < 0))
108407 + pr_err("FM_MAC_ConfigPadAndCrc() = 0x%08x\n", err);
108408 +
108409 + return _errno;
108410 +}
108411 +EXPORT_SYMBOL(fm_mac_config_pad_and_crc);
108412 +
108413 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable)
108414 +{
108415 + int err;
108416 + int _errno;
108417 +
108418 + err = FM_MAC_ConfigHalfDuplex(fm_mac_dev, enable);
108419 + _errno = -GET_ERROR_TYPE(err);
108420 + if (unlikely(_errno < 0))
108421 + pr_err("FM_MAC_ConfigHalfDuplex() = 0x%08x\n", err);
108422 +
108423 + return _errno;
108424 +}
108425 +EXPORT_SYMBOL(fm_mac_config_half_duplex);
108426 +
108427 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable)
108428 +{
108429 + int err;
108430 + int _errno;
108431 +
108432 + err = FM_MAC_ConfigResetOnInit(fm_mac_dev, enable);
108433 + _errno = -GET_ERROR_TYPE(err);
108434 + if (unlikely(_errno < 0))
108435 + pr_err("FM_MAC_ConfigResetOnInit() = 0x%08x\n", err);
108436 +
108437 + return _errno;
108438 +}
108439 +EXPORT_SYMBOL(fm_mac_config_reset_on_init);
108440 +
108441 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev)
108442 +{
108443 + int err;
108444 + int _errno;
108445 +
108446 + err = FM_MAC_Init(fm_mac_dev);
108447 + _errno = -GET_ERROR_TYPE(err);
108448 + if (unlikely(_errno < 0))
108449 + pr_err("FM_MAC_Init() = 0x%08x\n", err);
108450 +
108451 + return _errno;
108452 +}
108453 +EXPORT_SYMBOL(fm_mac_init);
108454 +
108455 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version)
108456 +{
108457 + int err;
108458 + int _errno;
108459 +
108460 + err = FM_MAC_GetVesrion(fm_mac_dev, version);
108461 + _errno = -GET_ERROR_TYPE(err);
108462 + if (unlikely(_errno < 0))
108463 + pr_err("FM_MAC_GetVesrion() = 0x%08x\n", err);
108464 +
108465 + return _errno;
108466 +}
108467 +EXPORT_SYMBOL(fm_mac_get_version);
108468 +
108469 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev)
108470 +{
108471 + int _errno;
108472 + t_Error err;
108473 +
108474 + err = FM_MAC_Enable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
108475 + _errno = -GET_ERROR_TYPE(err);
108476 + if (unlikely(_errno < 0))
108477 + pr_err("FM_MAC_Enable() = 0x%08x\n", err);
108478 +
108479 + return _errno;
108480 +}
108481 +EXPORT_SYMBOL(fm_mac_enable);
108482 +
108483 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev)
108484 +{
108485 + int _errno;
108486 + t_Error err;
108487 +
108488 + err = FM_MAC_Disable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
108489 + _errno = -GET_ERROR_TYPE(err);
108490 + if (unlikely(_errno < 0))
108491 + pr_err("FM_MAC_Disable() = 0x%08x\n", err);
108492 +
108493 + return _errno;
108494 +}
108495 +EXPORT_SYMBOL(fm_mac_disable);
108496 +
108497 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev)
108498 +{
108499 + int _errno;
108500 + t_Error err;
108501 +
108502 + err = FM_MAC_Resume(fm_mac_dev);
108503 + _errno = -GET_ERROR_TYPE(err);
108504 + if (unlikely(_errno < 0))
108505 + pr_err("FM_MAC_Resume() = 0x%08x\n", err);
108506 +
108507 + return _errno;
108508 +}
108509 +EXPORT_SYMBOL(fm_mac_resume);
108510 +
108511 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
108512 + bool enable)
108513 +{
108514 + int _errno;
108515 + t_Error err;
108516 +
108517 + err = FM_MAC_SetPromiscuous(fm_mac_dev, enable);
108518 + _errno = -GET_ERROR_TYPE(err);
108519 + if (unlikely(_errno < 0))
108520 + pr_err("FM_MAC_SetPromiscuous() = 0x%08x\n", err);
108521 +
108522 + return _errno;
108523 +}
108524 +EXPORT_SYMBOL(fm_mac_set_promiscuous);
108525 +
108526 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
108527 + t_EnetAddr *mac_addr)
108528 +{
108529 + int _errno;
108530 + t_Error err;
108531 +
108532 + err = FM_MAC_RemoveHashMacAddr(fm_mac_dev, mac_addr);
108533 + _errno = -GET_ERROR_TYPE(err);
108534 + if (_errno < 0) {
108535 + pr_err("FM_MAC_RemoveHashMacAddr() = 0x%08x\n", err);
108536 + return _errno;
108537 + }
108538 +
108539 + return 0;
108540 +}
108541 +EXPORT_SYMBOL(fm_mac_remove_hash_mac_addr);
108542 +
108543 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
108544 + t_EnetAddr *mac_addr)
108545 +{
108546 + int _errno;
108547 + t_Error err;
108548 +
108549 + err = FM_MAC_AddHashMacAddr(fm_mac_dev, mac_addr);
108550 + _errno = -GET_ERROR_TYPE(err);
108551 + if (_errno < 0) {
108552 + pr_err("FM_MAC_AddHashMacAddr() = 0x%08x\n", err);
108553 + return _errno;
108554 + }
108555 +
108556 + return 0;
108557 +}
108558 +EXPORT_SYMBOL(fm_mac_add_hash_mac_addr);
108559 +
108560 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
108561 + uint8_t *addr)
108562 +{
108563 + int _errno;
108564 + t_Error err;
108565 +
108566 + err = FM_MAC_ModifyMacAddr(fm_mac_dev, (t_EnetAddr *)addr);
108567 + _errno = -GET_ERROR_TYPE(err);
108568 + if (_errno < 0)
108569 + pr_err("FM_MAC_ModifyMacAddr() = 0x%08x\n", err);
108570 +
108571 + return _errno;
108572 +}
108573 +EXPORT_SYMBOL(fm_mac_modify_mac_addr);
108574 +
108575 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
108576 + bool link, int speed, bool duplex)
108577 +{
108578 + int _errno;
108579 + t_Error err;
108580 +
108581 + if (!link) {
108582 +#if (DPAA_VERSION < 11)
108583 + FM_MAC_RestartAutoneg(fm_mac_dev);
108584 +#endif
108585 + return 0;
108586 + }
108587 +
108588 + err = FM_MAC_AdjustLink(fm_mac_dev, speed, duplex);
108589 + _errno = -GET_ERROR_TYPE(err);
108590 + if (unlikely(_errno < 0))
108591 + pr_err("FM_MAC_AdjustLink() = 0x%08x\n", err);
108592 +
108593 + return _errno;
108594 +}
108595 +EXPORT_SYMBOL(fm_mac_adjust_link);
108596 +
108597 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
108598 +{
108599 + int _errno;
108600 + t_Error err;
108601 +
108602 + err = FM_MAC_Enable1588TimeStamp(fm_mac_dev);
108603 + _errno = -GET_ERROR_TYPE(err);
108604 + if (unlikely(_errno < 0))
108605 + pr_err("FM_MAC_Enable1588TimeStamp() = 0x%08x\n", err);
108606 + return _errno;
108607 +}
108608 +EXPORT_SYMBOL(fm_mac_enable_1588_time_stamp);
108609 +
108610 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
108611 +{
108612 + int _errno;
108613 + t_Error err;
108614 +
108615 + err = FM_MAC_Disable1588TimeStamp(fm_mac_dev);
108616 + _errno = -GET_ERROR_TYPE(err);
108617 + if (unlikely(_errno < 0))
108618 + pr_err("FM_MAC_Disable1588TimeStamp() = 0x%08x\n", err);
108619 + return _errno;
108620 +}
108621 +EXPORT_SYMBOL(fm_mac_disable_1588_time_stamp);
108622 +
108623 +int fm_mac_set_rx_pause_frames(
108624 + struct fm_mac_dev *fm_mac_dev, bool en)
108625 +{
108626 + int _errno;
108627 + t_Error err;
108628 +
108629 + /* if rx pause is enabled, do NOT ignore pause frames */
108630 + err = FM_MAC_SetRxIgnorePauseFrames(fm_mac_dev, !en);
108631 +
108632 + _errno = -GET_ERROR_TYPE(err);
108633 + if (_errno < 0)
108634 + pr_err("FM_MAC_SetRxIgnorePauseFrames() = 0x%08x\n", err);
108635 +
108636 + return _errno;
108637 +}
108638 +EXPORT_SYMBOL(fm_mac_set_rx_pause_frames);
108639 +
108640 +#ifdef CONFIG_FMAN_PFC
108641 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
108642 + bool en)
108643 +{
108644 + int _errno, i;
108645 + t_Error err;
108646 +
108647 + if (en)
108648 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
108649 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
108650 + i, fsl_fm_pfc_quanta[i],
108651 + FSL_FM_PAUSE_THRESH_DEFAULT);
108652 + _errno = -GET_ERROR_TYPE(err);
108653 + if (_errno < 0) {
108654 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
108655 + return _errno;
108656 + }
108657 + }
108658 + else
108659 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
108660 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
108661 + i, FSL_FM_PAUSE_TIME_DISABLE,
108662 + FSL_FM_PAUSE_THRESH_DEFAULT);
108663 + _errno = -GET_ERROR_TYPE(err);
108664 + if (_errno < 0) {
108665 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
108666 + return _errno;
108667 + }
108668 + }
108669 +
108670 + return _errno;
108671 +}
108672 +#else
108673 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
108674 + bool en)
108675 +{
108676 + int _errno;
108677 + t_Error err;
108678 +
108679 + if (en)
108680 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
108681 + FSL_FM_PAUSE_TIME_ENABLE);
108682 + else
108683 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
108684 + FSL_FM_PAUSE_TIME_DISABLE);
108685 +
108686 + _errno = -GET_ERROR_TYPE(err);
108687 + if (_errno < 0)
108688 + pr_err("FM_MAC_SetTxAutoPauseFrames() = 0x%08x\n", err);
108689 +
108690 + return _errno;
108691 +}
108692 +#endif
108693 +EXPORT_SYMBOL(fm_mac_set_tx_pause_frames);
108694 +
108695 +int fm_rtc_enable(struct fm *fm_dev)
108696 +{
108697 + int _errno;
108698 + t_Error err;
108699 +
108700 + err = FM_RTC_Enable(fm_get_rtc_handle(fm_dev), 0);
108701 + _errno = -GET_ERROR_TYPE(err);
108702 + if (unlikely(_errno < 0))
108703 + pr_err("FM_RTC_Enable = 0x%08x\n", err);
108704 +
108705 + return _errno;
108706 +}
108707 +EXPORT_SYMBOL(fm_rtc_enable);
108708 +
108709 +int fm_rtc_disable(struct fm *fm_dev)
108710 +{
108711 + int _errno;
108712 + t_Error err;
108713 +
108714 + err = FM_RTC_Disable(fm_get_rtc_handle(fm_dev));
108715 + _errno = -GET_ERROR_TYPE(err);
108716 + if (unlikely(_errno < 0))
108717 + pr_err("FM_RTC_Disable = 0x%08x\n", err);
108718 +
108719 + return _errno;
108720 +}
108721 +EXPORT_SYMBOL(fm_rtc_disable);
108722 +
108723 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts)
108724 +{
108725 + int _errno;
108726 + t_Error err;
108727 +
108728 + err = FM_RTC_GetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
108729 + _errno = -GET_ERROR_TYPE(err);
108730 + if (unlikely(_errno < 0))
108731 + pr_err("FM_RTC_GetCurrentTime = 0x%08x\n", err);
108732 +
108733 + return _errno;
108734 +}
108735 +EXPORT_SYMBOL(fm_rtc_get_cnt);
108736 +
108737 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts)
108738 +{
108739 + int _errno;
108740 + t_Error err;
108741 +
108742 + err = FM_RTC_SetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
108743 + _errno = -GET_ERROR_TYPE(err);
108744 + if (unlikely(_errno < 0))
108745 + pr_err("FM_RTC_SetCurrentTime = 0x%08x\n", err);
108746 +
108747 + return _errno;
108748 +}
108749 +EXPORT_SYMBOL(fm_rtc_set_cnt);
108750 +
108751 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift)
108752 +{
108753 + int _errno;
108754 + t_Error err;
108755 +
108756 + err = FM_RTC_GetFreqCompensation(fm_get_rtc_handle(fm_dev),
108757 + drift);
108758 + _errno = -GET_ERROR_TYPE(err);
108759 + if (unlikely(_errno < 0))
108760 + pr_err("FM_RTC_GetFreqCompensation = 0x%08x\n", err);
108761 +
108762 + return _errno;
108763 +}
108764 +EXPORT_SYMBOL(fm_rtc_get_drift);
108765 +
108766 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift)
108767 +{
108768 + int _errno;
108769 + t_Error err;
108770 +
108771 + err = FM_RTC_SetFreqCompensation(fm_get_rtc_handle(fm_dev),
108772 + drift);
108773 + _errno = -GET_ERROR_TYPE(err);
108774 + if (unlikely(_errno < 0))
108775 + pr_err("FM_RTC_SetFreqCompensation = 0x%08x\n", err);
108776 +
108777 + return _errno;
108778 +}
108779 +EXPORT_SYMBOL(fm_rtc_set_drift);
108780 +
108781 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
108782 + uint64_t time)
108783 +{
108784 + t_FmRtcAlarmParams alarm;
108785 + int _errno;
108786 + t_Error err;
108787 +
108788 + alarm.alarmId = id;
108789 + alarm.alarmTime = time;
108790 + alarm.f_AlarmCallback = NULL;
108791 + err = FM_RTC_SetAlarm(fm_get_rtc_handle(fm_dev),
108792 + &alarm);
108793 + _errno = -GET_ERROR_TYPE(err);
108794 + if (unlikely(_errno < 0))
108795 + pr_err("FM_RTC_SetAlarm = 0x%08x\n", err);
108796 +
108797 + return _errno;
108798 +}
108799 +EXPORT_SYMBOL(fm_rtc_set_alarm);
108800 +
108801 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
108802 + uint64_t fiper)
108803 +{
108804 + t_FmRtcPeriodicPulseParams pp;
108805 + int _errno;
108806 + t_Error err;
108807 +
108808 + pp.periodicPulseId = id;
108809 + pp.periodicPulsePeriod = fiper;
108810 + pp.f_PeriodicPulseCallback = NULL;
108811 + err = FM_RTC_SetPeriodicPulse(fm_get_rtc_handle(fm_dev), &pp);
108812 + _errno = -GET_ERROR_TYPE(err);
108813 + if (unlikely(_errno < 0))
108814 + pr_err("FM_RTC_SetPeriodicPulse = 0x%08x\n", err);
108815 +
108816 + return _errno;
108817 +}
108818 +EXPORT_SYMBOL(fm_rtc_set_fiper);
108819 +
108820 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
108821 +int fm_rtc_enable_interrupt(struct fm *fm_dev, uint32_t events)
108822 +{
108823 + int _errno;
108824 + t_Error err;
108825 +
108826 + err = FM_RTC_EnableInterrupt(fm_get_rtc_handle(fm_dev),
108827 + events);
108828 + _errno = -GET_ERROR_TYPE(err);
108829 + if (unlikely(_errno < 0))
108830 + pr_err("FM_RTC_EnableInterrupt = 0x%08x\n", err);
108831 +
108832 + return _errno;
108833 +}
108834 +EXPORT_SYMBOL(fm_rtc_enable_interrupt);
108835 +
108836 +int fm_rtc_disable_interrupt(struct fm *fm_dev, uint32_t events)
108837 +{
108838 + int _errno;
108839 + t_Error err;
108840 +
108841 + err = FM_RTC_DisableInterrupt(fm_get_rtc_handle(fm_dev),
108842 + events);
108843 + _errno = -GET_ERROR_TYPE(err);
108844 + if (unlikely(_errno < 0))
108845 + pr_err("FM_RTC_DisableInterrupt = 0x%08x\n", err);
108846 +
108847 + return _errno;
108848 +}
108849 +EXPORT_SYMBOL(fm_rtc_disable_interrupt);
108850 +#endif
108851 +
108852 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, bool en)
108853 +{
108854 + int _errno;
108855 + t_Error err;
108856 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108857 +
108858 + /* Do not set WoL on AR ports */
108859 + if (FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) {
108860 + printk(KERN_WARNING "Port is AutoResponse enabled! WoL will not be set on this port!\n");
108861 + return 0;
108862 + }
108863 +
108864 + err = FM_MAC_SetWakeOnLan(fm_mac_dev, en);
108865 +
108866 + _errno = -GET_ERROR_TYPE(err);
108867 + if (_errno < 0)
108868 + pr_err("FM_MAC_SetWakeOnLan() = 0x%08x\n", err);
108869 +
108870 + return _errno;
108871 +}
108872 +EXPORT_SYMBOL(fm_mac_set_wol);
108873 +
108874 +void fm_mutex_lock(void)
108875 +{
108876 + mutex_lock(&lnxwrp_mutex);
108877 +}
108878 +EXPORT_SYMBOL(fm_mutex_lock);
108879 +
108880 +void fm_mutex_unlock(void)
108881 +{
108882 + mutex_unlock(&lnxwrp_mutex);
108883 +}
108884 +EXPORT_SYMBOL(fm_mutex_unlock);
108885 +
108886 +/*Macsec wrapper functions*/
108887 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params)
108888 +{
108889 + struct fm_macsec_dev *fm_macsec_dev;
108890 +
108891 + fm_macsec_dev = FM_MACSEC_Config((t_FmMacsecParams *)fm_params);
108892 + if (unlikely(fm_macsec_dev == NULL))
108893 + pr_err("FM_MACSEC_Config() failed\n");
108894 +
108895 + return fm_macsec_dev;
108896 +}
108897 +EXPORT_SYMBOL(fm_macsec_config);
108898 +
108899 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev)
108900 +{
108901 + int err;
108902 + int _errno;
108903 +
108904 + err = FM_MACSEC_Init(fm_macsec_dev);
108905 + _errno = -GET_ERROR_TYPE(err);
108906 + if (unlikely(_errno < 0))
108907 + pr_err("FM_MACSEC_Init() = 0x%08x\n", err);
108908 +
108909 + return _errno;
108910 +}
108911 +EXPORT_SYMBOL(fm_macsec_init);
108912 +
108913 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev)
108914 +{
108915 + int err;
108916 + int _error;
108917 +
108918 + err = FM_MACSEC_Free(fm_macsec_dev);
108919 + _error = -GET_ERROR_TYPE(err);
108920 +
108921 + if (unlikely(_error < 0))
108922 + pr_err("FM_MACSEC_Free() = 0x%08x\n", err);
108923 +
108924 + return _error;
108925 +}
108926 +EXPORT_SYMBOL(fm_macsec_free);
108927 +
108928 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
108929 + *fm_macsec_dev,
108930 + fm_macsec_unknown_sci_frame_treatment treat_mode)
108931 +{
108932 + int err;
108933 + int _errno;
108934 +
108935 + err = FM_MACSEC_ConfigUnknownSciFrameTreatment(fm_macsec_dev,
108936 + treat_mode);
108937 + _errno = -GET_ERROR_TYPE(err);
108938 + if (unlikely(_errno < 0))
108939 + pr_err("FM_MACSEC_ConfigUnknownSciFrameTreatmen() = 0x%08x\n", err);
108940 +
108941 + return _errno;
108942 +}
108943 +EXPORT_SYMBOL(fm_macsec_config_unknown_sci_frame_treatment);
108944 +
108945 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
108946 + bool deliver_uncontrolled)
108947 +{
108948 + int err;
108949 + int _errno;
108950 +
108951 + err = FM_MACSEC_ConfigInvalidTagsFrameTreatment(fm_macsec_dev,
108952 + deliver_uncontrolled);
108953 + _errno = -GET_ERROR_TYPE(err);
108954 + if (unlikely(_errno < 0))
108955 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
108956 +
108957 + return _errno;
108958 +}
108959 +EXPORT_SYMBOL(fm_macsec_config_invalid_tags_frame_treatment);
108960 +
108961 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
108962 + bool discard_uncontrolled)
108963 +{
108964 + int err;
108965 + int _errno;
108966 +
108967 + err = FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(fm_macsec_dev,
108968 + discard_uncontrolled);
108969 + _errno = -GET_ERROR_TYPE(err);
108970 + if (unlikely(_errno < 0))
108971 + pr_err("FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatmen() = 0x%08x\n", err);
108972 +
108973 + return _errno;
108974 +}
108975 +EXPORT_SYMBOL(fm_macsec_config_kay_frame_treatment);
108976 +
108977 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
108978 + fm_macsec_untag_frame_treatment treat_mode)
108979 +{
108980 + int err;
108981 + int _errno;
108982 +
108983 + err = FM_MACSEC_ConfigUntagFrameTreatment(fm_macsec_dev, treat_mode);
108984 + _errno = -GET_ERROR_TYPE(err);
108985 + if (unlikely(_errno < 0))
108986 + pr_err("FM_MACSEC_ConfigUntagFrameTreatment() = 0x%08x\n", err);
108987 +
108988 + return _errno;
108989 +}
108990 +EXPORT_SYMBOL(fm_macsec_config_untag_frame_treatment);
108991 +
108992 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
108993 + uint32_t pn_exh_thr)
108994 +{
108995 + int err;
108996 + int _errno;
108997 +
108998 + err = FM_MACSEC_ConfigPnExhaustionThreshold(fm_macsec_dev, pn_exh_thr);
108999 + _errno = -GET_ERROR_TYPE(err);
109000 + if (unlikely(_errno < 0))
109001 + pr_err("FM_MACSEC_ConfigPnExhaustionThreshold() = 0x%08x\n", err);
109002 +
109003 + return _errno;
109004 +}
109005 +EXPORT_SYMBOL(fm_macsec_config_pn_exhaustion_threshold);
109006 +
109007 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev)
109008 +{
109009 + int err;
109010 + int _errno;
109011 +
109012 + err = FM_MACSEC_ConfigKeysUnreadable(fm_macsec_dev);
109013 + _errno = -GET_ERROR_TYPE(err);
109014 + if (unlikely(_errno < 0))
109015 + pr_err("FM_MACSEC_ConfigKeysUnreadable() = 0x%08x\n", err);
109016 +
109017 + return _errno;
109018 +}
109019 +EXPORT_SYMBOL(fm_macsec_config_keys_unreadable);
109020 +
109021 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev)
109022 +{
109023 + int err;
109024 + int _errno;
109025 +
109026 + err = FM_MACSEC_ConfigSectagWithoutSCI(fm_macsec_dev);
109027 + _errno = -GET_ERROR_TYPE(err);
109028 + if (unlikely(_errno < 0))
109029 + pr_err("FM_MACSEC_ConfigSectagWithoutSCI() = 0x%08x\n", err);
109030 +
109031 + return _errno;
109032 +}
109033 +EXPORT_SYMBOL(fm_macsec_config_sectag_without_sci);
109034 +
109035 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
109036 + fm_macsec_exception exception, bool enable)
109037 +{
109038 + int err;
109039 + int _errno;
109040 +
109041 + err = FM_MACSEC_ConfigException(fm_macsec_dev, exception, enable);
109042 + _errno = -GET_ERROR_TYPE(err);
109043 + if (unlikely(_errno < 0))
109044 + pr_err("FM_MACSEC_ConfigException() = 0x%08x\n", err);
109045 +
109046 + return _errno;
109047 +}
109048 +EXPORT_SYMBOL(fm_macsec_config_exception);
109049 +
109050 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
109051 + int *macsec_revision)
109052 +{
109053 + int err;
109054 + int _errno;
109055 +
109056 + err = FM_MACSEC_GetRevision(fm_macsec_dev, macsec_revision);
109057 + _errno = -GET_ERROR_TYPE(err);
109058 + if (unlikely(_errno < 0))
109059 + pr_err("FM_MACSEC_GetRevision() = 0x%08x\n", err);
109060 +
109061 + return _errno;
109062 +}
109063 +EXPORT_SYMBOL(fm_macsec_get_revision);
109064 +
109065 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev)
109066 +{
109067 + int err;
109068 + int _errno;
109069 +
109070 + err = FM_MACSEC_Enable(fm_macsec_dev);
109071 + _errno = -GET_ERROR_TYPE(err);
109072 + if (unlikely(_errno < 0))
109073 + pr_err("FM_MACSEC_Enable() = 0x%08x\n", err);
109074 +
109075 + return _errno;
109076 +}
109077 +EXPORT_SYMBOL(fm_macsec_enable);
109078 +
109079 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev)
109080 +{
109081 + int err;
109082 + int _errno;
109083 +
109084 + err = FM_MACSEC_Disable(fm_macsec_dev);
109085 + _errno = -GET_ERROR_TYPE(err);
109086 + if (unlikely(_errno < 0))
109087 + pr_err("FM_MACSEC_Disable() = 0x%08x\n", err);
109088 +
109089 + return _errno;
109090 +}
109091 +EXPORT_SYMBOL(fm_macsec_disable);
109092 +
109093 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
109094 + fm_macsec_exception exception, bool enable)
109095 +{
109096 + int err;
109097 + int _errno;
109098 +
109099 + err = FM_MACSEC_SetException(fm_macsec_dev, exception, enable);
109100 + _errno = -GET_ERROR_TYPE(err);
109101 + if (unlikely(_errno < 0))
109102 + pr_err("FM_MACSEC_SetException() = 0x%08x\n", err);
109103 +
109104 + return _errno;
109105 +}
109106 +EXPORT_SYMBOL(fm_macsec_set_exception);
109107 +
109108 +/* Macsec SECY wrapper API */
109109 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params)
109110 +{
109111 + struct fm_macsec_secy_dev *fm_macsec_secy;
109112 +
109113 + fm_macsec_secy = FM_MACSEC_SECY_Config((t_FmMacsecSecYParams *)secy_params);
109114 + if (unlikely(fm_macsec_secy < 0))
109115 + pr_err("FM_MACSEC_SECY_Config() failed\n");
109116 +
109117 + return fm_macsec_secy;
109118 +}
109119 +EXPORT_SYMBOL(fm_macsec_secy_config);
109120 +
109121 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109122 +{
109123 + int err;
109124 + int _errno;
109125 +
109126 + err = FM_MACSEC_SECY_Init(fm_macsec_secy_dev);
109127 + _errno = -GET_ERROR_TYPE(err);
109128 + if (unlikely(_errno < 0))
109129 + pr_err("FM_MACSEC_SECY_Init() = 0x%08x\n", err);
109130 +
109131 + return _errno;
109132 +}
109133 +EXPORT_SYMBOL(fm_macsec_secy_init);
109134 +
109135 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109136 +{
109137 + int err;
109138 + int _errno;
109139 +
109140 + err = FM_MACSEC_SECY_Free(fm_macsec_secy_dev);
109141 + _errno = -GET_ERROR_TYPE(err);
109142 + if (unlikely(_errno < 0))
109143 + pr_err("FM_MACSEC_SECY_Free() = 0x%08x\n", err);
109144 +
109145 + return _errno;
109146 +}
109147 +EXPORT_SYMBOL(fm_macsec_secy_free);
109148 +
109149 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109150 + fm_macsec_sci_insertion_mode sci_insertion_mode)
109151 +{
109152 + int err;
109153 + int _errno;
109154 +
109155 + err = FM_MACSEC_SECY_ConfigSciInsertionMode(fm_macsec_secy_dev,
109156 + sci_insertion_mode);
109157 + _errno = -GET_ERROR_TYPE(err);
109158 + if (unlikely(_errno < 0))
109159 + pr_err("FM_MACSEC_SECY_ConfigSciInsertionMode() = 0x%08x\n", err);
109160 +
109161 + return _errno;
109162 +}
109163 +EXPORT_SYMBOL(fm_macsec_secy_config_sci_insertion_mode);
109164 +
109165 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109166 + bool protect_frames)
109167 +{
109168 + int err;
109169 + int _errno;
109170 +
109171 + err = FM_MACSEC_SECY_ConfigProtectFrames(fm_macsec_secy_dev,
109172 + protect_frames);
109173 + _errno = -GET_ERROR_TYPE(err);
109174 + if (unlikely(_errno < 0))
109175 + pr_err("FM_MACSEC_SECY_ConfigProtectFrames() = 0x%08x\n", err);
109176 +
109177 + return _errno;
109178 +}
109179 +EXPORT_SYMBOL(fm_macsec_secy_config_protect_frames);
109180 +
109181 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109182 + bool replay_protect, uint32_t replay_window)
109183 +{
109184 + int err;
109185 + int _errno;
109186 +
109187 + err = FM_MACSEC_SECY_ConfigReplayWindow(fm_macsec_secy_dev,
109188 + replay_protect, replay_window);
109189 + _errno = -GET_ERROR_TYPE(err);
109190 + if (unlikely(_errno < 0))
109191 + pr_err("FM_MACSEC_SECY_ConfigReplayWindow() = 0x%08x\n", err);
109192 +
109193 + return _errno;
109194 +}
109195 +EXPORT_SYMBOL(fm_macsec_secy_config_replay_window);
109196 +
109197 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109198 + fm_macsec_valid_frame_behavior validate_frames)
109199 +{
109200 + int err;
109201 + int _errno;
109202 +
109203 + err = FM_MACSEC_SECY_ConfigValidationMode(fm_macsec_secy_dev,
109204 + validate_frames);
109205 + _errno = -GET_ERROR_TYPE(err);
109206 + if (unlikely(_errno < 0))
109207 + pr_err("FM_MACSEC_SECY_ConfigValidationMode() = 0x%08x\n", err);
109208 +
109209 + return _errno;
109210 +}
109211 +EXPORT_SYMBOL(fm_macsec_secy_config_validation_mode);
109212 +
109213 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109214 + bool confidentiality_enable,
109215 + uint32_t confidentiality_offset)
109216 +{
109217 + int err;
109218 + int _errno;
109219 +
109220 + err = FM_MACSEC_SECY_ConfigConfidentiality(fm_macsec_secy_dev,
109221 + confidentiality_enable,
109222 + confidentiality_offset);
109223 + _errno = -GET_ERROR_TYPE(err);
109224 + if (unlikely(_errno < 0))
109225 + pr_err("FM_MACSEC_SECY_ConfigConfidentiality() = 0x%08x\n",
109226 + err);
109227 +
109228 + return _errno;
109229 +}
109230 +EXPORT_SYMBOL(fm_macsec_secy_config_confidentiality);
109231 +
109232 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109233 +{
109234 + int err;
109235 + int _errno;
109236 +
109237 + err = FM_MACSEC_SECY_ConfigPointToPoint(fm_macsec_secy_dev);
109238 + _errno = -GET_ERROR_TYPE(err);
109239 + if (unlikely(_errno < 0))
109240 + pr_err("FM_MACSEC_SECY_ConfigPointToPoint() = 0x%08x\n",
109241 + err);
109242 +
109243 + return _errno;
109244 +}
109245 +EXPORT_SYMBOL(fm_macsec_secy_config_point_to_point);
109246 +
109247 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109248 + fm_macsec_secy_exception exception,
109249 + bool enable)
109250 +{
109251 + int err;
109252 + int _errno;
109253 +
109254 + err = FM_MACSEC_SECY_ConfigException(fm_macsec_secy_dev, exception,
109255 + enable);
109256 + _errno = -GET_ERROR_TYPE(err);
109257 + if (unlikely(_errno < 0))
109258 + pr_err("FM_MACSEC_SECY_ConfigException() = 0x%08x\n",
109259 + err);
109260 +
109261 + return _errno;
109262 +}
109263 +EXPORT_SYMBOL(fm_macsec_secy_config_exception);
109264 +
109265 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109266 + fm_macsec_secy_event event,
109267 + bool enable)
109268 +{
109269 + int err;
109270 + int _errno;
109271 +
109272 + err = FM_MACSEC_SECY_ConfigEvent(fm_macsec_secy_dev, event, enable);
109273 + _errno = -GET_ERROR_TYPE(err);
109274 + if (unlikely(_errno < 0))
109275 + pr_err("FM_MACSEC_SECY_ConfigEvent() = 0x%08x\n",
109276 + err);
109277 +
109278 + return _errno;
109279 +}
109280 +EXPORT_SYMBOL(fm_macsec_secy_config_event);
109281 +
109282 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109283 + struct fm_macsec_secy_sc_params *params)
109284 +{
109285 + struct rx_sc_dev *rx_sc_dev;
109286 +
109287 + rx_sc_dev = FM_MACSEC_SECY_CreateRxSc(fm_macsec_secy_dev, (t_FmMacsecSecYSCParams *)params);
109288 + if (unlikely(rx_sc_dev == NULL))
109289 + pr_err("FM_MACSEC_SECY_CreateRxSc() failed\n");
109290 +
109291 + return rx_sc_dev;
109292 +}
109293 +EXPORT_SYMBOL(fm_macsec_secy_create_rxsc);
109294 +
109295 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109296 + struct rx_sc_dev *sc)
109297 +{
109298 + int err;
109299 + int _errno;
109300 +
109301 + err = FM_MACSEC_SECY_DeleteRxSc(fm_macsec_secy_dev, sc);
109302 + _errno = -GET_ERROR_TYPE(err);
109303 + if (unlikely(_errno < 0))
109304 + pr_err("FM_MACSEC_SECY_DeleteRxSc() = 0x%08x\n",
109305 + err);
109306 +
109307 + return _errno;
109308 +}
109309 +EXPORT_SYMBOL(fm_macsec_secy_delete_rxsc);
109310 +
109311 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109312 + struct rx_sc_dev *sc, macsec_an_t an,
109313 + uint32_t lowest_pn, macsec_sa_key_t key)
109314 +{
109315 + int err;
109316 + int _errno;
109317 +
109318 + err = FM_MACSEC_SECY_CreateRxSa(fm_macsec_secy_dev, sc, an,
109319 + lowest_pn, key);
109320 + _errno = -GET_ERROR_TYPE(err);
109321 + if (unlikely(_errno < 0))
109322 + pr_err("FM_MACSEC_SECY_CreateRxSa() = 0x%08x\n",
109323 + err);
109324 +
109325 + return _errno;
109326 +}
109327 +EXPORT_SYMBOL(fm_macsec_secy_create_rx_sa);
109328 +
109329 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109330 + struct rx_sc_dev *sc, macsec_an_t an)
109331 +{
109332 + int err;
109333 + int _errno;
109334 +
109335 + err = FM_MACSEC_SECY_DeleteRxSa(fm_macsec_secy_dev, sc, an);
109336 + _errno = -GET_ERROR_TYPE(err);
109337 + if (unlikely(_errno < 0))
109338 + pr_err("FM_MACSEC_SECY_DeleteRxSa() = 0x%08x\n",
109339 + err);
109340 +
109341 + return _errno;
109342 +}
109343 +EXPORT_SYMBOL(fm_macsec_secy_delete_rx_sa);
109344 +
109345 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109346 + struct rx_sc_dev *sc,
109347 + macsec_an_t an)
109348 +{
109349 + int err;
109350 + int _errno;
109351 +
109352 + err = FM_MACSEC_SECY_RxSaEnableReceive(fm_macsec_secy_dev, sc, an);
109353 + _errno = -GET_ERROR_TYPE(err);
109354 + if (unlikely(_errno < 0))
109355 + pr_err("FM_MACSEC_SECY_RxSaEnableReceive() = 0x%08x\n",
109356 + err);
109357 +
109358 + return _errno;
109359 +}
109360 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_enable_receive);
109361 +
109362 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109363 + struct rx_sc_dev *sc,
109364 + macsec_an_t an)
109365 +{
109366 + int err;
109367 + int _errno;
109368 +
109369 + err = FM_MACSEC_SECY_RxSaDisableReceive(fm_macsec_secy_dev, sc, an);
109370 + _errno = -GET_ERROR_TYPE(err);
109371 + if (unlikely(_errno < 0))
109372 + pr_err("FM_MACSEC_SECY_RxSaDisableReceive() = 0x%08x\n",
109373 + err);
109374 +
109375 + return _errno;
109376 +}
109377 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_disable_receive);
109378 +
109379 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109380 + struct rx_sc_dev *sc,
109381 + macsec_an_t an, uint32_t updt_next_pn)
109382 +{
109383 + int err;
109384 + int _errno;
109385 +
109386 + err = FM_MACSEC_SECY_RxSaUpdateNextPn(fm_macsec_secy_dev, sc, an,
109387 + updt_next_pn);
109388 + _errno = -GET_ERROR_TYPE(err);
109389 + if (unlikely(_errno < 0))
109390 + pr_err("FM_MACSEC_SECY_RxSaUpdateNextPn() = 0x%08x\n", err);
109391 +
109392 + return _errno;
109393 +}
109394 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_next_pn);
109395 +
109396 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109397 + struct rx_sc_dev *sc,
109398 + macsec_an_t an, uint32_t updt_lowest_pn)
109399 +{
109400 + int err;
109401 + int _errno;
109402 +
109403 + err = FM_MACSEC_SECY_RxSaUpdateLowestPn(fm_macsec_secy_dev, sc, an,
109404 + updt_lowest_pn);
109405 + _errno = -GET_ERROR_TYPE(err);
109406 + if (unlikely(_errno < 0))
109407 + pr_err("FM_MACSEC_SECY_RxSaUpdateLowestPn() = 0x%08x\n",
109408 + err);
109409 +
109410 + return _errno;
109411 +}
109412 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_lowest_pn);
109413 +
109414 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109415 + struct rx_sc_dev *sc,
109416 + macsec_an_t an, macsec_sa_key_t key)
109417 +{
109418 + int err;
109419 + int _errno;
109420 +
109421 + err = FM_MACSEC_SECY_RxSaModifyKey(fm_macsec_secy_dev, sc, an, key);
109422 + _errno = -GET_ERROR_TYPE(err);
109423 + if (unlikely(_errno < 0))
109424 + pr_err("FM_MACSEC_SECY_RxSaModifyKey() = 0x%08x\n",
109425 + err);
109426 +
109427 + return _errno;
109428 +}
109429 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_modify_key);
109430 +
109431 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109432 + macsec_an_t an, macsec_sa_key_t key)
109433 +{
109434 + int err;
109435 + int _errno;
109436 +
109437 + err = FM_MACSEC_SECY_CreateTxSa(fm_macsec_secy_dev, an, key);
109438 + _errno = -GET_ERROR_TYPE(err);
109439 + if (unlikely(_errno < 0))
109440 + pr_err("FM_MACSEC_SECY_CreateTxSa() = 0x%08x\n",
109441 + err);
109442 +
109443 + return _errno;
109444 +}
109445 +EXPORT_SYMBOL(fm_macsec_secy_create_tx_sa);
109446 +
109447 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109448 + macsec_an_t an)
109449 +{
109450 + int err;
109451 + int _errno;
109452 +
109453 + err = FM_MACSEC_SECY_DeleteTxSa(fm_macsec_secy_dev, an);
109454 + _errno = -GET_ERROR_TYPE(err);
109455 + if (unlikely(_errno < 0))
109456 + pr_err("FM_MACSEC_SECY_DeleteTxSa() = 0x%08x\n",
109457 + err);
109458 +
109459 + return _errno;
109460 +}
109461 +EXPORT_SYMBOL(fm_macsec_secy_delete_tx_sa);
109462 +
109463 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109464 + macsec_an_t next_active_an,
109465 + macsec_sa_key_t key)
109466 +{
109467 + int err;
109468 + int _errno;
109469 +
109470 + err = FM_MACSEC_SECY_TxSaModifyKey(fm_macsec_secy_dev, next_active_an,
109471 + key);
109472 + _errno = -GET_ERROR_TYPE(err);
109473 + if (unlikely(_errno < 0))
109474 + pr_err("FM_MACSEC_SECY_TxSaModifyKey() = 0x%08x\n",
109475 + err);
109476 +
109477 + return _errno;
109478 +}
109479 +EXPORT_SYMBOL(fm_macsec_secy_txsa_modify_key);
109480 +
109481 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109482 + macsec_an_t an)
109483 +{
109484 + int err;
109485 + int _errno;
109486 +
109487 + err = FM_MACSEC_SECY_TxSaSetActive(fm_macsec_secy_dev, an);
109488 + _errno = -GET_ERROR_TYPE(err);
109489 + if (unlikely(_errno < 0))
109490 + pr_err("FM_MACSEC_SECY_TxSaSetActive() = 0x%08x\n",
109491 + err);
109492 +
109493 + return _errno;
109494 +}
109495 +EXPORT_SYMBOL(fm_macsec_secy_txsa_set_active);
109496 +
109497 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109498 + macsec_an_t *p_an)
109499 +{
109500 + int err;
109501 + int _errno;
109502 +
109503 + err = FM_MACSEC_SECY_TxSaGetActive(fm_macsec_secy_dev, p_an);
109504 + _errno = -GET_ERROR_TYPE(err);
109505 + if (unlikely(_errno < 0))
109506 + pr_err("FM_MACSEC_SECY_TxSaGetActive() = 0x%08x\n",
109507 + err);
109508 +
109509 + return _errno;
109510 +}
109511 +EXPORT_SYMBOL(fm_macsec_secy_txsa_get_active);
109512 +
109513 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109514 + struct rx_sc_dev *sc, uint32_t *sc_phys_id)
109515 +{
109516 + int err;
109517 + int _errno;
109518 +
109519 + err = FM_MACSEC_SECY_GetRxScPhysId(fm_macsec_secy_dev, sc, sc_phys_id);
109520 + _errno = -GET_ERROR_TYPE(err);
109521 + if (unlikely(_errno < 0))
109522 + pr_err("FM_MACSEC_SECY_GetRxScPhysId() = 0x%08x\n",
109523 + err);
109524 +
109525 + return _errno;
109526 +}
109527 +EXPORT_SYMBOL(fm_macsec_secy_get_rxsc_phys_id);
109528 +
109529 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109530 + uint32_t *sc_phys_id)
109531 +{
109532 + int err;
109533 + int _errno;
109534 +
109535 + err = FM_MACSEC_SECY_GetTxScPhysId(fm_macsec_secy_dev, sc_phys_id);
109536 + _errno = -GET_ERROR_TYPE(err);
109537 + if (unlikely(_errno < 0))
109538 + pr_err("FM_MACSEC_SECY_GetTxScPhysId() = 0x%08x\n",
109539 + err);
109540 +
109541 + return _errno;
109542 +}
109543 +EXPORT_SYMBOL(fm_macsec_secy_get_txsc_phys_id);
109544 +
109545 +static t_Handle h_FmLnxWrp;
109546 +
109547 +static int __init __cold fm_load (void)
109548 +{
109549 + if ((h_FmLnxWrp = LNXWRP_FM_Init()) == NULL)
109550 + {
109551 + printk("Failed to init FM wrapper!\n");
109552 + return -ENODEV;
109553 + }
109554 +
109555 + printk(KERN_CRIT "Freescale FM module," \
109556 + " FMD API version %d.%d.%d\n",
109557 + FMD_API_VERSION_MAJOR,
109558 + FMD_API_VERSION_MINOR,
109559 + FMD_API_VERSION_RESPIN);
109560 + return 0;
109561 +}
109562 +
109563 +static void __exit __cold fm_unload (void)
109564 +{
109565 + if (h_FmLnxWrp)
109566 + LNXWRP_FM_Free(h_FmLnxWrp);
109567 +}
109568 +
109569 +module_init (fm_load);
109570 +module_exit (fm_unload);
109571 --- /dev/null
109572 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
109573 @@ -0,0 +1,294 @@
109574 +/*
109575 + * Copyright 2008-2012 Freescale Semiconductor Inc.
109576 + *
109577 + * Redistribution and use in source and binary forms, with or without
109578 + * modification, are permitted provided that the following conditions are met:
109579 + * * Redistributions of source code must retain the above copyright
109580 + * notice, this list of conditions and the following disclaimer.
109581 + * * Redistributions in binary form must reproduce the above copyright
109582 + * notice, this list of conditions and the following disclaimer in the
109583 + * documentation and/or other materials provided with the distribution.
109584 + * * Neither the name of Freescale Semiconductor nor the
109585 + * names of its contributors may be used to endorse or promote products
109586 + * derived from this software without specific prior written permission.
109587 + *
109588 + *
109589 + * ALTERNATIVELY, this software may be distributed under the terms of the
109590 + * GNU General Public License ("GPL") as published by the Free Software
109591 + * Foundation, either version 2 of that License or (at your option) any
109592 + * later version.
109593 + *
109594 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
109595 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
109596 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
109597 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
109598 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
109599 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
109600 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
109601 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
109602 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
109603 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
109604 + */
109605 +
109606 +/*
109607 + @File lnxwrp_fm.h
109608 +
109609 + @Author Shlomi Gridish
109610 +
109611 + @Description FM Linux wrapper functions.
109612 +
109613 +*/
109614 +
109615 +#ifndef __LNXWRP_FM_H__
109616 +#define __LNXWRP_FM_H__
109617 +
109618 +#include <linux/fsl_qman.h> /* struct qman_fq */
109619 +
109620 +#include "std_ext.h"
109621 +#include "error_ext.h"
109622 +#include "list_ext.h"
109623 +
109624 +#include "lnxwrp_fm_ext.h"
109625 +
109626 +#define FM_MAX_NUM_OF_ADV_SETTINGS 10
109627 +
109628 +#define LNXWRP_FM_NUM_OF_SHARED_PROFILES 16
109629 +
109630 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
109631 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
109632 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
109633 +#else
109634 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
109635 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
109636 +#endif
109637 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
109638 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
109639 +
109640 +#define FRAG_MANIP_SPACE 128
109641 +#define FRAG_DATA_ALIGN 64
109642 +
109643 +#ifndef CONFIG_FSL_FM_MAX_FRAME_SIZE
109644 +#define CONFIG_FSL_FM_MAX_FRAME_SIZE 0
109645 +#endif
109646 +
109647 +#ifndef CONFIG_FSL_FM_RX_EXTRA_HEADROOM
109648 +#define CONFIG_FSL_FM_RX_EXTRA_HEADROOM 16
109649 +#endif
109650 +
109651 +typedef enum {
109652 + e_NO_PCD = 0,
109653 + e_FM_PCD_3_TUPLE
109654 +} e_LnxWrpFmPortPcdDefUseCase;
109655 +
109656 +
109657 +typedef struct t_FmTestFq {
109658 + struct qman_fq fq_base;
109659 + t_Handle h_Arg;
109660 +} t_FmTestFq;
109661 +
109662 +typedef struct {
109663 + uint8_t id; /* sw port id, see SW_PORT_ID_TO_HW_PORT_ID() in fm_common.h */
109664 + int minor;
109665 + char name[20];
109666 + bool active;
109667 + uint64_t phys_baseAddr;
109668 + uint64_t baseAddr; /* Port's *virtual* address */
109669 + uint32_t memSize;
109670 + t_WrpFmPortDevSettings settings;
109671 + t_FmExtPools opExtPools;
109672 + uint8_t totalNumOfSchemes;
109673 + uint8_t schemesBase;
109674 + uint8_t numOfSchemesUsed;
109675 + uint32_t pcdBaseQ;
109676 + uint16_t pcdNumOfQs;
109677 + struct fm_port_pcd_param pcd_owner_params;
109678 + e_LnxWrpFmPortPcdDefUseCase defPcd;
109679 + t_Handle h_DefNetEnv;
109680 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
109681 + t_FmBufferPrefixContent buffPrefixContent;
109682 + t_Handle h_Dev;
109683 + t_Handle h_DfltVsp;
109684 + t_Handle h_LnxWrpFmDev;
109685 + uint16_t txCh;
109686 + struct device *dev;
109687 + struct device_attribute *dev_attr_stats;
109688 + struct device_attribute *dev_attr_regs;
109689 + struct device_attribute *dev_attr_bmi_regs;
109690 + struct device_attribute *dev_attr_qmi_regs;
109691 +#if (DPAA_VERSION >= 11)
109692 + struct device_attribute *dev_attr_ipv4_opt;
109693 +#endif
109694 + struct device_attribute *dev_attr_dsar_regs;
109695 + struct device_attribute *dev_attr_dsar_mem;
109696 + struct auto_res_tables_sizes dsar_table_sizes;
109697 +} t_LnxWrpFmPortDev;
109698 +
109699 +typedef struct {
109700 + uint8_t id;
109701 + bool active;
109702 + uint64_t baseAddr;
109703 + uint32_t memSize;
109704 + t_WrpFmMacDevSettings settings;
109705 + t_Handle h_Dev;
109706 + t_Handle h_LnxWrpFmDev;
109707 +} t_LnxWrpFmMacDev;
109708 +
109709 +/* information about all active ports for an FMan.
109710 + * !Some ports may be disabled by u-boot, thus will not be available */
109711 +struct fm_active_ports {
109712 + uint32_t num_oh_ports;
109713 + uint32_t num_tx_ports;
109714 + uint32_t num_rx_ports;
109715 + uint32_t num_tx25_ports;
109716 + uint32_t num_rx25_ports;
109717 + uint32_t num_tx10_ports;
109718 + uint32_t num_rx10_ports;
109719 +};
109720 +
109721 +/* FMan resources precalculated at fm probe based
109722 + * on available FMan port. */
109723 +struct fm_resource_settings {
109724 + /* buffers - fifo sizes */
109725 + uint32_t tx1g_num_buffers;
109726 + uint32_t rx1g_num_buffers;
109727 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
109728 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
109729 + uint32_t tx10g_num_buffers;
109730 + uint32_t rx10g_num_buffers;
109731 + uint32_t oh_num_buffers;
109732 + uint32_t shared_ext_buffers;
109733 +
109734 + /* open DMAs */
109735 + uint32_t tx_1g_dmas;
109736 + uint32_t rx_1g_dmas;
109737 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
109738 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
109739 + uint32_t tx_10g_dmas;
109740 + uint32_t rx_10g_dmas;
109741 + uint32_t oh_dmas;
109742 + uint32_t shared_ext_open_dma;
109743 +
109744 + /* Tnums */
109745 + uint32_t tx_1g_tnums;
109746 + uint32_t rx_1g_tnums;
109747 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
109748 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
109749 + uint32_t tx_10g_tnums;
109750 + uint32_t rx_10g_tnums;
109751 + uint32_t oh_tnums;
109752 + uint32_t shared_ext_tnums;
109753 +};
109754 +
109755 +typedef struct {
109756 + uint8_t id;
109757 + char name[10];
109758 + bool active;
109759 + bool pcdActive;
109760 + bool prsActive;
109761 + bool kgActive;
109762 + bool ccActive;
109763 + bool plcrActive;
109764 + e_LnxWrpFmPortPcdDefUseCase defPcd;
109765 + uint32_t usedSchemes;
109766 + uint8_t totalNumOfSharedSchemes;
109767 + uint8_t sharedSchemesBase;
109768 + uint8_t numOfSchemesUsed;
109769 + uint8_t defNetEnvId;
109770 + uint64_t fmPhysBaseAddr;
109771 + uint64_t fmBaseAddr;
109772 + uint32_t fmMemSize;
109773 + uint64_t fmMuramPhysBaseAddr;
109774 + uint64_t fmMuramBaseAddr;
109775 + uint32_t fmMuramMemSize;
109776 + uint64_t fmRtcPhysBaseAddr;
109777 + uint64_t fmRtcBaseAddr;
109778 + uint32_t fmRtcMemSize;
109779 + uint64_t fmVspPhysBaseAddr;
109780 + uint64_t fmVspBaseAddr;
109781 + uint32_t fmVspMemSize;
109782 + int irq;
109783 + int err_irq;
109784 + t_WrpFmDevSettings fmDevSettings;
109785 + t_WrpFmPcdDevSettings fmPcdDevSettings;
109786 + t_Handle h_Dev;
109787 + uint16_t hcCh;
109788 +
109789 + t_Handle h_MuramDev;
109790 + t_Handle h_PcdDev;
109791 + t_Handle h_RtcDev;
109792 +
109793 + t_Handle h_DsarRxPort;
109794 + t_Handle h_DsarTxPort;
109795 +
109796 + t_LnxWrpFmPortDev hcPort;
109797 + t_LnxWrpFmPortDev opPorts[FM_MAX_NUM_OF_OH_PORTS-1];
109798 + t_LnxWrpFmPortDev rxPorts[FM_MAX_NUM_OF_RX_PORTS];
109799 + t_LnxWrpFmPortDev txPorts[FM_MAX_NUM_OF_TX_PORTS];
109800 + t_LnxWrpFmMacDev macs[FM_MAX_NUM_OF_MACS];
109801 + struct fm_active_ports fm_active_ports_info;
109802 + struct fm_resource_settings fm_resource_settings_info;
109803 +
109804 + struct device *dev;
109805 + struct resource *res;
109806 + int major;
109807 + struct class *fm_class;
109808 + struct device_attribute *dev_attr_stats;
109809 + struct device_attribute *dev_attr_regs;
109810 + struct device_attribute *dev_attr_risc_load;
109811 +
109812 + struct device_attribute *dev_pcd_attr_stats;
109813 + struct device_attribute *dev_plcr_attr_regs;
109814 + struct device_attribute *dev_prs_attr_regs;
109815 + struct device_attribute *dev_fm_fpm_attr_regs;
109816 + struct device_attribute *dev_fm_kg_attr_regs;
109817 + struct device_attribute *dev_fm_kg_pe_attr_regs;
109818 + struct device_attribute *dev_attr_muram_free_size;
109819 + struct device_attribute *dev_attr_fm_ctrl_code_ver;
109820 +
109821 +
109822 + struct qman_fq *hc_tx_conf_fq, *hc_tx_err_fq, *hc_tx_fq;
109823 +} t_LnxWrpFmDev;
109824 +
109825 +typedef struct {
109826 + t_LnxWrpFmDev *p_FmDevs[INTG_MAX_NUM_OF_FM];
109827 +} t_LnxWrpFm;
109828 +#define LNXWRP_FM_OBJECT(ptr) LIST_OBJECT(ptr, t_LnxWrpFm, fms[((t_LnxWrpFmDev *)ptr)->id])
109829 +
109830 +
109831 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat);
109832 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat);
109833 +
109834 +
109835 +#if 0
109836 +static __inline__ t_Error AllocSchemesForPort(t_LnxWrpFmDev *p_LnxWrpFmDev, uint8_t numSchemes, uint8_t *p_BaseSchemeNum)
109837 +{
109838 + uint32_t schemeMask;
109839 + uint8_t i;
109840 +
109841 + if (!numSchemes)
109842 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
109843 +
109844 + schemeMask = 0x80000000;
109845 + *p_BaseSchemeNum = 0xff;
109846 +
109847 + for (i=0; schemeMask && numSchemes; schemeMask>>=1, i++)
109848 + if ((p_LnxWrpFmDev->usedSchemes & schemeMask) == 0)
109849 + {
109850 + p_LnxWrpFmDev->usedSchemes |= schemeMask;
109851 + numSchemes--;
109852 + if (*p_BaseSchemeNum==0xff)
109853 + *p_BaseSchemeNum = i;
109854 + }
109855 + else if (*p_BaseSchemeNum!=0xff)
109856 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Fragmentation on schemes array!!!"));
109857 +
109858 + if (numSchemes)
109859 + RETURN_ERROR(MINOR, E_FULL, ("schemes!!!"));
109860 + return E_OK;
109861 +}
109862 +#endif
109863 +
109864 +void LnxWrpPCDIOCTLTypeChecking(void);
109865 +void LnxWrpPCDIOCTLEnumChecking(void);
109866 +
109867 +#endif /* __LNXWRP_FM_H__ */
109868 --- /dev/null
109869 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
109870 @@ -0,0 +1,1480 @@
109871 +/*
109872 + * Copyright 2008-2012 Freescale Semiconductor Inc.
109873 + *
109874 + * Redistribution and use in source and binary forms, with or without
109875 + * modification, are permitted provided that the following conditions are met:
109876 + * * Redistributions of source code must retain the above copyright
109877 + * notice, this list of conditions and the following disclaimer.
109878 + * * Redistributions in binary form must reproduce the above copyright
109879 + * notice, this list of conditions and the following disclaimer in the
109880 + * documentation and/or other materials provided with the distribution.
109881 + * * Neither the name of Freescale Semiconductor nor the
109882 + * names of its contributors may be used to endorse or promote products
109883 + * derived from this software without specific prior written permission.
109884 + *
109885 + *
109886 + * ALTERNATIVELY, this software may be distributed under the terms of the
109887 + * GNU General Public License ("GPL") as published by the Free Software
109888 + * Foundation, either version 2 of that License or (at your option) any
109889 + * later version.
109890 + *
109891 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
109892 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
109893 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
109894 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
109895 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
109896 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
109897 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
109898 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
109899 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
109900 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
109901 + */
109902 +
109903 +/*
109904 + @File lnxwrp_fm_port.c
109905 +
109906 + @Description FMD wrapper - FMan port functions.
109907 +
109908 +*/
109909 +
109910 +#include <linux/version.h>
109911 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
109912 +#define MODVERSIONS
109913 +#endif
109914 +#ifdef MODVERSIONS
109915 +#include <config/modversions.h>
109916 +#endif /* MODVERSIONS */
109917 +#include <linux/kernel.h>
109918 +#include <linux/module.h>
109919 +#include <linux/of_platform.h>
109920 +#include <linux/of_address.h>
109921 +#include <linux/cdev.h>
109922 +#include <linux/slab.h>
109923 +#include <linux/spinlock.h>
109924 +#ifndef CONFIG_FMAN_ARM
109925 +#include <linux/fsl/svr.h>
109926 +#endif
109927 +#include <linux/io.h>
109928 +
109929 +#include "sprint_ext.h"
109930 +#include "fm_common.h"
109931 +#include "lnxwrp_fsl_fman.h"
109932 +#include "fm_port_ext.h"
109933 +#if (DPAA_VERSION >= 11)
109934 +#include "fm_vsp_ext.h"
109935 +#endif /* DPAA_VERSION >= 11 */
109936 +#include "fm_ioctls.h"
109937 +#include "lnxwrp_resources.h"
109938 +#include "lnxwrp_sysfs_fm_port.h"
109939 +
109940 +#define __ERR_MODULE__ MODULE_FM
109941 +
109942 +extern struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx);
109943 +
109944 +/* TODO: duplicated, see lnxwrp_fm.c */
109945 +#define ADD_ADV_CONFIG_NO_RET(_func, _param)\
109946 +do {\
109947 + if (i < max) {\
109948 + p_Entry = &p_Entrys[i];\
109949 + p_Entry->p_Function = _func;\
109950 + _param\
109951 + i++;\
109952 + } else {\
109953 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
109954 + ("Number of advanced-configuration entries exceeded"));\
109955 + } \
109956 +} while (0)
109957 +
109958 +#ifndef CONFIG_FMAN_ARM
109959 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
109960 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
109961 +#endif
109962 +
109963 +static volatile int hcFrmRcv/* = 0 */;
109964 +static spinlock_t lock;
109965 +
109966 +static enum qman_cb_dqrr_result qm_tx_conf_dqrr_cb(struct qman_portal *portal,
109967 + struct qman_fq *fq,
109968 + const struct qm_dqrr_entry
109969 + *dq)
109970 +{
109971 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_FmTestFq *) fq)->h_Arg;
109972 + unsigned long flags;
109973 +
109974 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
109975 +{
109976 + /* extract the HC frame address */
109977 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *)&dq->fd));
109978 + int hcf_l = ((struct qm_fd *)&dq->fd)->length20;
109979 + int i;
109980 +
109981 + /* 32b byteswap of all data in the HC Frame */
109982 + for(i = 0; i < hcf_l / 4; ++i)
109983 + hcf_va[i] =
109984 + ___constant_swab32(hcf_va[i]);
109985 +}
109986 +#endif
109987 + FM_PCD_HcTxConf(p_LnxWrpFmDev->h_PcdDev, (t_DpaaFD *)&dq->fd);
109988 + spin_lock_irqsave(&lock, flags);
109989 + hcFrmRcv--;
109990 + spin_unlock_irqrestore(&lock, flags);
109991 +
109992 + return qman_cb_dqrr_consume;
109993 +}
109994 +
109995 +static enum qman_cb_dqrr_result qm_tx_dqrr_cb(struct qman_portal *portal,
109996 + struct qman_fq *fq,
109997 + const struct qm_dqrr_entry *dq)
109998 +{
109999 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
110000 + __func__);
110001 + return qman_cb_dqrr_consume;
110002 +}
110003 +
110004 +static void qm_err_cb(struct qman_portal *portal,
110005 + struct qman_fq *fq, const struct qm_mr_entry *msg)
110006 +{
110007 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
110008 + __func__);
110009 +}
110010 +
110011 +static struct qman_fq *FqAlloc(t_LnxWrpFmDev * p_LnxWrpFmDev,
110012 + uint32_t fqid,
110013 + uint32_t flags, uint16_t channel, uint8_t wq)
110014 +{
110015 + int _errno;
110016 + struct qman_fq *fq = NULL;
110017 + t_FmTestFq *p_FmtFq;
110018 + struct qm_mcc_initfq initfq;
110019 +
110020 + p_FmtFq = (t_FmTestFq *) XX_Malloc(sizeof(t_FmTestFq));
110021 + if (!p_FmtFq) {
110022 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
110023 + return NULL;
110024 + }
110025 +
110026 + p_FmtFq->fq_base.cb.dqrr = ((flags & QMAN_FQ_FLAG_NO_ENQUEUE)
110027 + ? qm_tx_conf_dqrr_cb
110028 + : qm_tx_dqrr_cb);
110029 + p_FmtFq->fq_base.cb.ern = qm_err_cb;
110030 + /* p_FmtFq->fq_base.cb.fqs = qm_err_cb; */
110031 + /* qm_err_cb wrongly called when the FQ is parked */
110032 + p_FmtFq->fq_base.cb.fqs = NULL;
110033 + p_FmtFq->h_Arg = (t_Handle) p_LnxWrpFmDev;
110034 + if (fqid == 0) {
110035 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
110036 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
110037 + } else {
110038 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
110039 + }
110040 +
110041 + if (qman_create_fq(fqid, flags, &p_FmtFq->fq_base)) {
110042 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj - qman_new_fq!!!"));
110043 + XX_Free(p_FmtFq);
110044 + return NULL;
110045 + }
110046 + fq = &p_FmtFq->fq_base;
110047 +
110048 + if (!(flags & QMAN_FQ_FLAG_NO_MODIFY)) {
110049 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
110050 + initfq.fqd.dest.channel = channel;
110051 + initfq.fqd.dest.wq = wq;
110052 +
110053 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
110054 + if (unlikely(_errno < 0)) {
110055 + REPORT_ERROR(MAJOR, E_NO_MEMORY,
110056 + ("FQ obj - qman_init_fq!!!"));
110057 + qman_destroy_fq(fq, 0);
110058 + XX_Free(p_FmtFq);
110059 + return NULL;
110060 + }
110061 + }
110062 +
110063 + DBG(TRACE,
110064 + ("fqid %d, flags 0x%08x, channel %d, wq %d", qman_fq_fqid(fq),
110065 + flags, channel, wq));
110066 +
110067 + return fq;
110068 +}
110069 +
110070 +static void FqFree(struct qman_fq *fq)
110071 +{
110072 + int _errno;
110073 +
110074 + _errno = qman_retire_fq(fq, NULL);
110075 + if (unlikely(_errno < 0))
110076 + printk(KERN_WARNING "qman_retire_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
110077 +
110078 + _errno = qman_oos_fq(fq);
110079 + if (unlikely(_errno < 0))
110080 + printk(KERN_WARNING "qman_oos_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
110081 +
110082 + qman_destroy_fq(fq, 0);
110083 + XX_Free((t_FmTestFq *) fq);
110084 +}
110085 +
110086 +static t_Error QmEnqueueCB(t_Handle h_Arg, void *p_Fd)
110087 +{
110088 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_Arg;
110089 + int _errno, timeout = 1000000;
110090 + unsigned long flags;
110091 +
110092 + ASSERT_COND(p_LnxWrpFmDev);
110093 +
110094 + spin_lock_irqsave(&lock, flags);
110095 + hcFrmRcv++;
110096 + spin_unlock_irqrestore(&lock, flags);
110097 +
110098 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
110099 +{
110100 + /* extract the HC frame address */
110101 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *) p_Fd));
110102 + int hcf_l = ((struct qm_fd *)p_Fd)->length20;
110103 + int i;
110104 +
110105 + /* 32b byteswap of all data in the HC Frame */
110106 + for(i = 0; i < hcf_l / 4; ++i)
110107 + hcf_va[i] =
110108 + ___constant_swab32(hcf_va[i]);
110109 +}
110110 +#endif
110111 +
110112 + _errno = qman_enqueue(p_LnxWrpFmDev->hc_tx_fq, (struct qm_fd *) p_Fd,
110113 + 0);
110114 + if (_errno)
110115 + RETURN_ERROR(MINOR, E_INVALID_STATE,
110116 + ("qman_enqueue() failed"));
110117 +
110118 + while (hcFrmRcv && --timeout) {
110119 + udelay(1);
110120 + cpu_relax();
110121 + }
110122 + if (timeout == 0) {
110123 + dump_stack();
110124 + RETURN_ERROR(MINOR, E_WRITE_FAILED,
110125 + ("timeout waiting for Tx confirmation"));
110126 + return E_WRITE_FAILED;
110127 + }
110128 +
110129 + return E_OK;
110130 +}
110131 +
110132 +static t_LnxWrpFmPortDev *ReadFmPortDevTreeNode(struct platform_device
110133 + *of_dev)
110134 +{
110135 + t_LnxWrpFmDev *p_LnxWrpFmDev;
110136 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
110137 + struct device_node *fm_node, *port_node;
110138 + struct resource res;
110139 + const uint32_t *uint32_prop;
110140 + int _errno = 0, lenp;
110141 + uint32_t tmp_prop;
110142 +
110143 +#ifdef CONFIG_FMAN_P1023
110144 + static unsigned char have_oh_port/* = 0 */;
110145 +#endif
110146 +
110147 + port_node = of_node_get(of_dev->dev.of_node);
110148 +
110149 + /* Get the FM node */
110150 + fm_node = of_get_parent(port_node);
110151 + if (unlikely(fm_node == NULL)) {
110152 + REPORT_ERROR(MAJOR, E_NO_DEVICE,
110153 + ("of_get_parent() = %d", _errno));
110154 + return NULL;
110155 + }
110156 +
110157 + p_LnxWrpFmDev =
110158 + dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
110159 + of_node_put(fm_node);
110160 +
110161 + /* if fm_probe() failed, no point in going further with port probing */
110162 + if (p_LnxWrpFmDev == NULL)
110163 + return NULL;
110164 +
110165 + uint32_prop =
110166 + (uint32_t *) of_get_property(port_node, "cell-index", &lenp);
110167 + if (unlikely(uint32_prop == NULL)) {
110168 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110169 + ("of_get_property(%s, cell-index) failed",
110170 + port_node->full_name));
110171 + return NULL;
110172 + }
110173 + tmp_prop = be32_to_cpu(*uint32_prop);
110174 + if (WARN_ON(lenp != sizeof(uint32_t)))
110175 + return NULL;
110176 + if (of_device_is_compatible(port_node, "fsl,fman-port-oh")) {
110177 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) {
110178 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110179 + ("of_get_property(%s, cell-index) failed",
110180 + port_node->full_name));
110181 + return NULL;
110182 + }
110183 +
110184 +#ifdef CONFIG_FMAN_P1023
110185 + /* Beware, this can be done when there is only
110186 + one FMan to be initialized */
110187 + if (!have_oh_port) {
110188 + have_oh_port = 1; /* first OP/HC port
110189 + is used for host command */
110190 +#else
110191 + /* Here it is hardcoded the use of the OH port 1
110192 + (with cell-index 0) */
110193 + if (tmp_prop == 0) {
110194 +#endif
110195 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
110196 + p_LnxWrpFmPortDev->id = 0;
110197 + /*
110198 + p_LnxWrpFmPortDev->id = *uint32_prop-1;
110199 + p_LnxWrpFmPortDev->id = *uint32_prop;
110200 + */
110201 + p_LnxWrpFmPortDev->settings.param.portType =
110202 + e_FM_PORT_TYPE_OH_HOST_COMMAND;
110203 + } else {
110204 + p_LnxWrpFmPortDev =
110205 + &p_LnxWrpFmDev->opPorts[tmp_prop - 1];
110206 + p_LnxWrpFmPortDev->id = tmp_prop- 1;
110207 + p_LnxWrpFmPortDev->settings.param.portType =
110208 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
110209 + }
110210 + p_LnxWrpFmPortDev->settings.param.portId = tmp_prop;
110211 +
110212 + uint32_prop =
110213 + (uint32_t *) of_get_property(port_node,
110214 + "fsl,qman-channel-id",
110215 + &lenp);
110216 + if (uint32_prop == NULL) {
110217 + /*
110218 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("missing fsl,qman-channel-id"));
110219 + */
110220 + XX_Print("FM warning: missing fsl,qman-channel-id"
110221 + " for OH port.\n");
110222 + return NULL;
110223 + }
110224 + tmp_prop = be32_to_cpu(*uint32_prop);
110225 + if (WARN_ON(lenp != sizeof(uint32_t)))
110226 + return NULL;
110227 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110228 +
110229 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110230 + qmChannel = p_LnxWrpFmPortDev->txCh;
110231 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-tx")) {
110232 + tmp_prop -= 0x28;
110233 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_TX_PORTS)) {
110234 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110235 + ("of_get_property(%s, cell-index) failed",
110236 + port_node->full_name));
110237 + return NULL;
110238 + }
110239 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
110240 +
110241 + p_LnxWrpFmPortDev->id = tmp_prop;
110242 + p_LnxWrpFmPortDev->settings.param.portId =
110243 + p_LnxWrpFmPortDev->id;
110244 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_TX;
110245 +
110246 + uint32_prop = (uint32_t *) of_get_property(port_node,
110247 + "fsl,qman-channel-id", &lenp);
110248 + if (uint32_prop == NULL) {
110249 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110250 + ("missing fsl,qman-channel-id"));
110251 + return NULL;
110252 + }
110253 + tmp_prop = be32_to_cpu(*uint32_prop);
110254 + if (WARN_ON(lenp != sizeof(uint32_t)))
110255 + return NULL;
110256 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110257 + p_LnxWrpFmPortDev->
110258 + settings.param.specificParams.nonRxParams.qmChannel =
110259 + p_LnxWrpFmPortDev->txCh;
110260 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) {
110261 + tmp_prop -= 0x30;
110262 + if (unlikely(tmp_prop>= FM_MAX_NUM_OF_10G_TX_PORTS)) {
110263 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110264 + ("of_get_property(%s, cell-index) failed",
110265 + port_node->full_name));
110266 + return NULL;
110267 + }
110268 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop +
110269 + FM_MAX_NUM_OF_1G_TX_PORTS];
110270 +#ifndef CONFIG_FMAN_ARM
110271 + if (IS_T1023_T1024)
110272 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[*uint32_prop];
110273 +#endif
110274 +
110275 + p_LnxWrpFmPortDev->id = tmp_prop;
110276 + p_LnxWrpFmPortDev->settings.param.portId =
110277 + p_LnxWrpFmPortDev->id;
110278 + p_LnxWrpFmPortDev->settings.param.portType =
110279 + e_FM_PORT_TYPE_TX_10G;
110280 + uint32_prop = (uint32_t *) of_get_property(port_node,
110281 + "fsl,qman-channel-id", &lenp);
110282 + if (uint32_prop == NULL) {
110283 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110284 + ("missing fsl,qman-channel-id"));
110285 + return NULL;
110286 + }
110287 + tmp_prop = be32_to_cpu(*uint32_prop);
110288 + if (WARN_ON(lenp != sizeof(uint32_t)))
110289 + return NULL;
110290 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110291 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110292 + qmChannel = p_LnxWrpFmPortDev->txCh;
110293 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-rx")) {
110294 + tmp_prop -= 0x08;
110295 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_RX_PORTS)) {
110296 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110297 + ("of_get_property(%s, cell-index) failed",
110298 + port_node->full_name));
110299 + return NULL;
110300 + }
110301 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
110302 +
110303 + p_LnxWrpFmPortDev->id = tmp_prop;
110304 + p_LnxWrpFmPortDev->settings.param.portId =
110305 + p_LnxWrpFmPortDev->id;
110306 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_RX;
110307 + if (p_LnxWrpFmDev->pcdActive)
110308 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110309 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-rx")) {
110310 + tmp_prop -= 0x10;
110311 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_10G_RX_PORTS)) {
110312 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110313 + ("of_get_property(%s, cell-index) failed",
110314 + port_node->full_name));
110315 + return NULL;
110316 + }
110317 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop +
110318 + FM_MAX_NUM_OF_1G_RX_PORTS];
110319 +
110320 +#ifndef CONFIG_FMAN_ARM
110321 + if (IS_T1023_T1024)
110322 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[*uint32_prop];
110323 +#endif
110324 +
110325 + p_LnxWrpFmPortDev->id = tmp_prop;
110326 + p_LnxWrpFmPortDev->settings.param.portId =
110327 + p_LnxWrpFmPortDev->id;
110328 + p_LnxWrpFmPortDev->settings.param.portType =
110329 + e_FM_PORT_TYPE_RX_10G;
110330 + if (p_LnxWrpFmDev->pcdActive)
110331 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110332 + } else {
110333 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
110334 + return NULL;
110335 + }
110336 +
110337 + _errno = of_address_to_resource(port_node, 0, &res);
110338 + if (unlikely(_errno < 0)) {
110339 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110340 + ("of_address_to_resource() = %d", _errno));
110341 + return NULL;
110342 + }
110343 +
110344 + p_LnxWrpFmPortDev->dev = &of_dev->dev;
110345 + p_LnxWrpFmPortDev->baseAddr = 0;
110346 + p_LnxWrpFmPortDev->phys_baseAddr = res.start;
110347 + p_LnxWrpFmPortDev->memSize = res.end + 1 - res.start;
110348 + p_LnxWrpFmPortDev->settings.param.h_Fm = p_LnxWrpFmDev->h_Dev;
110349 + p_LnxWrpFmPortDev->h_LnxWrpFmDev = (t_Handle) p_LnxWrpFmDev;
110350 +
110351 + of_node_put(port_node);
110352 +
110353 + p_LnxWrpFmPortDev->active = TRUE;
110354 +
110355 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
110356 + /* for performance mode no OH port available. */
110357 + if (p_LnxWrpFmPortDev->settings.param.portType ==
110358 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
110359 + p_LnxWrpFmPortDev->active = FALSE;
110360 +#endif
110361 +
110362 + return p_LnxWrpFmPortDev;
110363 +}
110364 +
110365 +struct device_node * GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
110366 + e_FmPortType portType,
110367 + uint8_t portId)
110368 +{
110369 + struct device_node *port_node;
110370 + const uint32_t *uint32_prop;
110371 + int lenp;
110372 + char *portTypeString;
110373 + uint32_t tmp_prop;
110374 +
110375 + switch(portType) {
110376 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
110377 + portTypeString = "fsl,fman-port-op-extended-args";
110378 + break;
110379 + case e_FM_PORT_TYPE_TX:
110380 + portTypeString = "fsl,fman-port-1g-tx-extended-args";
110381 + break;
110382 + case e_FM_PORT_TYPE_TX_10G:
110383 + portTypeString = "fsl,fman-port-10g-tx-extended-args";
110384 + break;
110385 + case e_FM_PORT_TYPE_RX:
110386 + portTypeString = "fsl,fman-port-1g-rx-extended-args";
110387 + break;
110388 + case e_FM_PORT_TYPE_RX_10G:
110389 + portTypeString = "fsl,fman-port-10g-rx-extended-args";
110390 + break;
110391 + default:
110392 + return NULL;
110393 + }
110394 +
110395 + for_each_child_of_node(fm_node, port_node) {
110396 + uint32_prop = (uint32_t *)of_get_property(port_node, "cell-index", &lenp);
110397 + if (unlikely(uint32_prop == NULL)) {
110398 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110399 + ("of_get_property(%s, cell-index) failed",
110400 + port_node->full_name));
110401 + return NULL;
110402 + }
110403 + tmp_prop = be32_to_cpu(*uint32_prop);
110404 + if (WARN_ON(lenp != sizeof(uint32_t)))
110405 + return NULL;
110406 + if ((portId == tmp_prop) &&
110407 + (of_device_is_compatible(port_node, portTypeString))) {
110408 + return port_node;
110409 + }
110410 + }
110411 +
110412 + return NULL;
110413 +}
110414 +
110415 +static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110416 +{
110417 + struct device_node *fm_node, *port_node;
110418 + t_Error err;
110419 + t_FmPortRsrc portRsrc;
110420 + const uint32_t *uint32_prop;
110421 + /*const char *str_prop;*/
110422 + int lenp;
110423 +#ifdef CONFIG_FMAN_PFC
110424 + uint8_t i, id, num_pools;
110425 + t_FmBufPoolDepletion poolDepletion;
110426 +
110427 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
110428 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) {
110429 + memset(&poolDepletion, 0, sizeof(t_FmBufPoolDepletion));
110430 + poolDepletion.singlePoolModeEnable = true;
110431 + num_pools = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110432 + extBufPools.numOfPoolsUsed;
110433 + for (i = 0; i < num_pools; i++) {
110434 + id = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110435 + extBufPools.extBufPool[i].id;
110436 + poolDepletion.poolsToConsiderForSingleMode[id] = true;
110437 + }
110438 +
110439 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++)
110440 + poolDepletion.pfcPrioritiesEn[i] = true;
110441 +
110442 + err = FM_PORT_ConfigPoolDepletion(p_LnxWrpFmPortDev->h_Dev,
110443 + &poolDepletion);
110444 + if (err != E_OK)
110445 + RETURN_ERROR(MAJOR, err, ("FM_PORT_ConfigPoolDepletion() failed"));
110446 + }
110447 +#endif
110448 +
110449 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
110450 + if (!fm_node) /* no advance parameters for FMan */
110451 + return E_OK;
110452 +
110453 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
110454 + p_LnxWrpFmPortDev->settings.param.portType,
110455 + p_LnxWrpFmPortDev->settings.param.portId);
110456 + if (!port_node) /* no advance parameters for FMan-Port */
110457 + return E_OK;
110458 +
110459 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-tnums", &lenp);
110460 + if (uint32_prop) {
110461 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110462 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110463 +
110464 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110465 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110466 +
110467 + if ((err = FM_PORT_ConfigNumOfTasks(p_LnxWrpFmPortDev->h_Dev,
110468 + &portRsrc)) != E_OK)
110469 + RETURN_ERROR(MINOR, err, NO_MSG);
110470 + }
110471 +
110472 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-dmas", &lenp);
110473 + if (uint32_prop) {
110474 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110475 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110476 +
110477 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110478 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110479 +
110480 + if ((err = FM_PORT_ConfigNumOfOpenDmas(p_LnxWrpFmPortDev->h_Dev,
110481 + &portRsrc)) != E_OK)
110482 + RETURN_ERROR(MINOR, err, NO_MSG);
110483 + }
110484 +
110485 + uint32_prop = (uint32_t *)of_get_property(port_node, "fifo-size", &lenp);
110486 + if (uint32_prop) {
110487 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110488 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110489 +
110490 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110491 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110492 +
110493 + if ((err = FM_PORT_ConfigSizeOfFifo(p_LnxWrpFmPortDev->h_Dev,
110494 + &portRsrc)) != E_OK)
110495 + RETURN_ERROR(MINOR, err, NO_MSG);
110496 + }
110497 +
110498 + uint32_prop = (uint32_t *)of_get_property(port_node, "errors-to-discard", &lenp);
110499 + if (uint32_prop) {
110500 + if (WARN_ON(lenp != sizeof(uint32_t)))
110501 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110502 + if ((err = FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev,
110503 + be32_to_cpu(uint32_prop[0]))) != E_OK)
110504 + RETURN_ERROR(MINOR, err, NO_MSG);
110505 + }
110506 +
110507 + uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes",
110508 + &lenp);
110509 + if (uint32_prop) {
110510 +
110511 + if (WARN_ON(lenp != sizeof(uint32_t)*8))
110512 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110513 + if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType !=
110514 + e_FM_PORT_TYPE_RX) &&
110515 + (p_LnxWrpFmPortDev->settings.param.portType !=
110516 + e_FM_PORT_TYPE_RX_10G))
110517 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
110518 + ("Auto Response is an Rx port atribute."));
110519 +
110520 + memset(&p_LnxWrpFmPortDev->dsar_table_sizes, 0, sizeof(struct auto_res_tables_sizes));
110521 +
110522 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_arp_entries =
110523 + (uint16_t)be32_to_cpu(uint32_prop[0]);
110524 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv4_entries =
110525 + (uint16_t)be32_to_cpu(uint32_prop[1]);
110526 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ndp_entries =
110527 + (uint16_t)be32_to_cpu(uint32_prop[2]);
110528 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv6_entries =
110529 + (uint16_t)be32_to_cpu(uint32_prop[3]);
110530 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv4_entries =
110531 + (uint16_t)be32_to_cpu(uint32_prop[4]);
110532 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv6_entries =
110533 + (uint16_t)be32_to_cpu(uint32_prop[5]);
110534 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_oid_entries =
110535 + (uint16_t)be32_to_cpu(uint32_prop[6]);
110536 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_char =
110537 + (uint16_t)be32_to_cpu(uint32_prop[7]);
110538 +
110539 + uint32_prop = (uint32_t *)of_get_property(port_node,
110540 + "ar-filters-sizes", &lenp);
110541 + if (uint32_prop) {
110542 + if (WARN_ON(lenp != sizeof(uint32_t)*3))
110543 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110544 +
110545 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering =
110546 + (uint16_t)be32_to_cpu(uint32_prop[0]);
110547 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering =
110548 + (uint16_t)be32_to_cpu(uint32_prop[1]);
110549 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering =
110550 + (uint16_t)be32_to_cpu(uint32_prop[2]);
110551 + }
110552 +
110553 + if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev,
110554 + (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK)
110555 + RETURN_ERROR(MINOR, err, NO_MSG);
110556 + }
110557 +
110558 + of_node_put(port_node);
110559 + of_node_put(fm_node);
110560 +
110561 + return E_OK;
110562 +}
110563 +
110564 +static t_Error CheckNSetFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110565 +{
110566 + struct device_node *fm_node, *port_node;
110567 + t_Error err;
110568 + const uint32_t *uint32_prop;
110569 + /*const char *str_prop;*/
110570 + int lenp;
110571 +
110572 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
110573 + if (!fm_node) /* no advance parameters for FMan */
110574 + return E_OK;
110575 +
110576 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
110577 + p_LnxWrpFmPortDev->settings.param.portType,
110578 + p_LnxWrpFmPortDev->settings.param.portId);
110579 + if (!port_node) /* no advance parameters for FMan-Port */
110580 + return E_OK;
110581 +
110582 +#if (DPAA_VERSION >= 11)
110583 + uint32_prop = (uint32_t *)of_get_property(port_node, "vsp-window", &lenp);
110584 + if (uint32_prop) {
110585 + t_FmPortVSPAllocParams portVSPAllocParams;
110586 + t_FmVspParams fmVspParams;
110587 + t_LnxWrpFmDev *p_LnxWrpFmDev;
110588 + uint8_t portId;
110589 +
110590 + p_LnxWrpFmDev = ((t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev);
110591 +
110592 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110593 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110594 +
110595 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) ||
110596 + (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX_10G) ||
110597 + ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110598 + p_LnxWrpFmPortDev->settings.frag_enabled))
110599 + return E_OK;
110600 +
110601 + memset(&portVSPAllocParams, 0, sizeof(portVSPAllocParams));
110602 + memset(&fmVspParams, 0, sizeof(fmVspParams));
110603 +
110604 + portVSPAllocParams.numOfProfiles = (uint8_t)be32_to_cpu(uint32_prop[0]);
110605 + portVSPAllocParams.dfltRelativeId = (uint8_t)be32_to_cpu(uint32_prop[1]);
110606 + fmVspParams.h_Fm = p_LnxWrpFmDev->h_Dev;
110607 +
110608 + fmVspParams.portParams.portType = p_LnxWrpFmPortDev->settings.param.portType;
110609 + fmVspParams.portParams.portId = p_LnxWrpFmPortDev->settings.param.portId;
110610 + fmVspParams.relativeProfileId = portVSPAllocParams.dfltRelativeId;
110611 +
110612 + if (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
110613 + {
110614 + portId = fmVspParams.portParams.portId;
110615 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G){
110616 +#ifndef CONFIG_FMAN_ARM
110617 + if (!(IS_T1023_T1024))
110618 +#endif
110619 + portId += FM_MAX_NUM_OF_1G_RX_PORTS;
110620 + }
110621 + portVSPAllocParams.h_FmTxPort =
110622 + p_LnxWrpFmDev->txPorts[portId].h_Dev;
110623 + fmVspParams.liodnOffset =
110624 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
110625 + memcpy(&fmVspParams.extBufPools,
110626 + &p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools,
110627 + sizeof(t_FmExtPools));
110628 + }
110629 + else
110630 + {
110631 + memcpy(&fmVspParams.extBufPools,
110632 + &p_LnxWrpFmPortDev->opExtPools,
110633 + sizeof(t_FmExtPools));
110634 + }
110635 +
110636 + if ((err = FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev,
110637 + &portVSPAllocParams)) != E_OK)
110638 + RETURN_ERROR(MINOR, err, NO_MSG);
110639 +
110640 + /* We're initializing only the default VSP that are being used by the Linux-Ethernet-driver */
110641 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110642 + !p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed)
110643 + return E_OK;
110644 +
110645 + p_LnxWrpFmPortDev->h_DfltVsp = FM_VSP_Config(&fmVspParams);
110646 + if (!p_LnxWrpFmPortDev->h_DfltVsp)
110647 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("default-VSP for port!"));
110648 +
110649 + if ((err = FM_VSP_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_DfltVsp,
110650 + &p_LnxWrpFmPortDev->buffPrefixContent)) != E_OK)
110651 + RETURN_ERROR(MINOR, err, NO_MSG);
110652 +
110653 + if ((err = FM_VSP_Init(p_LnxWrpFmPortDev->h_DfltVsp)) != E_OK)
110654 + RETURN_ERROR(MINOR, err, NO_MSG);
110655 + }
110656 +#else
110657 +UNUSED(err); UNUSED(uint32_prop); UNUSED(lenp);
110658 +#endif /* (DPAA_VERSION >= 11) */
110659 +
110660 + of_node_put(port_node);
110661 + of_node_put(fm_node);
110662 +
110663 + return E_OK;
110664 +}
110665 +
110666 +static t_Error ConfigureFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110667 +{
110668 + t_LnxWrpFmDev *p_LnxWrpFmDev =
110669 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
110670 + struct resource *dev_res;
110671 +
110672 + if (!p_LnxWrpFmPortDev->active)
110673 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
110674 + ("FM port not configured!!!"));
110675 +
110676 + dev_res =
110677 + __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
110678 + p_LnxWrpFmPortDev->phys_baseAddr,
110679 + p_LnxWrpFmPortDev->memSize,
110680 + "fman-port-hc");
110681 + if (unlikely(dev_res == NULL))
110682 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
110683 + ("__devm_request_region() failed"));
110684 + p_LnxWrpFmPortDev->baseAddr =
110685 + PTR_TO_UINT(devm_ioremap
110686 + (p_LnxWrpFmDev->dev,
110687 + p_LnxWrpFmPortDev->phys_baseAddr,
110688 + p_LnxWrpFmPortDev->memSize));
110689 + if (unlikely(p_LnxWrpFmPortDev->baseAddr == 0))
110690 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
110691 + ("devm_ioremap() failed"));
110692 +
110693 + p_LnxWrpFmPortDev->settings.param.baseAddr =
110694 + p_LnxWrpFmPortDev->baseAddr;
110695 +
110696 + return E_OK;
110697 +}
110698 +
110699 +static t_Error InitFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110700 +{
110701 +#define MY_ADV_CONFIG_CHECK_END \
110702 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,\
110703 + ("Advanced configuration routine"));\
110704 + if (errCode != E_OK)\
110705 + RETURN_ERROR(MAJOR, errCode, NO_MSG);\
110706 + }
110707 +
110708 + int i = 0;
110709 +
110710 + if (!p_LnxWrpFmPortDev->active || p_LnxWrpFmPortDev->h_Dev)
110711 + return E_INVALID_STATE;
110712 +
110713 + p_LnxWrpFmPortDev->h_Dev =
110714 + FM_PORT_Config(&p_LnxWrpFmPortDev->settings.param);
110715 + if (p_LnxWrpFmPortDev->h_Dev == NULL)
110716 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-port"));
110717 +
110718 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
110719 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110720 + e_FM_PORT_TYPE_TX_10G)
110721 + || (p_LnxWrpFmPortDev->settings.param.portType ==
110722 + e_FM_PORT_TYPE_TX)) {
110723 + t_Error errCode = E_OK;
110724 + errCode =
110725 + FM_PORT_ConfigDeqHighPriority(p_LnxWrpFmPortDev->h_Dev,
110726 + TRUE);
110727 + if (errCode != E_OK)
110728 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
110729 + errCode =
110730 + FM_PORT_ConfigDeqPrefetchOption(p_LnxWrpFmPortDev->h_Dev,
110731 + e_FM_PORT_DEQ_FULL_PREFETCH);
110732 + if (errCode
110733 + != E_OK)
110734 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
110735 + }
110736 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
110737 +
110738 +#ifndef CONFIG_FMAN_ARM
110739 +#ifdef FM_BCB_ERRATA_BMI_SW001
110740 +/* Configure BCB workaround on Rx ports, only for B4860 rev1 */
110741 +#define SVR_SECURITY_MASK 0x00080000
110742 +#define SVR_PERSONALITY_MASK 0x0000FF00
110743 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
110744 +#define SVR_B4860_REV1_VALUE 0x86800010
110745 +
110746 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110747 + e_FM_PORT_TYPE_RX_10G) ||
110748 + (p_LnxWrpFmPortDev->settings.param.portType ==
110749 + e_FM_PORT_TYPE_RX)) {
110750 + unsigned int svr;
110751 +
110752 + svr = mfspr(SPRN_SVR);
110753 +
110754 + if ((svr & ~SVR_VER_IGNORE_MASK) == SVR_B4860_REV1_VALUE)
110755 + FM_PORT_ConfigBCBWorkaround(p_LnxWrpFmPortDev->h_Dev);
110756 + }
110757 +#endif /* FM_BCB_ERRATA_BMI_SW001 */
110758 +#endif /* CONFIG_FMAN_ARM */
110759 +/* Call the driver's advanced configuration routines, if requested:
110760 + Compare the function pointer of each entry to the available routines,
110761 + and invoke the matching routine with proper casting of arguments. */
110762 + while (p_LnxWrpFmPortDev->settings.advConfig[i].p_Function
110763 + && (i < FM_MAX_NUM_OF_ADV_SETTINGS)) {
110764 +
110765 +/* TODO: Change this MACRO */
110766 + ADV_CONFIG_CHECK_START(
110767 + &(p_LnxWrpFmPortDev->settings.advConfig[i]))
110768 +
110769 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
110770 + FM_PORT_ConfigBufferPrefixContent,
110771 + NCSW_PARAMS(1,
110772 + (t_FmBufferPrefixContent *)))
110773 +
110774 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110775 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110776 + (p_LnxWrpFmPortDev->settings.frag_enabled == TRUE)) {
110777 +
110778 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
110779 + FM_PORT_ConfigExtBufPools,
110780 + NCSW_PARAMS(1, (t_FmExtPools *)))
110781 +
110782 + /* this define contains an else */
110783 + MY_ADV_CONFIG_CHECK_END
110784 + }
110785 +
110786 + /* Advance to next advanced configuration entry */
110787 + i++;
110788 + }
110789 +
110790 +
110791 + if ((p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX) &&
110792 + (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX_10G)) {
110793 + if (FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, (FM_PORT_FRM_ERR_IPRE |
110794 + FM_PORT_FRM_ERR_IPR_NCSP |
110795 + FM_PORT_FRM_ERR_CLS_DISCARD)) !=E_OK)
110796 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110797 + }
110798 +
110799 + if (CheckNConfigFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
110800 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110801 +
110802 + if (FM_PORT_Init(p_LnxWrpFmPortDev->h_Dev) != E_OK)
110803 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110804 +
110805 + if (CheckNSetFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
110806 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110807 +
110808 +/* FMan Fifo sizes behind the scene":
110809 + * Using the following formulae (*), under a set of simplifying assumptions (.):
110810 + * . all ports are configured in Normal Mode (rather than Independent Mode)
110811 + * . the DPAA Eth driver allocates buffers of size:
110812 + * . MAXFRM + NET_IP_ALIGN + DPA_PRIV_DATA_SIZE + DPA_PARSE_RESULTS_SIZE
110813 + * + DPA_HASH_RESULTS_SIZE, i.e.:
110814 + * MAXFRM + 2 + 16 + sizeof(t_FmPrsResult) + 16, i.e.:
110815 + * MAXFRM + 66
110816 + * . excessive buffer pools not accounted for
110817 + *
110818 + * * for Rx ports on P4080:
110819 + * . IFSZ = ceil(max(FMBM_EBMPI[PBS]) / 256) * 256 + 7 * 256
110820 + * . no internal frame offset (FMBM_RIM[FOF] == 0) - otherwise,
110821 + * add up to 256 to the above
110822 + *
110823 + * * for Rx ports on P1023:
110824 + * . IFSZ = ceil(second_largest(FMBM_EBMPI[PBS] / 256)) * 256 + 7 * 256,
110825 + * if at least 2 bpools are configured
110826 + * . IFSZ = 8 * 256, if only a single bpool is configured
110827 + *
110828 + * * for Tx ports:
110829 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256
110830 + * + FMBM_TFP[DPDE] * 256, i.e.:
110831 + * IFSZ = ceil(MAXFRM / 256) * 256 + 3 x 256 + FMBM_TFP[DPDE] * 256
110832 + *
110833 + * * for OH ports on P4080:
110834 + * . IFSZ = ceil(frame_size / 256) * 256 + 1 * 256 + FMBM_PP[MXT] * 256
110835 + * * for OH ports on P1023:
110836 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256 + FMBM_TFP[DPDE] * 256
110837 + * * for both P4080 and P1023:
110838 + * . (conservative decisions, assuming that BMI must bring the entire
110839 + * frame, not only the frame header)
110840 + * . no internal frame offset (FMBM_OIM[FOF] == 0) - otherwise,
110841 + * add up to 256 to the above
110842 + *
110843 + * . for P4080/P5020/P3041/P2040, DPDE is:
110844 + * > 0 or 1, for 1Gb ports, HW default: 0
110845 + * > 2..7 (recommended: 3..7) for 10Gb ports, HW default: 3
110846 + * . for P1023, DPDE should be 1
110847 + *
110848 + * . for P1023, MXT is in range (0..31)
110849 + * . for P4080, MXT is in range (0..63)
110850 + *
110851 + */
110852 +#if 0
110853 + if ((p_LnxWrpFmPortDev->defPcd != e_NO_PCD) &&
110854 + (InitFmPort3TupleDefPcd(p_LnxWrpFmPortDev) != E_OK))
110855 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110856 +#endif
110857 + return E_OK;
110858 +}
110859 +
110860 +void fm_set_rx_port_params(struct fm_port *port,
110861 + struct fm_port_params *params)
110862 +{
110863 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
110864 + int i;
110865 +
110866 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.errFqid =
110867 + params->errq;
110868 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.dfltFqid =
110869 + params->defq;
110870 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools.
110871 + numOfPoolsUsed = params->num_pools;
110872 + for (i = 0; i < params->num_pools; i++) {
110873 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110874 + extBufPools.extBufPool[i].id =
110875 + params->pool_param[i].id;
110876 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110877 + extBufPools.extBufPool[i].size =
110878 + params->pool_param[i].size;
110879 + }
110880 +
110881 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
110882 + params->priv_data_size;
110883 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
110884 + params->parse_results;
110885 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
110886 + params->hash_results;
110887 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
110888 + params->time_stamp;
110889 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
110890 + params->data_align;
110891 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
110892 + params->manip_extra_space;
110893 +
110894 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
110895 + FM_MAX_NUM_OF_ADV_SETTINGS)
110896 +
110897 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
110898 + ARGS(1,
110899 + (&p_LnxWrpFmPortDev->
110900 + buffPrefixContent)));
110901 +
110902 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
110903 +}
110904 +EXPORT_SYMBOL(fm_set_rx_port_params);
110905 +
110906 +/* this function is called from oh_probe as well, thus it contains oh port
110907 + * specific parameters (make sure everything is checked) */
110908 +void fm_set_tx_port_params(struct fm_port *port,
110909 + struct fm_port_params *params)
110910 +{
110911 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
110912 +
110913 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.errFqid =
110914 + params->errq;
110915 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110916 + dfltFqid = params->defq;
110917 +
110918 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
110919 + params->priv_data_size;
110920 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
110921 + params->parse_results;
110922 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
110923 + params->hash_results;
110924 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
110925 + params->time_stamp;
110926 + p_LnxWrpFmPortDev->settings.frag_enabled =
110927 + params->frag_enable;
110928 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
110929 + params->data_align;
110930 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
110931 + params->manip_extra_space;
110932 +
110933 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
110934 + FM_MAX_NUM_OF_ADV_SETTINGS)
110935 +
110936 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
110937 + ARGS(1,
110938 + (&p_LnxWrpFmPortDev->
110939 + buffPrefixContent)));
110940 +
110941 + /* oh port specific parameter (for fragmentation only) */
110942 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110943 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110944 + params->num_pools) {
110945 + int i;
110946 +
110947 + p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed = params->num_pools;
110948 + for (i = 0; i < params->num_pools; i++) {
110949 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].id = params->pool_param[i].id;
110950 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].size = params->pool_param[i].size;
110951 + }
110952 +
110953 + if (p_LnxWrpFmPortDev->settings.frag_enabled)
110954 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigExtBufPools,
110955 + ARGS(1, (&p_LnxWrpFmPortDev->opExtPools)));
110956 + }
110957 +
110958 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
110959 +}
110960 +EXPORT_SYMBOL(fm_set_tx_port_params);
110961 +
110962 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev,
110963 + t_Handle h_fm_mac,
110964 + int mac_id)
110965 +{
110966 + t_LnxWrpFmDev *p_lnx_wrp_fm_dev = (t_LnxWrpFmDev *)h_lnx_wrp_fm_dev;
110967 +
110968 + p_lnx_wrp_fm_dev->macs[mac_id].h_Dev = h_fm_mac;
110969 + p_lnx_wrp_fm_dev->macs[mac_id].h_LnxWrpFmDev = h_lnx_wrp_fm_dev;
110970 +}
110971 +EXPORT_SYMBOL(fm_mac_set_handle);
110972 +
110973 +static void LnxwrpFmPcdDevExceptionsCb(t_Handle h_App,
110974 + e_FmPcdExceptions exception)
110975 +{
110976 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
110977 +
110978 + ASSERT_COND(p_LnxWrpFmDev);
110979 +
110980 + DBG(INFO, ("got fm-pcd exception %d", exception));
110981 +
110982 + /* do nothing */
110983 + UNUSED(exception);
110984 +}
110985 +
110986 +static void LnxwrpFmPcdDevIndexedExceptionsCb(t_Handle h_App,
110987 + e_FmPcdExceptions exception,
110988 + uint16_t index)
110989 +{
110990 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
110991 +
110992 + ASSERT_COND(p_LnxWrpFmDev);
110993 +
110994 + DBG(INFO,
110995 + ("got fm-pcd-indexed exception %d, indx %d", exception, index));
110996 +
110997 + /* do nothing */
110998 + UNUSED(exception);
110999 + UNUSED(index);
111000 +}
111001 +
111002 +static t_Error InitFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
111003 +{
111004 + spin_lock_init(&lock);
111005 +
111006 + if (p_LnxWrpFmDev->pcdActive) {
111007 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
111008 + t_FmPcdParams fmPcdParams;
111009 + t_Error err;
111010 +
111011 + memset(&fmPcdParams, 0, sizeof(fmPcdParams));
111012 + fmPcdParams.h_Fm = p_LnxWrpFmDev->h_Dev;
111013 + fmPcdParams.prsSupport = p_LnxWrpFmDev->prsActive;
111014 + fmPcdParams.kgSupport = p_LnxWrpFmDev->kgActive;
111015 + fmPcdParams.plcrSupport = p_LnxWrpFmDev->plcrActive;
111016 + fmPcdParams.ccSupport = p_LnxWrpFmDev->ccActive;
111017 + fmPcdParams.numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
111018 +
111019 +#ifndef CONFIG_GUEST_PARTITION
111020 + fmPcdParams.f_Exception = LnxwrpFmPcdDevExceptionsCb;
111021 + if (fmPcdParams.kgSupport)
111022 + fmPcdParams.f_ExceptionId =
111023 + LnxwrpFmPcdDevIndexedExceptionsCb;
111024 + fmPcdParams.h_App = p_LnxWrpFmDev;
111025 +#endif /* !CONFIG_GUEST_PARTITION */
111026 +
111027 +#ifdef CONFIG_MULTI_PARTITION_SUPPORT
111028 + fmPcdParams.numOfSchemes = 0;
111029 + fmPcdParams.numOfClsPlanEntries = 0;
111030 + fmPcdParams.partitionId = 0;
111031 +#endif /* CONFIG_MULTI_PARTITION_SUPPORT */
111032 + fmPcdParams.useHostCommand = TRUE;
111033 +
111034 + p_LnxWrpFmDev->hc_tx_fq =
111035 + FqAlloc(p_LnxWrpFmDev,
111036 + 0,
111037 + QMAN_FQ_FLAG_TO_DCPORTAL,
111038 + p_LnxWrpFmPortDev->txCh, 0);
111039 + if (!p_LnxWrpFmDev->hc_tx_fq)
111040 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111041 + ("Frame queue allocation failed..."));
111042 +
111043 + p_LnxWrpFmDev->hc_tx_conf_fq =
111044 + FqAlloc(p_LnxWrpFmDev,
111045 + 0,
111046 + QMAN_FQ_FLAG_NO_ENQUEUE,
111047 + p_LnxWrpFmDev->hcCh, 1);
111048 + if (!p_LnxWrpFmDev->hc_tx_conf_fq)
111049 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111050 + ("Frame queue allocation failed..."));
111051 +
111052 + p_LnxWrpFmDev->hc_tx_err_fq =
111053 + FqAlloc(p_LnxWrpFmDev,
111054 + 0,
111055 + QMAN_FQ_FLAG_NO_ENQUEUE,
111056 + p_LnxWrpFmDev->hcCh, 2);
111057 + if (!p_LnxWrpFmDev->hc_tx_err_fq)
111058 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111059 + ("Frame queue allocation failed..."));
111060 +
111061 + fmPcdParams.hc.portBaseAddr = p_LnxWrpFmPortDev->baseAddr;
111062 + fmPcdParams.hc.portId =
111063 + p_LnxWrpFmPortDev->settings.param.portId;
111064 + fmPcdParams.hc.liodnBase =
111065 + p_LnxWrpFmPortDev->settings.param.liodnBase;
111066 + fmPcdParams.hc.errFqid =
111067 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_err_fq);
111068 + fmPcdParams.hc.confFqid =
111069 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_conf_fq);
111070 + fmPcdParams.hc.qmChannel = p_LnxWrpFmPortDev->txCh;
111071 + fmPcdParams.hc.f_QmEnqueue = QmEnqueueCB;
111072 + fmPcdParams.hc.h_QmArg = (t_Handle) p_LnxWrpFmDev;
111073 +
111074 + p_LnxWrpFmDev->h_PcdDev = FM_PCD_Config(&fmPcdParams);
111075 + if (!p_LnxWrpFmDev->h_PcdDev)
111076 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM PCD!"));
111077 +
111078 + err =
111079 + FM_PCD_ConfigPlcrNumOfSharedProfiles(p_LnxWrpFmDev->h_PcdDev,
111080 + LNXWRP_FM_NUM_OF_SHARED_PROFILES);
111081 + if (err != E_OK)
111082 + RETURN_ERROR(MAJOR, err, NO_MSG);
111083 +
111084 + err = FM_PCD_Init(p_LnxWrpFmDev->h_PcdDev);
111085 + if (err != E_OK)
111086 + RETURN_ERROR(MAJOR, err, NO_MSG);
111087 +
111088 + if (p_LnxWrpFmDev->err_irq == 0) {
111089 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111090 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC,
111091 + FALSE);
111092 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111093 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW,
111094 + FALSE);
111095 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111096 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,
111097 + FALSE);
111098 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111099 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC,
111100 + FALSE);
111101 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111102 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC,
111103 + FALSE);
111104 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111105 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE,
111106 + FALSE);
111107 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111108 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE,
111109 + FALSE);
111110 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111111 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC,
111112 + FALSE);
111113 + }
111114 + }
111115 +
111116 + return E_OK;
111117 +}
111118 +
111119 +void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
111120 +{
111121 +
111122 + if (p_LnxWrpFmDev->h_PcdDev)
111123 + FM_PCD_Free(p_LnxWrpFmDev->h_PcdDev);
111124 +
111125 + if (p_LnxWrpFmDev->hc_tx_err_fq)
111126 + FqFree(p_LnxWrpFmDev->hc_tx_err_fq);
111127 +
111128 + if (p_LnxWrpFmDev->hc_tx_conf_fq)
111129 + FqFree(p_LnxWrpFmDev->hc_tx_conf_fq);
111130 +
111131 + if (p_LnxWrpFmDev->hc_tx_fq)
111132 + FqFree(p_LnxWrpFmDev->hc_tx_fq);
111133 +}
111134 +
111135 +static void FreeFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111136 +{
111137 + t_LnxWrpFmDev *p_LnxWrpFmDev =
111138 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111139 +
111140 + if (!p_LnxWrpFmPortDev->active)
111141 + return;
111142 +
111143 + if (p_LnxWrpFmPortDev->h_Dev)
111144 + FM_PORT_Free(p_LnxWrpFmPortDev->h_Dev);
111145 +
111146 + devm_iounmap(p_LnxWrpFmDev->dev,
111147 + UINT_TO_PTR(p_LnxWrpFmPortDev->baseAddr));
111148 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
111149 + p_LnxWrpFmPortDev->phys_baseAddr,
111150 + p_LnxWrpFmPortDev->memSize);
111151 +}
111152 +
111153 +static int /*__devinit*/ fm_port_probe(struct platform_device *of_dev)
111154 +{
111155 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111156 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111157 + struct device *dev;
111158 +
111159 + dev = &of_dev->dev;
111160 +
111161 + p_LnxWrpFmPortDev = ReadFmPortDevTreeNode(of_dev);
111162 + if (p_LnxWrpFmPortDev == NULL)
111163 + return -EIO;
111164 + /* Port can be inactive, thus will not be probed:
111165 + - in performance mode, OH ports are disabled
111166 + ...
111167 + */
111168 + if (!p_LnxWrpFmPortDev->active)
111169 + return 0;
111170 +
111171 + if (ConfigureFmPortDev(p_LnxWrpFmPortDev) != E_OK)
111172 + return -EIO;
111173 +
111174 + dev_set_drvdata(dev, p_LnxWrpFmPortDev);
111175 +
111176 + if (p_LnxWrpFmPortDev->settings.param.portType ==
111177 + e_FM_PORT_TYPE_OH_HOST_COMMAND)
111178 + InitFmPcdDev((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev);
111179 +
111180 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111181 +
111182 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX) {
111183 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111184 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111185 + p_LnxWrpFmPortDev->minor =
111186 + p_LnxWrpFmPortDev->id + DEV_FM_RX_PORTS_MINOR_BASE;
111187 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111188 + e_FM_PORT_TYPE_RX_10G) {
111189 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111190 + p_LnxWrpFmDev->name,
111191 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS);
111192 + p_LnxWrpFmPortDev->minor =
111193 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS +
111194 + DEV_FM_RX_PORTS_MINOR_BASE;
111195 +#ifndef CONFIG_FMAN_ARM
111196 + if (IS_T1023_T1024) {
111197 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111198 + p_LnxWrpFmDev->name,
111199 + p_LnxWrpFmPortDev->id);
111200 + p_LnxWrpFmPortDev->minor =
111201 + p_LnxWrpFmPortDev->id +
111202 + DEV_FM_RX_PORTS_MINOR_BASE;
111203 + }
111204 +#endif
111205 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111206 + e_FM_PORT_TYPE_TX) {
111207 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111208 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111209 + p_LnxWrpFmPortDev->minor =
111210 + p_LnxWrpFmPortDev->id + DEV_FM_TX_PORTS_MINOR_BASE;
111211 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111212 + e_FM_PORT_TYPE_TX_10G) {
111213 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111214 + p_LnxWrpFmDev->name,
111215 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS);
111216 + p_LnxWrpFmPortDev->minor =
111217 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS +
111218 + DEV_FM_TX_PORTS_MINOR_BASE;
111219 +#ifndef CONFIG_FMAN_ARM
111220 + if (IS_T1023_T1024) {
111221 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111222 + p_LnxWrpFmDev->name,
111223 + p_LnxWrpFmPortDev->id);
111224 + p_LnxWrpFmPortDev->minor =
111225 + p_LnxWrpFmPortDev->id +
111226 + DEV_FM_TX_PORTS_MINOR_BASE;
111227 + }
111228 +#endif
111229 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111230 + e_FM_PORT_TYPE_OH_HOST_COMMAND) {
111231 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111232 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111233 + p_LnxWrpFmPortDev->minor =
111234 + p_LnxWrpFmPortDev->id + DEV_FM_OH_PORTS_MINOR_BASE;
111235 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111236 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
111237 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111238 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id + 1);
111239 + p_LnxWrpFmPortDev->minor =
111240 + p_LnxWrpFmPortDev->id + 1 +
111241 + DEV_FM_OH_PORTS_MINOR_BASE;
111242 + }
111243 +
111244 + device_create(p_LnxWrpFmDev->fm_class, NULL,
111245 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor),
111246 + NULL, p_LnxWrpFmPortDev->name);
111247 +
111248 + /* create sysfs entries for stats and regs */
111249 +
111250 + if (fm_port_sysfs_create(dev) != 0) {
111251 + FreeFmPortDev(p_LnxWrpFmPortDev);
111252 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
111253 + ("Unable to create sys entry - fm port!!!"));
111254 + return -EIO;
111255 + }
111256 +
111257 +#ifdef FM_TX_INVALID_ECC_ERRATA_10GMAC_A009
111258 + FM_DisableRamsEcc(p_LnxWrpFmDev->h_Dev);
111259 +#endif /* FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 */
111260 +
111261 + DBG(TRACE, ("%s probed", p_LnxWrpFmPortDev->name));
111262 +
111263 + return 0;
111264 +}
111265 +
111266 +static int fm_port_remove(struct platform_device *of_dev)
111267 +{
111268 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111269 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111270 + struct device *dev;
111271 +
111272 + dev = &of_dev->dev;
111273 + p_LnxWrpFmPortDev = dev_get_drvdata(dev);
111274 +
111275 + fm_port_sysfs_destroy(dev);
111276 +
111277 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111278 + device_destroy(p_LnxWrpFmDev->fm_class,
111279 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor));
111280 +
111281 + FreeFmPortDev(p_LnxWrpFmPortDev);
111282 +
111283 + dev_set_drvdata(dev, NULL);
111284 +
111285 + return 0;
111286 +}
111287 +
111288 +static const struct of_device_id fm_port_match[] = {
111289 + {
111290 + .compatible = "fsl,fman-port-oh"},
111291 + {
111292 + .compatible = "fsl,fman-port-1g-rx"},
111293 + {
111294 + .compatible = "fsl,fman-port-10g-rx"},
111295 + {
111296 + .compatible = "fsl,fman-port-1g-tx"},
111297 + {
111298 + .compatible = "fsl,fman-port-10g-tx"},
111299 + {}
111300 +};
111301 +
111302 +#ifndef MODULE
111303 +MODULE_DEVICE_TABLE(of, fm_port_match);
111304 +#endif /* !MODULE */
111305 +
111306 +static struct platform_driver fm_port_driver = {
111307 +
111308 + .driver = {
111309 + .name = "fsl-fman-port",
111310 + .of_match_table = fm_port_match,
111311 + .owner = THIS_MODULE,
111312 + },
111313 + .probe = fm_port_probe,
111314 + .remove = fm_port_remove
111315 +};
111316 +
111317 +
111318 +t_Error LNXWRP_FM_Port_Init(void)
111319 +{
111320 + /* Register to the DTB for basic FM port API */
111321 + if (platform_driver_register(&fm_port_driver))
111322 + return E_NO_DEVICE;
111323 +
111324 + return E_OK;
111325 +}
111326 +
111327 +void LNXWRP_FM_Port_Free(void)
111328 +{
111329 + platform_driver_unregister(&fm_port_driver);
111330 +}
111331 +
111332 +static int __init __cold fm_port_load(void)
111333 +{
111334 + if (LNXWRP_FM_Port_Init() != E_OK) {
111335 + printk(KERN_CRIT "Failed to init FM Ports wrapper!\n");
111336 + return -ENODEV;
111337 + }
111338 +
111339 + printk(KERN_CRIT "Freescale FM Ports module\n");
111340 +
111341 + return 0;
111342 +}
111343 +
111344 +static void __exit __cold fm_port_unload(void)
111345 +{
111346 + LNXWRP_FM_Port_Free();
111347 +}
111348 +
111349 +module_init(fm_port_load);
111350 +module_exit(fm_port_unload);
111351 --- /dev/null
111352 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
111353 @@ -0,0 +1,4854 @@
111354 +/*
111355 + * Copyright 2008-2012 Freescale Semiconductor Inc.
111356 + *
111357 + * Redistribution and use in source and binary forms, with or without
111358 + * modification, are permitted provided that the following conditions are met:
111359 + * * Redistributions of source code must retain the above copyright
111360 + * notice, this list of conditions and the following disclaimer.
111361 + * * Redistributions in binary form must reproduce the above copyright
111362 + * notice, this list of conditions and the following disclaimer in the
111363 + * documentation and/or other materials provided with the distribution.
111364 + * * Neither the name of Freescale Semiconductor nor the
111365 + * names of its contributors may be used to endorse or promote products
111366 + * derived from this software without specific prior written permission.
111367 + *
111368 + *
111369 + * ALTERNATIVELY, this software may be distributed under the terms of the
111370 + * GNU General Public License ("GPL") as published by the Free Software
111371 + * Foundation, either version 2 of that License or (at your option) any
111372 + * later version.
111373 + *
111374 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
111375 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
111376 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
111377 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
111378 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
111379 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
111380 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
111381 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
111382 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
111383 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111384 + */
111385 +
111386 +/*
111387 + @File lnxwrp_ioctls_fm.c
111388 + @Author Shlomi Gridish
111389 + @Description FM Linux wrapper functions.
111390 +*/
111391 +
111392 +/* Linux Headers ------------------- */
111393 +#include <linux/version.h>
111394 +
111395 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
111396 +#define MODVERSIONS
111397 +#endif
111398 +#ifdef MODVERSIONS
111399 +#include <config/modversions.h>
111400 +#endif /* MODVERSIONS */
111401 +
111402 +#include <linux/kernel.h>
111403 +#include <linux/module.h>
111404 +#include <linux/slab.h>
111405 +#include <linux/fs.h>
111406 +#include <linux/cdev.h>
111407 +#include <linux/device.h>
111408 +#include <linux/irq.h>
111409 +#include <linux/interrupt.h>
111410 +#include <linux/io.h>
111411 +#include <linux/ioport.h>
111412 +#include <linux/of_platform.h>
111413 +#include <linux/uaccess.h>
111414 +#include <asm/errno.h>
111415 +#ifndef CONFIG_FMAN_ARM
111416 +#include <sysdev/fsl_soc.h>
111417 +#include <linux/fsl/svr.h>
111418 +#endif
111419 +
111420 +#if defined(CONFIG_COMPAT)
111421 +#include <linux/compat.h>
111422 +#endif
111423 +
111424 +#include "part_ext.h"
111425 +#include "fm_ioctls.h"
111426 +#include "fm_pcd_ioctls.h"
111427 +#include "fm_port_ioctls.h"
111428 +#include "fm_vsp_ext.h"
111429 +
111430 +#ifndef CONFIG_FMAN_ARM
111431 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
111432 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
111433 +#endif
111434 +
111435 +#define __ERR_MODULE__ MODULE_FM
111436 +
111437 +#if defined(CONFIG_COMPAT)
111438 +#include "lnxwrp_ioctls_fm_compat.h"
111439 +#endif
111440 +
111441 +#include "lnxwrp_fm.h"
111442 +
111443 +#define CMP_IOC_DEFINE(def) (IOC_##def != def)
111444 +
111445 +/* fm_pcd_ioctls.h === fm_pcd_ext.h assertions */
111446 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
111447 +#error Error: please synchronize IOC_ defines!
111448 +#endif
111449 +
111450 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_HDRS)
111451 +#error Error: please synchronize IOC_ defines!
111452 +#endif
111453 +
111454 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
111455 +#error Error: please synchronize IOC_ defines!
111456 +#endif
111457 +
111458 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
111459 +#error Error: please synchronize IOC_ defines!
111460 +#endif
111461 +
111462 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_GENERIC_REGS)
111463 +#error Error: please synchronize IOC_ defines!
111464 +#endif
111465 +
111466 +#if CMP_IOC_DEFINE(FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
111467 +#error Error: please synchronize IOC_ defines!
111468 +#endif
111469 +
111470 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
111471 +#error Error: please synchronize IOC_ defines!
111472 +#endif
111473 +
111474 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_DEFAULT_GROUPS)
111475 +#error Error: please synchronize IOC_ defines!
111476 +#endif
111477 +
111478 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_LABELS)
111479 +#error Error: please synchronize IOC_ defines!
111480 +#endif
111481 +
111482 +#if CMP_IOC_DEFINE(FM_PCD_SW_PRS_SIZE)
111483 +#error Error: please synchronize IOC_ defines!
111484 +#endif
111485 +
111486 +#if CMP_IOC_DEFINE(FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE)
111487 +#error Error: please synchronize IOC_ defines!
111488 +#endif
111489 +
111490 +#if DPAA_VERSION >= 11
111491 +#if CMP_IOC_DEFINE(FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
111492 +#error Error: please synchronize IOC_ defines!
111493 +#endif
111494 +#endif
111495 +
111496 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_TREES)
111497 +#error Error: please synchronize IOC_ defines!
111498 +#endif
111499 +
111500 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_GROUPS)
111501 +#error Error: please synchronize IOC_ defines!
111502 +#endif
111503 +
111504 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_UNITS)
111505 +#error Error: please synchronize IOC_ defines!
111506 +#endif
111507 +
111508 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_KEYS)
111509 +#error Error: please synchronize IOC_ defines!
111510 +#endif
111511 +
111512 +#if CMP_IOC_DEFINE(FM_PCD_MAX_SIZE_OF_KEY)
111513 +#error Error: please synchronize IOC_ defines!
111514 +#endif
111515 +
111516 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP)
111517 +#error Error: please synchronize IOC_ defines!
111518 +#endif
111519 +
111520 +#if CMP_IOC_DEFINE(FM_PCD_LAST_KEY_INDEX)
111521 +#error Error: please synchronize IOC_ defines!
111522 +#endif
111523 +
111524 +/* net_ioctls.h === net_ext.h assertions */
111525 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_PID)
111526 +#error Error: please synchronize IOC_ defines!
111527 +#endif
111528 +
111529 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_COMPRESSED)
111530 +#error Error: please synchronize IOC_ defines!
111531 +#endif
111532 +
111533 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_ALL_FIELDS)
111534 +#error Error: please synchronize IOC_ defines!
111535 +#endif
111536 +
111537 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPoE_ALL_FIELDS)
111538 +#error Error: please synchronize IOC_ defines!
111539 +#endif
111540 +
111541 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_ALL_FIELDS)
111542 +#error Error: please synchronize IOC_ defines!
111543 +#endif
111544 +
111545 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS)
111546 +#error Error: please synchronize IOC_ defines!
111547 +#endif
111548 +
111549 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ETH_ALL_FIELDS)
111550 +#error Error: please synchronize IOC_ defines!
111551 +#endif
111552 +
111553 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv4_ALL_FIELDS)
111554 +#error Error: please synchronize IOC_ defines!
111555 +#endif
111556 +
111557 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv6_ALL_FIELDS)
111558 +#error Error: please synchronize IOC_ defines!
111559 +#endif
111560 +
111561 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ICMP_ALL_FIELDS)
111562 +#error Error: please synchronize IOC_ defines!
111563 +#endif
111564 +
111565 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IGMP_ALL_FIELDS)
111566 +#error Error: please synchronize IOC_ defines!
111567 +#endif
111568 +
111569 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_TCP_ALL_FIELDS)
111570 +#error Error: please synchronize IOC_ defines!
111571 +#endif
111572 +
111573 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_ALL_FIELDS)
111574 +#error Error: please synchronize IOC_ defines!
111575 +#endif
111576 +
111577 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_DCCP_ALL_FIELDS)
111578 +#error Error: please synchronize IOC_ defines!
111579 +#endif
111580 +
111581 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ALL_FIELDS)
111582 +#error Error: please synchronize IOC_ defines!
111583 +#endif
111584 +
111585 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS)
111586 +#error Error: please synchronize IOC_ defines!
111587 +#endif
111588 +
111589 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPHC_ALL_FIELDS)
111590 +#error Error: please synchronize IOC_ defines!
111591 +#endif
111592 +
111593 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS)
111594 +#error Error: please synchronize IOC_ defines!
111595 +#endif
111596 +
111597 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv2_ALL_FIELDS)
111598 +#error Error: please synchronize IOC_ defines!
111599 +#endif
111600 +
111601 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS)
111602 +#error Error: please synchronize IOC_ defines!
111603 +#endif
111604 +
111605 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS)
111606 +#error Error: please synchronize IOC_ defines!
111607 +#endif
111608 +
111609 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_VLAN_ALL_FIELDS)
111610 +#error Error: please synchronize IOC_ defines!
111611 +#endif
111612 +
111613 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_ALL_FIELDS)
111614 +#error Error: please synchronize IOC_ defines!
111615 +#endif
111616 +
111617 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_NLPID_ALL_FIELDS)
111618 +#error Error: please synchronize IOC_ defines!
111619 +#endif
111620 +
111621 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SNAP_ALL_FIELDS)
111622 +#error Error: please synchronize IOC_ defines!
111623 +#endif
111624 +
111625 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS)
111626 +#warning Error: please synchronize IOC_ defines!
111627 +#endif
111628 +
111629 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ARP_ALL_FIELDS)
111630 +#error Error: please synchronize IOC_ defines!
111631 +#endif
111632 +
111633 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_RFC2684_ALL_FIELDS)
111634 +#error Error: please synchronize IOC_ defines!
111635 +#endif
111636 +
111637 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS)
111638 +#error Error: please synchronize IOC_ defines!
111639 +#endif
111640 +
111641 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS)
111642 +#error Error: please synchronize IOC_ defines!
111643 +#endif
111644 +
111645 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_GRE_ALL_FIELDS)
111646 +#error Error: please synchronize IOC_ defines!
111647 +#endif
111648 +
111649 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MINENCAP_ALL_FIELDS)
111650 +#error Error: please synchronize IOC_ defines!
111651 +#endif
111652 +
111653 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS)
111654 +#error Error: please synchronize IOC_ defines!
111655 +#endif
111656 +
111657 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS)
111658 +#error Error: please synchronize IOC_ defines!
111659 +#endif
111660 +
111661 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS)
111662 +#error Error: please synchronize IOC_ defines!
111663 +#endif
111664 +
111665 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MACSEC_ALL_FIELDS)
111666 +#error Error: please synchronize IOC_ defines!
111667 +#endif
111668 +
111669 +/* fm_ioctls.h === fm_ext.h assertions */
111670 +#if CMP_IOC_DEFINE(FM_MAX_NUM_OF_VALID_PORTS)
111671 +#error Error: please synchronize IOC_ defines!
111672 +#endif
111673 +
111674 +void LnxWrpPCDIOCTLTypeChecking(void)
111675 +{
111676 + /* fm_ext.h == fm_ioctls.h */
111677 + ASSERT_COND(sizeof(ioc_fm_port_bandwidth_params) == sizeof(t_FmPortsBandwidthParams));
111678 + ASSERT_COND(sizeof(ioc_fm_revision_info_t) == sizeof(t_FmRevisionInfo));
111679 +
111680 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
111681 + /*ioc_fm_pcd_counters_params_t : NOT USED */
111682 + /*ioc_fm_pcd_exception_params_t : private */
111683 +#if (DPAA_VERSION >= 11)
111684 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_params_t) == sizeof(t_FmPcdManipFragCapwapParams));
111685 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_params_t) == sizeof(t_FmPcdManipReassemCapwapParams));
111686 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t) == sizeof(t_FmPcdManipHdrInsrtByHdrParams));
111687 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_ip_params_t) == sizeof(t_FmPcdManipHdrInsrtIpParams));
111688 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_t) == sizeof(t_FmPcdManipHdrInsrt));
111689 + ASSERT_COND(sizeof(ioc_fm_manip_hdr_info_t) == sizeof(t_FmManipHdrInfo));
111690 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t) == sizeof(t_FmPcdManipHdrRmvByHdrParams));
111691 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_capwap_params_t) == sizeof(t_FmPcdManipSpecialOffloadCapwapParams));
111692 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_stats_t) == sizeof(t_FmPcdManipFragCapwapStats));
111693 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_stats_t) == sizeof(t_FmPcdManipReassemCapwapStats));
111694 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
111695 +#endif /* (DPAA_VERSION >= 11) */
111696 +
111697 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_label_params_t) == sizeof(t_FmPcdPrsLabelParams));
111698 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_sw_params_t) == sizeof(t_FmPcdPrsSwParams));
111699 + /*ioc_fm_pcd_kg_dflt_value_params_t : private */
111700 + ASSERT_COND(sizeof(ioc_fm_pcd_hdr_protocol_opt_u) == sizeof(u_FmPcdHdrProtocolOpt));
111701 + ASSERT_COND(sizeof(ioc_fm_pcd_fields_u) == sizeof(t_FmPcdFields));
111702 + ASSERT_COND(sizeof(ioc_fm_pcd_from_hdr_t) == sizeof(t_FmPcdFromHdr));
111703 + ASSERT_COND(sizeof(ioc_fm_pcd_from_field_t) == sizeof(t_FmPcdFromField));
111704 + ASSERT_COND(sizeof(ioc_fm_pcd_distinction_unit_t) == sizeof(t_FmPcdDistinctionUnit));
111705 +
111706 +#if defined(CONFIG_ARM64)
111707 + /* different alignment */
111708 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *) + 4);
111709 +#else
111710 +#if !defined(CONFIG_COMPAT)
111711 + /* different alignment */
111712 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *));
111713 +#endif
111714 +#endif
111715 + ASSERT_COND(sizeof(ioc_fm_pcd_extract_entry_t) == sizeof(t_FmPcdExtractEntry));
111716 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_mask_t) == sizeof(t_FmPcdKgExtractMask));
111717 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_dflt_t) == sizeof(t_FmPcdKgExtractDflt));
111718 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t) == sizeof(t_FmPcdKgKeyExtractAndHashParams));
111719 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extracted_or_params_t) == sizeof(t_FmPcdKgExtractedOrParams));
111720 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_counter_t) == sizeof(t_FmPcdKgSchemeCounter));
111721 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_plcr_profile_t) == sizeof(t_FmPcdKgPlcrProfile));
111722 +#if (DPAA_VERSION >= 11)
111723 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_storage_profile_t) == sizeof(t_FmPcdKgStorageProfile));
111724 +#endif
111725 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_cc_t) == sizeof(t_FmPcdKgCc));
111726 +#if !defined(CONFIG_COMPAT)
111727 + /* different alignment */
111728 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_params_t) == sizeof(t_FmPcdKgSchemeParams) + sizeof(void *));
111729 +#endif
111730 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_cc_params_t) == sizeof(t_FmPcdCcNextCcParams));
111731 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_plcr_params_t) == sizeof(t_FmPcdCcNextPlcrParams));
111732 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_enqueue_params_t) == sizeof(t_FmPcdCcNextEnqueueParams));
111733 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_kg_params_t) == sizeof(t_FmPcdCcNextKgParams));
111734 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_engine_params_t) == sizeof(t_FmPcdCcNextEngineParams));
111735 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_key_params_t) == sizeof(t_FmPcdCcKeyParams));
111736 + ASSERT_COND(sizeof(ioc_keys_params_t) == sizeof(t_KeysParams));
111737 +#if !defined(CONFIG_COMPAT)
111738 + /* different alignment */
111739 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_node_params_t) == sizeof(t_FmPcdCcNodeParams) + sizeof(void *));
111740 + ASSERT_COND(sizeof(ioc_fm_pcd_hash_table_params_t) == sizeof(t_FmPcdHashTableParams) + sizeof(void *));
111741 +#endif
111742 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_grp_params_t) == sizeof(t_FmPcdCcGrpParams));
111743 +#if !defined(CONFIG_COMPAT)
111744 + /* different alignment */
111745 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_tree_params_t) == sizeof(t_FmPcdCcTreeParams) + sizeof(void *));
111746 +#endif
111747 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_byte_rate_mode_param_t) == sizeof(t_FmPcdPlcrByteRateModeParams));
111748 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t) == sizeof(t_FmPcdPlcrNonPassthroughAlgParams));
111749 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_next_engine_params_u) == sizeof(u_FmPcdPlcrNextEngineParams));
111750 + /*ioc_fm_pcd_port_params_t : private */
111751 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_profile_params_t) == sizeof(t_FmPcdPlcrProfileParams) + sizeof(void *));
111752 + /*ioc_fm_pcd_cc_tree_modify_next_engine_params_t : private */
111753 +
111754 +#ifdef FM_CAPWAP_SUPPORT
111755 +#error TODO: unsupported feature
111756 +/*
111757 + ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipHdrInsrtByTemplateParams));
111758 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapFragmentationParams));
111759 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapReassemblyParams));
111760 +*/
111761 +#endif
111762 +
111763 + /*ioc_fm_pcd_cc_node_modify_next_engine_params_t : private */
111764 + /*ioc_fm_pcd_cc_node_remove_key_params_t : private */
111765 + /*ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t : private */
111766 + /*ioc_fm_pcd_cc_node_modify_key_params_t : private */
111767 + /*ioc_fm_manip_hdr_info_t : private */
111768 + /*ioc_fm_pcd_hash_table_set_t : private */
111769 +
111770 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_params_t) == sizeof(t_FmPcdManipFragIpParams));
111771 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_params_t) == sizeof(t_FmPcdManipReassemIpParams));
111772 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_ipsec_params_t) == sizeof(t_FmPcdManipSpecialOffloadIPSecParams));
111773 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_params_t) == sizeof(t_FmPcdManipSpecialOffloadParams));
111774 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_generic_params_t) == sizeof(t_FmPcdManipHdrRmvGenericParams));
111775 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_generic_params_t) == sizeof(t_FmPcdManipHdrInsrtGenericParams));
111776 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_params_t) == sizeof(t_FmPcdManipHdrInsrtParams));
111777 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_params_t) == sizeof(t_FmPcdManipHdrRmvParams));
111778 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_params_t) == sizeof(t_FmPcdManipHdrParams));
111779 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
111780 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_params_t) == sizeof(t_FmPcdManipReassemParams));
111781 +#if !defined(CONFIG_COMPAT)
111782 + /* different alignment */
111783 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_params_t) == sizeof(t_FmPcdManipParams) + sizeof(void *));
111784 +#endif
111785 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_stats_t) == sizeof(t_FmPcdManipReassemIpStats));
111786 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_stats_t) == sizeof(t_FmPcdManipFragIpStats));
111787 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_stats_t) == sizeof(t_FmPcdManipReassemStats));
111788 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_stats_t) == sizeof(t_FmPcdManipFragStats));
111789 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_stats_t) == sizeof(t_FmPcdManipStats));
111790 +#if DPAA_VERSION >= 11
111791 + ASSERT_COND(sizeof(ioc_fm_pcd_frm_replic_group_params_t) == sizeof(t_FmPcdFrmReplicGroupParams) + sizeof(void *));
111792 +#endif
111793 +
111794 + /* fm_port_ext.h == fm_port_ioctls.h */
111795 + ASSERT_COND(sizeof(ioc_fm_port_rate_limit_t) == sizeof(t_FmPortRateLimit));
111796 + ASSERT_COND(sizeof(ioc_fm_port_pcd_params_t) == sizeof(t_FmPortPcdParams));
111797 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_select_t) == sizeof(t_FmPcdKgSchemeSelect));
111798 + ASSERT_COND(sizeof(ioc_fm_pcd_port_schemes_params_t) == sizeof(t_FmPcdPortSchemesParams));
111799 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_start_t) == sizeof(t_FmPcdPrsStart));
111800 +
111801 + return;
111802 +}
111803 +
111804 +#define ASSERT_IOC_NET_ENUM(def) ASSERT_COND((unsigned long)e_IOC_NET_##def == (unsigned long)def)
111805 +
111806 +void LnxWrpPCDIOCTLEnumChecking(void)
111807 +{
111808 + /* net_ext.h == net_ioctls.h : sampling checks */
111809 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_MACSEC);
111810 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_PPP);
111811 + ASSERT_IOC_NET_ENUM(MAX_HEADER_TYPE_COUNT);
111812 +
111813 + /* fm_ext.h == fm_ioctls.h */
111814 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_TYPE_DUMMY == (unsigned long)e_FM_PORT_TYPE_DUMMY);
111815 + ASSERT_COND((unsigned long)e_IOC_EX_MURAM_ECC == (unsigned long)e_FM_EX_MURAM_ECC);
111816 + ASSERT_COND((unsigned long)e_IOC_FM_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_COUNTERS_DEQ_CONFIRM);
111817 +
111818 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
111819 + 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);
111820 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC == (unsigned long)e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
111821 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS == (unsigned long)e_FM_PCD_PRS);
111822 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FULL_FIELD == (unsigned long)e_FM_PCD_EXTRACT_FULL_FIELD);
111823 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID == (unsigned long)e_FM_PCD_EXTRACT_FROM_FLOW_ID);
111824 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO == (unsigned long)e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO);
111825 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_DFLT_ILLEGAL == (unsigned long)e_FM_PCD_KG_DFLT_ILLEGAL);
111826 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA == (unsigned long)e_FM_PCD_KG_GENERIC_NOT_FROM_DATA);
111827 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_HDR_INDEX_LAST == (unsigned long)e_FM_PCD_HDR_INDEX_LAST);
111828 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_SHARED == (unsigned long)e_FM_PCD_PLCR_SHARED);
111829 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_RFC_4115 == (unsigned long)e_FM_PCD_PLCR_RFC_4115);
111830 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_COLOR_AWARE == (unsigned long)e_FM_PCD_PLCR_COLOR_AWARE);
111831 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_OVERRIDE == (unsigned long)e_FM_PCD_PLCR_OVERRIDE);
111832 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_FULL_FRM_LEN);
111833 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN);
111834 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PACKET_MODE == (unsigned long)e_FM_PCD_PLCR_PACKET_MODE);
111835 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_DROP_FRAME == (unsigned long)e_FM_PCD_DROP_FRAME);
111836 + 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);
111837 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP == (unsigned long)e_FM_PCD_ACTION_INDEXED_LOOKUP);
111838 + 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);
111839 +#if !defined(FM_CAPWAP_SUPPORT)
111840 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_GENERIC == (unsigned long)e_FM_PCD_MANIP_INSRT_GENERIC);
111841 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_GENERIC == (unsigned long)e_FM_PCD_MANIP_RMV_GENERIC);
111842 +#else
111843 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE == (unsigned long)e_FM_PCD_MANIP_INSRT_BY_TEMPLATE);
111844 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR);
111845 + 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);
111846 +#endif
111847 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG == (unsigned long)e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG);
111848 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH == (unsigned long)e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
111849 +
111850 +#ifdef FM_CAPWAP_SUPPORT
111851 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_STATS_PER_FLOWID == (unsigned long)e_FM_PCD_STATS_PER_FLOWID);
111852 +#endif
111853 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD);
111854 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_CC_STATS_MODE_FRAME == (unsigned long)e_FM_PCD_CC_STATS_MODE_FRAME);
111855 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG == (unsigned long)e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG);
111856 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC);
111857 +
111858 + /* fm_port_ext.h == fm_port_ioctls.h */
111859 +#if !defined(FM_CAPWAP_SUPPORT)
111860 + 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);
111861 +#else
111862 + 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);
111863 +#endif
111864 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_PORT_COUNTERS_DEQ_CONFIRM);
111865 + 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);
111866 +
111867 + return;
111868 +}
111869 +
111870 +static t_Error LnxwrpFmPcdIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
111871 +{
111872 + t_Error err = E_OK;
111873 +
111874 +/*
111875 +Status: PCD API to fmlib (file: drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h):
111876 +
111877 + FM_PCD_PrsLoadSw
111878 + FM_PCD_SetAdvancedOffloadSupport
111879 + FM_PCD_Enable
111880 + FM_PCD_Disable
111881 + FM_PCD_ForceIntr
111882 + FM_PCD_SetException
111883 + FM_PCD_KgSetAdditionalDataAfterParsing
111884 + FM_PCD_KgSetDfltValue
111885 + FM_PCD_NetEnvCharacteristicsSet
111886 + FM_PCD_NetEnvCharacteristicsDelete
111887 + FM_PCD_KgSchemeSet
111888 + FM_PCD_KgSchemeDelete
111889 + FM_PCD_MatchTableSet
111890 + FM_PCD_MatchTableDelete
111891 + FM_PCD_CcRootBuild
111892 + FM_PCD_CcRootDelete
111893 + FM_PCD_PlcrProfileSet
111894 + FM_PCD_PlcrProfileDelete
111895 + FM_PCD_CcRootModifyNextEngine
111896 + FM_PCD_MatchTableModifyNextEngine
111897 + FM_PCD_MatchTableModifyMissNextEngine
111898 + FM_PCD_MatchTableRemoveKey
111899 + FM_PCD_MatchTableAddKey
111900 + FM_PCD_MatchTableModifyKeyAndNextEngine
111901 + FM_PCD_HashTableSet
111902 + FM_PCD_HashTableDelete
111903 + FM_PCD_HashTableAddKey
111904 + FM_PCD_HashTableRemoveKey
111905 + FM_PCD_MatchTableModifyKey
111906 + FM_PCD_ManipNodeReplace
111907 + FM_PCD_ManipNodeSet
111908 + FM_PCD_ManipNodeDelete
111909 +
111910 +Status: not exported, should be thru sysfs
111911 + FM_PCD_KgSchemeGetCounter
111912 + FM_PCD_KgSchemeSetCounter
111913 + FM_PCD_PlcrProfileGetCounter
111914 + FM_PCD_PlcrProfileSetCounter
111915 +
111916 +Status: not exported
111917 + FM_PCD_MatchTableFindNRemoveKey
111918 + FM_PCD_MatchTableFindNModifyNextEngine
111919 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine
111920 + FM_PCD_MatchTableFindNModifyKey
111921 + FM_PCD_MatchTableGetIndexedHashBucket
111922 + FM_PCD_MatchTableGetNextEngine
111923 + FM_PCD_MatchTableGetKeyCounter
111924 +
111925 +Status: not exported, would be nice to have
111926 + FM_PCD_HashTableModifyNextEngine
111927 + FM_PCD_HashTableModifyMissNextEngine
111928 + FM_PCD_HashTableGetMissNextEngine
111929 + FM_PCD_ManipGetStatistics
111930 +
111931 +Status: not exported
111932 +#if DPAA_VERSION >= 11
111933 +
111934 + FM_VSP_GetStatistics -- it's not available yet
111935 +#endif
111936 +
111937 +Status: feature not supported
111938 +#ifdef FM_CAPWAP_SUPPORT
111939 +#error unsupported feature
111940 + FM_PCD_StatisticsSetNode
111941 +#endif
111942 +
111943 + */
111944 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
111945 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 20);
111946 +
111947 + switch (cmd)
111948 + {
111949 +#if defined(CONFIG_COMPAT)
111950 + case FM_PCD_IOC_PRS_LOAD_SW_COMPAT:
111951 +#endif
111952 + case FM_PCD_IOC_PRS_LOAD_SW:
111953 + {
111954 + ioc_fm_pcd_prs_sw_params_t *param;
111955 + uint8_t *p_code;
111956 +
111957 + param = (ioc_fm_pcd_prs_sw_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_prs_sw_params_t));
111958 + if (!param)
111959 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
111960 +
111961 + memset(param, 0, sizeof(ioc_fm_pcd_prs_sw_params_t));
111962 +
111963 +#if defined(CONFIG_COMPAT)
111964 + if (compat)
111965 + {
111966 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param;
111967 +
111968 + compat_param = (ioc_compat_fm_pcd_prs_sw_params_t *) XX_Malloc(
111969 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
111970 + if (!compat_param)
111971 + {
111972 + XX_Free(param);
111973 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
111974 + }
111975 +
111976 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
111977 + if (copy_from_user(compat_param,
111978 + (ioc_compat_fm_pcd_prs_sw_params_t *) compat_ptr(arg),
111979 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t)))
111980 + {
111981 + XX_Free(compat_param);
111982 + XX_Free(param);
111983 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111984 + }
111985 +
111986 + compat_fm_pcd_prs_sw(compat_param, param, COMPAT_US_TO_K);
111987 +
111988 + XX_Free(compat_param);
111989 + }
111990 + else
111991 +#endif
111992 + {
111993 + if (copy_from_user(param, (ioc_fm_pcd_prs_sw_params_t *)arg,
111994 + sizeof(ioc_fm_pcd_prs_sw_params_t)))
111995 + {
111996 + XX_Free(param);
111997 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111998 + }
111999 + }
112000 +
112001 + if (!param->p_code || !param->size)
112002 + {
112003 + XX_Free(param);
112004 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112005 + }
112006 +
112007 + p_code = (uint8_t *) XX_Malloc(param->size);
112008 + if (!p_code)
112009 + {
112010 + XX_Free(param);
112011 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112012 + }
112013 +
112014 + memset(p_code, 0, param->size);
112015 + if (copy_from_user(p_code, param->p_code, param->size))
112016 + {
112017 + XX_Free(p_code);
112018 + XX_Free(param);
112019 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112020 + }
112021 +
112022 + param->p_code = p_code;
112023 +
112024 + err = FM_PCD_PrsLoadSw(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPrsSwParams*)param);
112025 +
112026 + XX_Free(p_code);
112027 + XX_Free(param);
112028 + break;
112029 + }
112030 +
112031 + case FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT:
112032 + err = FM_PCD_SetAdvancedOffloadSupport(p_LnxWrpFmDev->h_PcdDev);
112033 + break;
112034 +
112035 + case FM_PCD_IOC_ENABLE:
112036 + err = FM_PCD_Enable(p_LnxWrpFmDev->h_PcdDev);
112037 + break;
112038 +
112039 + case FM_PCD_IOC_DISABLE:
112040 + err = FM_PCD_Disable(p_LnxWrpFmDev->h_PcdDev);
112041 + break;
112042 +
112043 + case FM_PCD_IOC_FORCE_INTR:
112044 + {
112045 + int exception;
112046 +
112047 +#if defined(CONFIG_COMPAT)
112048 + if (compat)
112049 + {
112050 + if (get_user(exception, (int *) compat_ptr(arg)))
112051 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112052 + }
112053 + else
112054 +#endif
112055 + {
112056 + if (get_user(exception, (int *)arg))
112057 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112058 + }
112059 +
112060 + err = FM_PCD_ForceIntr(p_LnxWrpFmDev->h_PcdDev, (e_FmPcdExceptions)exception);
112061 + break;
112062 + }
112063 +
112064 + case FM_PCD_IOC_SET_EXCEPTION:
112065 + {
112066 + ioc_fm_pcd_exception_params_t *param;
112067 +
112068 + param = (ioc_fm_pcd_exception_params_t *) XX_Malloc(
112069 + sizeof(ioc_fm_pcd_exception_params_t));
112070 + if (!param)
112071 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112072 +
112073 + memset(param, 0, sizeof(ioc_fm_pcd_exception_params_t));
112074 +
112075 +#if defined(CONFIG_COMPAT)
112076 + if (compat)
112077 + {
112078 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)compat_ptr(arg),
112079 + sizeof(ioc_fm_pcd_exception_params_t)))
112080 + {
112081 + XX_Free(param);
112082 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112083 + }
112084 + }
112085 + else
112086 +#endif
112087 + {
112088 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)arg,
112089 + sizeof(ioc_fm_pcd_exception_params_t)))
112090 + {
112091 + XX_Free(param);
112092 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112093 + }
112094 + }
112095 +
112096 + err = FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, param->exception, param->enable);
112097 +
112098 + XX_Free(param);
112099 + break;
112100 + }
112101 +
112102 + case FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING:
112103 + {
112104 + uint8_t payloadOffset;
112105 +
112106 +#if defined(CONFIG_COMPAT)
112107 + if (compat)
112108 + {
112109 + if (get_user(payloadOffset, (uint8_t*) compat_ptr(arg)))
112110 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112111 + }
112112 + else
112113 +#endif
112114 + {
112115 + if (get_user(payloadOffset, (uint8_t*) arg))
112116 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112117 + }
112118 +
112119 + err = FM_PCD_KgSetAdditionalDataAfterParsing(p_LnxWrpFmDev->h_PcdDev, payloadOffset);
112120 + break;
112121 + }
112122 +
112123 + case FM_PCD_IOC_KG_SET_DFLT_VALUE:
112124 + {
112125 + ioc_fm_pcd_kg_dflt_value_params_t *param;
112126 +
112127 + param = (ioc_fm_pcd_kg_dflt_value_params_t *) XX_Malloc(
112128 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
112129 + if (!param)
112130 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112131 +
112132 + memset(param, 0, sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
112133 +
112134 +#if defined(CONFIG_COMPAT)
112135 + if (compat)
112136 + {
112137 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)compat_ptr(arg),
112138 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
112139 + {
112140 + XX_Free(param);
112141 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112142 + }
112143 + }
112144 + else
112145 +#endif
112146 + {
112147 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)arg,
112148 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
112149 + {
112150 + XX_Free(param);
112151 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112152 + }
112153 + }
112154 +
112155 + err = FM_PCD_KgSetDfltValue(p_LnxWrpFmDev->h_PcdDev, param->valueId, param->value);
112156 +
112157 + XX_Free(param);
112158 + break;
112159 + }
112160 +
112161 +#if defined(CONFIG_COMPAT)
112162 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT:
112163 +#endif
112164 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET:
112165 + {
112166 + ioc_fm_pcd_net_env_params_t *param;
112167 +
112168 + param = (ioc_fm_pcd_net_env_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_net_env_params_t));
112169 + if (!param)
112170 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112171 +
112172 + memset(param, 0, sizeof(ioc_fm_pcd_net_env_params_t));
112173 +
112174 +#if defined(CONFIG_COMPAT)
112175 + if (compat)
112176 + {
112177 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112178 +
112179 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112180 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112181 + if (!compat_param)
112182 + {
112183 + XX_Free(param);
112184 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112185 + }
112186 +
112187 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112188 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112189 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112190 + {
112191 + XX_Free(compat_param);
112192 + XX_Free(param);
112193 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112194 + }
112195 +
112196 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_US_TO_K);
112197 + XX_Free(compat_param);
112198 + }
112199 + else
112200 +#endif
112201 + {
112202 + if (copy_from_user(param, (ioc_fm_pcd_net_env_params_t *) arg,
112203 + sizeof(ioc_fm_pcd_net_env_params_t)))
112204 + {
112205 + XX_Free(param);
112206 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112207 + }
112208 + }
112209 +
112210 + param->id = FM_PCD_NetEnvCharacteristicsSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdNetEnvParams*)param);
112211 +
112212 + if (!param->id)
112213 + {
112214 + XX_Free(param);
112215 + err = E_INVALID_VALUE;
112216 + /* Since the LLD has no errno-style error reporting,
112217 + we're left here with no other option than to report
112218 + a generic E_INVALID_VALUE */
112219 + break;
112220 + }
112221 +
112222 +#if defined(CONFIG_COMPAT)
112223 + if (compat)
112224 + {
112225 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112226 +
112227 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112228 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112229 + if (!compat_param)
112230 + {
112231 + XX_Free(param);
112232 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112233 + }
112234 +
112235 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112236 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_K_TO_US);
112237 +
112238 + if (copy_to_user((ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112239 + compat_param,
112240 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112241 + err = E_READ_FAILED;
112242 +
112243 + XX_Free(compat_param);
112244 + }
112245 + else
112246 +#endif
112247 + {
112248 + if (copy_to_user((ioc_fm_pcd_net_env_params_t *)arg,
112249 + param,
112250 + sizeof(ioc_fm_pcd_net_env_params_t)))
112251 + err = E_READ_FAILED;
112252 + }
112253 +
112254 + XX_Free(param);
112255 + break;
112256 + }
112257 +
112258 +#if defined(CONFIG_COMPAT)
112259 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT:
112260 +#endif
112261 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE:
112262 + {
112263 + ioc_fm_obj_t id;
112264 +
112265 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112266 +
112267 +#if defined(CONFIG_COMPAT)
112268 + if (compat)
112269 + {
112270 + ioc_compat_fm_obj_t compat_id;
112271 +
112272 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112273 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112274 +
112275 + compat_obj_delete(&compat_id, &id);
112276 + }
112277 + else
112278 +#endif
112279 + {
112280 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112281 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112282 + }
112283 +
112284 + err = FM_PCD_NetEnvCharacteristicsDelete(id.obj);
112285 + break;
112286 + }
112287 +
112288 +#if defined(CONFIG_COMPAT)
112289 + case FM_PCD_IOC_KG_SCHEME_SET_COMPAT:
112290 +#endif
112291 + case FM_PCD_IOC_KG_SCHEME_SET:
112292 + {
112293 + ioc_fm_pcd_kg_scheme_params_t *param;
112294 +
112295 + param = (ioc_fm_pcd_kg_scheme_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_params_t));
112296 + if (!param)
112297 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112298 +
112299 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_params_t));
112300 +
112301 +#if defined(CONFIG_COMPAT)
112302 + if (compat)
112303 + {
112304 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param = NULL;
112305 +
112306 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112307 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112308 + if (!compat_param)
112309 + {
112310 + XX_Free(param);
112311 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112312 + }
112313 +
112314 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112315 +
112316 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_params_t *) compat_ptr(arg),
112317 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112318 + {
112319 + XX_Free(compat_param);
112320 + XX_Free(param);
112321 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112322 + }
112323 +
112324 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_US_TO_K);
112325 +
112326 + XX_Free(compat_param);
112327 + }
112328 + else
112329 +#endif
112330 + {
112331 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_params_t *)arg,
112332 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112333 + {
112334 + XX_Free(param);
112335 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112336 + }
112337 + }
112338 +
112339 + param->id = FM_PCD_KgSchemeSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdKgSchemeParams*)param);
112340 +
112341 + if (!param->id)
112342 + {
112343 + XX_Free(param);
112344 + err = E_INVALID_VALUE;
112345 + /* Since the LLD has no errno-style error reporting,
112346 + we're left here with no other option than to report
112347 + a generic E_INVALID_VALUE */
112348 + break;
112349 + }
112350 +
112351 +#if defined(CONFIG_COMPAT)
112352 + if (compat)
112353 + {
112354 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param;
112355 +
112356 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112357 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112358 + if (!compat_param)
112359 + {
112360 + XX_Free(param);
112361 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112362 + }
112363 +
112364 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112365 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_K_TO_US);
112366 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_params_t *)compat_ptr(arg),
112367 + compat_param,
112368 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112369 + err = E_READ_FAILED;
112370 +
112371 + XX_Free(compat_param);
112372 + }
112373 + else
112374 +#endif
112375 + {
112376 + if (copy_to_user((ioc_fm_pcd_kg_scheme_params_t *)arg,
112377 + param,
112378 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112379 + err = E_READ_FAILED;
112380 + }
112381 +
112382 + XX_Free(param);
112383 + break;
112384 + }
112385 +
112386 +#if defined(CONFIG_COMPAT)
112387 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT:
112388 +#endif
112389 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR:
112390 + {
112391 + ioc_fm_pcd_kg_scheme_spc_t *param;
112392 +
112393 + param = (ioc_fm_pcd_kg_scheme_spc_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112394 + if (!param)
112395 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112396 +
112397 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112398 +
112399 +#if defined(CONFIG_COMPAT)
112400 + if (compat)
112401 + {
112402 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param = NULL;
112403 +
112404 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
112405 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112406 + if (!compat_param)
112407 + {
112408 + XX_Free(param);
112409 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112410 + }
112411 +
112412 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112413 +
112414 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_spc_t *) compat_ptr(arg),
112415 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
112416 + {
112417 + XX_Free(compat_param);
112418 + XX_Free(param);
112419 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112420 + }
112421 +
112422 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_US_TO_K);
112423 +
112424 + XX_Free(compat_param);
112425 + }
112426 + else
112427 +#endif
112428 + {
112429 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_spc_t *)arg,
112430 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
112431 + {
112432 + XX_Free(param);
112433 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112434 + }
112435 + }
112436 +
112437 + param->val = FM_PCD_KgSchemeGetCounter((t_Handle)param->id);
112438 +
112439 +#if defined(CONFIG_COMPAT)
112440 + if (compat)
112441 + {
112442 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param;
112443 +
112444 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
112445 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112446 + if (!compat_param)
112447 + {
112448 + XX_Free(param);
112449 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112450 + }
112451 +
112452 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112453 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_K_TO_US);
112454 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_spc_t *)compat_ptr(arg),
112455 + compat_param,
112456 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
112457 + err = E_READ_FAILED;
112458 +
112459 + XX_Free(compat_param);
112460 + }
112461 + else
112462 +#endif
112463 + {
112464 + if (copy_to_user((ioc_fm_pcd_kg_scheme_spc_t *)arg,
112465 + param,
112466 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
112467 + err = E_READ_FAILED;
112468 + }
112469 +
112470 + XX_Free(param);
112471 + break;
112472 + }
112473 +
112474 +#if defined(CONFIG_COMPAT)
112475 + case FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT:
112476 +#endif
112477 + case FM_PCD_IOC_KG_SCHEME_DELETE:
112478 + {
112479 + ioc_fm_obj_t id;
112480 +
112481 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112482 +
112483 +#if defined(CONFIG_COMPAT)
112484 + if (compat)
112485 + {
112486 + ioc_compat_fm_obj_t compat_id;
112487 +
112488 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112489 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112490 +
112491 + compat_obj_delete(&compat_id, &id);
112492 + }
112493 + else
112494 +#endif
112495 + {
112496 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112497 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112498 + }
112499 +
112500 + err = FM_PCD_KgSchemeDelete(id.obj);
112501 + break;
112502 + }
112503 +
112504 +#if defined(CONFIG_COMPAT)
112505 + case FM_PCD_IOC_MATCH_TABLE_SET_COMPAT:
112506 +#endif
112507 + case FM_PCD_IOC_MATCH_TABLE_SET:
112508 + {
112509 + ioc_fm_pcd_cc_node_params_t *param;
112510 + uint8_t *keys;
112511 + uint8_t *masks;
112512 + int i,k;
112513 +
112514 + param = (ioc_fm_pcd_cc_node_params_t *) XX_Malloc(
112515 + sizeof(ioc_fm_pcd_cc_node_params_t) +
112516 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112517 + if (!param)
112518 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112519 +
112520 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_params_t) +
112521 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112522 +
112523 + keys = (uint8_t *) (param + 1);
112524 + masks = keys + IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY;
112525 +
112526 +#if defined(CONFIG_COMPAT)
112527 + if (compat)
112528 + {
112529 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
112530 +
112531 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
112532 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112533 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112534 + if (!compat_param)
112535 + {
112536 + XX_Free(param);
112537 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112538 + }
112539 +
112540 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112541 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112542 +
112543 + if (copy_from_user(compat_param,
112544 + (ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
112545 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
112546 + {
112547 + XX_Free(compat_param);
112548 + XX_Free(param);
112549 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112550 + }
112551 +
112552 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_US_TO_K);
112553 +
112554 + XX_Free(compat_param);
112555 + }
112556 + else
112557 +#endif
112558 + {
112559 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_params_t *)arg, sizeof(ioc_fm_pcd_cc_node_params_t)))
112560 + {
112561 + XX_Free(param);
112562 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112563 + }
112564 + }
112565 +
112566 + ASSERT_COND(param->keys_params.num_of_keys <= IOC_FM_PCD_MAX_NUM_OF_KEYS);
112567 + ASSERT_COND(param->keys_params.key_size <= IOC_FM_PCD_MAX_SIZE_OF_KEY);
112568 +
112569 + /* support for indexed lookup */
112570 + if( !(param->extract_cc_params.type == e_IOC_FM_PCD_EXTRACT_NON_HDR &&
112571 + param->extract_cc_params.extract_params.extract_non_hdr.src == e_IOC_FM_PCD_EXTRACT_FROM_HASH &&
112572 + param->extract_cc_params.extract_params.extract_non_hdr.action == e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP))
112573 + {
112574 + for (i=0, k=0;
112575 + i < param->keys_params.num_of_keys;
112576 + i++, k += IOC_FM_PCD_MAX_SIZE_OF_KEY)
112577 + {
112578 + if (param->keys_params.key_params[i].p_key &&
112579 + param->keys_params.key_size)
112580 + {
112581 + if (copy_from_user(&keys[k],
112582 + param->keys_params.key_params[i].p_key,
112583 + param->keys_params.key_size))
112584 + {
112585 + XX_Free(param);
112586 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112587 + }
112588 +
112589 + param->keys_params.key_params[i].p_key = &keys[k];
112590 + }
112591 +
112592 + if (param->keys_params.key_params[i].p_mask)
112593 + {
112594 + if (copy_from_user(&masks[k],
112595 + param->keys_params.key_params[i].p_mask,
112596 + param->keys_params.key_size))
112597 + {
112598 + XX_Free(param);
112599 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112600 + }
112601 +
112602 + param->keys_params.key_params[i].p_mask = &masks[k];
112603 + }
112604 + }
112605 + }
112606 +
112607 + param->id = FM_PCD_MatchTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcNodeParams*)param);
112608 +
112609 + if (!param->id) {
112610 + XX_Free(param);
112611 + err = E_INVALID_VALUE;
112612 + /* Since the LLD has no errno-style error reporting,
112613 + we're left here with no other option than to report
112614 + a generic E_INVALID_VALUE */
112615 + break;
112616 + }
112617 +
112618 +#if defined(CONFIG_COMPAT)
112619 + if (compat)
112620 + {
112621 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
112622 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
112623 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112624 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112625 + if (!compat_param)
112626 + {
112627 + XX_Free(param);
112628 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112629 + }
112630 +
112631 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112632 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112633 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_K_TO_US);
112634 +
112635 + if (copy_to_user((ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
112636 + compat_param,
112637 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
112638 + err = E_READ_FAILED;
112639 +
112640 + XX_Free(compat_param);
112641 + }
112642 + else
112643 +#endif
112644 + {
112645 + if (copy_to_user((ioc_fm_pcd_cc_node_params_t *)arg,
112646 + param,
112647 + sizeof(ioc_fm_pcd_cc_node_params_t)))
112648 + err = E_READ_FAILED;
112649 + }
112650 +
112651 + XX_Free(param);
112652 + break;
112653 + }
112654 +
112655 +#if defined(CONFIG_COMPAT)
112656 + case FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT:
112657 +#endif
112658 + case FM_PCD_IOC_MATCH_TABLE_DELETE:
112659 + {
112660 + ioc_fm_obj_t id;
112661 +
112662 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112663 +
112664 +#if defined(CONFIG_COMPAT)
112665 + if (compat)
112666 + {
112667 + ioc_compat_fm_obj_t compat_id;
112668 +
112669 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112670 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112671 +
112672 + compat_obj_delete(&compat_id, &id);
112673 + }
112674 + else
112675 +#endif
112676 + {
112677 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112678 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112679 + }
112680 +
112681 + err = FM_PCD_MatchTableDelete(id.obj);
112682 + break;
112683 + }
112684 +
112685 +#if defined(CONFIG_COMPAT)
112686 + case FM_PCD_IOC_CC_ROOT_BUILD_COMPAT:
112687 +#endif
112688 + case FM_PCD_IOC_CC_ROOT_BUILD:
112689 + {
112690 + ioc_fm_pcd_cc_tree_params_t *param;
112691 +
112692 + param = (ioc_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_cc_tree_params_t));
112693 + if (!param)
112694 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112695 +
112696 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_params_t));
112697 +
112698 +#if defined(CONFIG_COMPAT)
112699 + if (compat)
112700 + {
112701 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
112702 +
112703 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(
112704 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112705 + if (!compat_param)
112706 + {
112707 + XX_Free(param);
112708 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112709 + }
112710 +
112711 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112712 + if (copy_from_user(compat_param,
112713 + (ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
112714 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
112715 + {
112716 + XX_Free(compat_param);
112717 + XX_Free(param);
112718 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112719 + }
112720 +
112721 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_US_TO_K);
112722 +
112723 + XX_Free(compat_param);
112724 + }
112725 + else
112726 +#endif
112727 + {
112728 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_params_t *)arg,
112729 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
112730 + {
112731 + XX_Free(param);
112732 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112733 + }
112734 + }
112735 +
112736 + param->id = FM_PCD_CcRootBuild(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcTreeParams*)param);
112737 +
112738 + if (!param->id) {
112739 + XX_Free(param);
112740 + err = E_INVALID_VALUE;
112741 + /* Since the LLD has no errno-style error reporting,
112742 + we're left here with no other option than to report
112743 + a generic E_INVALID_VALUE */
112744 + break;
112745 + }
112746 +
112747 +#if defined(CONFIG_COMPAT)
112748 + if (compat)
112749 + {
112750 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
112751 +
112752 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112753 + if (!compat_param)
112754 + {
112755 + XX_Free(param);
112756 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112757 + }
112758 +
112759 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112760 +
112761 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_K_TO_US);
112762 +
112763 + if (copy_to_user((ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
112764 + compat_param,
112765 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
112766 + err = E_READ_FAILED;
112767 +
112768 + XX_Free(compat_param);
112769 + }
112770 + else
112771 +#endif
112772 + {
112773 + if (copy_to_user((ioc_fm_pcd_cc_tree_params_t *)arg,
112774 + param,
112775 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
112776 + err = E_READ_FAILED;
112777 + }
112778 +
112779 + XX_Free(param);
112780 + break;
112781 + }
112782 +
112783 +#if defined(CONFIG_COMPAT)
112784 + case FM_PCD_IOC_CC_ROOT_DELETE_COMPAT:
112785 +#endif
112786 + case FM_PCD_IOC_CC_ROOT_DELETE:
112787 + {
112788 + ioc_fm_obj_t id;
112789 +
112790 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112791 +
112792 +#if defined(CONFIG_COMPAT)
112793 + if (compat)
112794 + {
112795 + ioc_compat_fm_obj_t compat_id;
112796 +
112797 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112798 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112799 +
112800 + compat_obj_delete(&compat_id, &id);
112801 + }
112802 + else
112803 +#endif
112804 + {
112805 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112806 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112807 + }
112808 +
112809 + err = FM_PCD_CcRootDelete(id.obj);
112810 + break;
112811 + }
112812 +
112813 +#if defined(CONFIG_COMPAT)
112814 + case FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT:
112815 +#endif
112816 + case FM_PCD_IOC_PLCR_PROFILE_SET:
112817 + {
112818 + ioc_fm_pcd_plcr_profile_params_t *param;
112819 +
112820 + param = (ioc_fm_pcd_plcr_profile_params_t *) XX_Malloc(
112821 + sizeof(ioc_fm_pcd_plcr_profile_params_t));
112822 + if (!param)
112823 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112824 +
112825 + memset(param, 0, sizeof(ioc_fm_pcd_plcr_profile_params_t));
112826 +
112827 +#if defined(CONFIG_COMPAT)
112828 + if (compat)
112829 + {
112830 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
112831 +
112832 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
112833 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112834 + if (!compat_param)
112835 + {
112836 + XX_Free(param);
112837 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112838 + }
112839 +
112840 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112841 + if (copy_from_user(compat_param, (
112842 + ioc_compat_fm_pcd_plcr_profile_params_t *)compat_ptr(arg),
112843 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
112844 + {
112845 + XX_Free(compat_param);
112846 + XX_Free(param);
112847 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112848 + }
112849 +
112850 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_US_TO_K);
112851 +
112852 + XX_Free(compat_param);
112853 + }
112854 + else
112855 +#endif
112856 + {
112857 + if (copy_from_user(param, (ioc_fm_pcd_plcr_profile_params_t *)arg,
112858 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
112859 + {
112860 + XX_Free(param);
112861 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112862 + }
112863 + }
112864 +
112865 + if (!param->modify &&
112866 + (((t_FmPcdPlcrProfileParams*)param)->id.newParams.profileType != e_FM_PCD_PLCR_SHARED))
112867 + {
112868 + t_Handle h_Port;
112869 + ioc_fm_pcd_port_params_t *port_params;
112870 +
112871 + port_params = (ioc_fm_pcd_port_params_t*) XX_Malloc(sizeof(ioc_fm_pcd_port_params_t));
112872 + if (!port_params)
112873 + {
112874 + XX_Free(param);
112875 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112876 + }
112877 +
112878 + memset(port_params, 0, sizeof(ioc_fm_pcd_port_params_t));
112879 + if (copy_from_user(port_params, (ioc_fm_pcd_port_params_t*)((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort,
112880 + sizeof(ioc_fm_pcd_port_params_t)))
112881 + {
112882 + XX_Free(port_params);
112883 + XX_Free(param);
112884 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112885 + }
112886 +
112887 + switch(port_params->port_type)
112888 + {
112889 + case (e_IOC_FM_PORT_TYPE_RX):
112890 + if (port_params->port_id < FM_MAX_NUM_OF_1G_RX_PORTS) {
112891 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
112892 + break;
112893 + }
112894 + goto invalid_port_id;
112895 +
112896 + case (e_IOC_FM_PORT_TYPE_RX_10G):
112897 + if (port_params->port_id < FM_MAX_NUM_OF_10G_RX_PORTS) {
112898 +#ifndef CONFIG_FMAN_ARM
112899 + if (IS_T1023_T1024) {
112900 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
112901 + } else {
112902 +#else
112903 + {
112904 +#endif
112905 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id + FM_MAX_NUM_OF_1G_RX_PORTS].h_Dev;
112906 + }
112907 + break;
112908 + }
112909 + goto invalid_port_id;
112910 +
112911 + case (e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING):
112912 + if (port_params->port_id && port_params->port_id < FM_MAX_NUM_OF_OH_PORTS) {
112913 + h_Port = p_LnxWrpFmDev->opPorts[port_params->port_id - 1].h_Dev;
112914 + break;
112915 + }
112916 + goto invalid_port_id;
112917 +
112918 + default:
112919 +invalid_port_id:
112920 + XX_Free(port_params);
112921 + XX_Free(param);
112922 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
112923 + }
112924 +
112925 + ((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort = h_Port;
112926 + XX_Free(port_params);
112927 + }
112928 +
112929 + param->id = FM_PCD_PlcrProfileSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPlcrProfileParams*)param);
112930 +
112931 + if (!param->id) {
112932 + XX_Free(param);
112933 + err = E_INVALID_VALUE;
112934 + /* Since the LLD has no errno-style error reporting,
112935 + we're left here with no other option than to report
112936 + a generic E_INVALID_VALUE */
112937 + break;
112938 + }
112939 +
112940 +#if defined(CONFIG_COMPAT)
112941 + if (compat)
112942 + {
112943 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
112944 +
112945 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
112946 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112947 + if (!compat_param)
112948 + {
112949 + XX_Free(param);
112950 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112951 + }
112952 +
112953 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112954 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_K_TO_US);
112955 + if (copy_to_user((ioc_compat_fm_pcd_plcr_profile_params_t *) compat_ptr(arg),
112956 + compat_param,
112957 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
112958 + err = E_READ_FAILED;
112959 +
112960 + XX_Free(compat_param);
112961 + }
112962 + else
112963 +#endif
112964 + {
112965 + if (copy_to_user((ioc_fm_pcd_plcr_profile_params_t *)arg,
112966 + param,
112967 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
112968 + err = E_READ_FAILED;
112969 + }
112970 +
112971 + XX_Free(param);
112972 + break;
112973 + }
112974 +
112975 +#if defined(CONFIG_COMPAT)
112976 + case FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT:
112977 +#endif
112978 + case FM_PCD_IOC_PLCR_PROFILE_DELETE:
112979 + {
112980 + ioc_fm_obj_t id;
112981 +
112982 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112983 +
112984 +#if defined(CONFIG_COMPAT)
112985 + if (compat)
112986 + {
112987 + ioc_compat_fm_obj_t compat_id;
112988 +
112989 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112990 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112991 +
112992 + compat_obj_delete(&compat_id, &id);
112993 + }
112994 + else
112995 +#endif
112996 + {
112997 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112998 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112999 + }
113000 +
113001 + err = FM_PCD_PlcrProfileDelete(id.obj);
113002 + break;
113003 + }
113004 +
113005 +#if defined(CONFIG_COMPAT)
113006 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT:
113007 +#endif
113008 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE:
113009 + {
113010 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param;
113011 +
113012 + param = (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
113013 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
113014 + if (!param)
113015 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113016 +
113017 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
113018 +
113019 +#if defined(CONFIG_COMPAT)
113020 + if (compat)
113021 + {
113022 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param;
113023 +
113024 + compat_param = (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
113025 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
113026 + if (!compat_param)
113027 + {
113028 + XX_Free(param);
113029 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113030 + }
113031 +
113032 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
113033 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) compat_ptr(arg),
113034 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)))
113035 + {
113036 + XX_Free(compat_param);
113037 + XX_Free(param);
113038 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113039 + }
113040 +
113041 + compat_fm_pcd_cc_tree_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113042 +
113043 + XX_Free(compat_param);
113044 + }
113045 + else
113046 +#endif
113047 + {
113048 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *)arg,
113049 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t)))
113050 + {
113051 + XX_Free(param);
113052 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113053 + }
113054 + }
113055 +
113056 + err = FM_PCD_CcRootModifyNextEngine(param->id,
113057 + param->grp_indx,
113058 + param->indx,
113059 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113060 +
113061 + XX_Free(param);
113062 + break;
113063 + }
113064 +
113065 +#if defined(CONFIG_COMPAT)
113066 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT:
113067 +#endif
113068 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE:
113069 + {
113070 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
113071 +
113072 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113073 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113074 + if (!param)
113075 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113076 +
113077 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113078 +
113079 +#if defined(CONFIG_COMPAT)
113080 + if (compat)
113081 + {
113082 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
113083 +
113084 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113085 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113086 + if (!compat_param)
113087 + {
113088 + XX_Free(param);
113089 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113090 + }
113091 +
113092 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113093 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
113094 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
113095 + {
113096 + XX_Free(compat_param);
113097 + XX_Free(param);
113098 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113099 + }
113100 +
113101 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113102 +
113103 + XX_Free(compat_param);
113104 + }
113105 + else
113106 +#endif
113107 + {
113108 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *)arg,
113109 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
113110 + {
113111 + XX_Free(param);
113112 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113113 + }
113114 + }
113115 +
113116 + err = FM_PCD_MatchTableModifyNextEngine(param->id,
113117 + param->key_indx,
113118 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113119 +
113120 + XX_Free(param);
113121 + break;
113122 + }
113123 +
113124 +#if defined(CONFIG_COMPAT)
113125 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT:
113126 +#endif
113127 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE:
113128 + {
113129 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
113130 +
113131 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113132 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113133 + if (!param)
113134 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113135 +
113136 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113137 +
113138 +#if defined(CONFIG_COMPAT)
113139 + if (compat)
113140 + {
113141 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
113142 +
113143 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113144 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113145 + if (!compat_param)
113146 + {
113147 + XX_Free(param);
113148 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113149 + }
113150 +
113151 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113152 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
113153 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
113154 + {
113155 + XX_Free(compat_param);
113156 + XX_Free(param);
113157 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113158 + }
113159 +
113160 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113161 +
113162 + XX_Free(compat_param);
113163 + }
113164 + else
113165 +#endif
113166 + {
113167 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) arg,
113168 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
113169 + {
113170 + XX_Free(param);
113171 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113172 + }
113173 + }
113174 +
113175 + err = FM_PCD_MatchTableModifyMissNextEngine(param->id,
113176 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113177 +
113178 + XX_Free(param);
113179 + break;
113180 + }
113181 +
113182 +#if defined(CONFIG_COMPAT)
113183 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT:
113184 +#endif
113185 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY:
113186 + {
113187 + ioc_fm_pcd_cc_node_remove_key_params_t *param;
113188 +
113189 + param = (ioc_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113190 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113191 + if (!param)
113192 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113193 +
113194 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113195 +
113196 +#if defined(CONFIG_COMPAT)
113197 + if (compat)
113198 + {
113199 + ioc_compat_fm_pcd_cc_node_remove_key_params_t *compat_param;
113200 +
113201 + compat_param = (ioc_compat_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113202 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113203 + if (!compat_param)
113204 + {
113205 + XX_Free(param);
113206 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113207 + }
113208 +
113209 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113210 + if (copy_from_user(compat_param,
113211 + (ioc_compat_fm_pcd_cc_node_remove_key_params_t *)compat_ptr(arg),
113212 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t)))
113213 + {
113214 + XX_Free(compat_param);
113215 + XX_Free(param);
113216 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113217 + }
113218 +
113219 + param->id = compat_ptr(compat_param->id);
113220 + param->key_indx = compat_param->key_indx;
113221 +
113222 + XX_Free(compat_param);
113223 + }
113224 + else
113225 +#endif
113226 + {
113227 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_remove_key_params_t *) arg,
113228 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t)))
113229 + {
113230 + XX_Free(param);
113231 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113232 + }
113233 + }
113234 +
113235 + err = FM_PCD_MatchTableRemoveKey(param->id, param->key_indx);
113236 +
113237 + XX_Free(param);
113238 + break;
113239 + }
113240 +#if defined(CONFIG_COMPAT)
113241 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT:
113242 +#endif
113243 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY:
113244 + {
113245 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113246 +
113247 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113248 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113249 + if (!param)
113250 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113251 +
113252 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113253 +
113254 +#if defined(CONFIG_COMPAT)
113255 + if (compat)
113256 + {
113257 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113258 +
113259 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113260 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113261 + if (!compat_param)
113262 + {
113263 + XX_Free(param);
113264 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113265 + }
113266 +
113267 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113268 + if (copy_from_user(compat_param,
113269 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113270 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113271 + {
113272 + XX_Free(compat_param);
113273 + XX_Free(param);
113274 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113275 + }
113276 +
113277 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113278 +
113279 + XX_Free(compat_param);
113280 + }
113281 + else
113282 +#endif
113283 + {
113284 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113285 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113286 + {
113287 + XX_Free(param);
113288 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113289 + }
113290 + }
113291 +
113292 + if (param->key_size)
113293 + {
113294 + int size = 0;
113295 +
113296 + if (param->key_params.p_key) size += param->key_size;
113297 + if (param->key_params.p_mask) size += param->key_size;
113298 +
113299 + if (size)
113300 + {
113301 + uint8_t *p_tmp;
113302 +
113303 + p_tmp = (uint8_t*) XX_Malloc(size);
113304 + if (!p_tmp)
113305 + {
113306 + XX_Free(param);
113307 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
113308 + }
113309 +
113310 + if (param->key_params.p_key)
113311 + {
113312 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
113313 + {
113314 + XX_Free(p_tmp);
113315 + XX_Free(param);
113316 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113317 + }
113318 +
113319 + param->key_params.p_key = p_tmp;
113320 + }
113321 +
113322 + if (param->key_params.p_mask)
113323 + {
113324 + p_tmp += param->key_size;
113325 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
113326 + {
113327 + XX_Free(p_tmp - param->key_size);
113328 + XX_Free(param);
113329 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113330 + }
113331 +
113332 + param->key_params.p_mask = p_tmp;
113333 + }
113334 + }
113335 + }
113336 +
113337 + err = FM_PCD_MatchTableAddKey(
113338 + param->id,
113339 + param->key_indx,
113340 + param->key_size,
113341 + (t_FmPcdCcKeyParams*)&param->key_params);
113342 +
113343 + if (param->key_params.p_key)
113344 + XX_Free(param->key_params.p_key);
113345 + XX_Free(param);
113346 + break;
113347 + }
113348 +
113349 +#if defined(CONFIG_COMPAT)
113350 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT:
113351 +#endif
113352 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE:
113353 + {
113354 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113355 +
113356 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113357 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113358 + if (!param)
113359 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113360 +
113361 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113362 +
113363 +#if defined(CONFIG_COMPAT)
113364 + if (compat)
113365 + {
113366 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113367 +
113368 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113369 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113370 + if (!compat_param)
113371 + {
113372 + XX_Free(param);
113373 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113374 + }
113375 +
113376 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113377 + if (copy_from_user(compat_param,
113378 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113379 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113380 + {
113381 + XX_Free(compat_param);
113382 + XX_Free(param);
113383 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113384 + }
113385 +
113386 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113387 +
113388 + XX_Free(compat_param);
113389 + }
113390 + else
113391 +#endif
113392 + {
113393 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113394 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113395 + {
113396 + XX_Free(param);
113397 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113398 + }
113399 + }
113400 +
113401 + err = FM_PCD_MatchTableModifyKeyAndNextEngine(param->id,
113402 + param->key_indx,
113403 + param->key_size,
113404 + (t_FmPcdCcKeyParams*)(&param->key_params));
113405 +
113406 + XX_Free(param);
113407 + break;
113408 + }
113409 +
113410 +
113411 +#if defined(CONFIG_COMPAT)
113412 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT:
113413 +#endif
113414 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT:
113415 + {
113416 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113417 +
113418 +#if defined(CONFIG_COMPAT)
113419 + if (compat)
113420 + {
113421 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113422 +
113423 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113424 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113425 + if (!compat_param)
113426 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113427 +
113428 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113429 + if (copy_from_user(compat_param,
113430 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113431 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113432 + {
113433 + XX_Free(compat_param);
113434 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113435 + }
113436 +
113437 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113438 +
113439 + XX_Free(compat_param);
113440 + }
113441 + else
113442 +#endif
113443 + {
113444 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113445 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113446 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113447 + }
113448 +
113449 +
113450 + err = FM_PCD_MatchTableGetKeyStatistics((t_Handle) param.id,
113451 + param.key_index,
113452 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113453 +
113454 +#if defined(CONFIG_COMPAT)
113455 + if (compat)
113456 + {
113457 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113458 +
113459 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113460 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113461 + if (!compat_param)
113462 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113463 +
113464 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113465 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113466 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113467 + compat_param,
113468 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113469 + XX_Free(compat_param);
113470 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113471 + }
113472 + XX_Free(compat_param);
113473 + }
113474 + else
113475 +#endif
113476 + {
113477 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113478 + &param,
113479 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113480 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113481 + }
113482 +
113483 + break;
113484 + }
113485 +
113486 +
113487 +#if defined(CONFIG_COMPAT)
113488 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT:
113489 +#endif
113490 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT:
113491 + {
113492 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113493 +
113494 +#if defined(CONFIG_COMPAT)
113495 + if (compat)
113496 + {
113497 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113498 +
113499 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113500 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113501 + if (!compat_param)
113502 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113503 +
113504 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113505 + if (copy_from_user(compat_param,
113506 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113507 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113508 + {
113509 + XX_Free(compat_param);
113510 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113511 + }
113512 +
113513 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113514 +
113515 + XX_Free(compat_param);
113516 + }
113517 + else
113518 +#endif
113519 + {
113520 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113521 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113522 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113523 + }
113524 +
113525 +
113526 + err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id,
113527 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113528 +
113529 +#if defined(CONFIG_COMPAT)
113530 + if (compat)
113531 + {
113532 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113533 +
113534 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113535 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113536 + if (!compat_param)
113537 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113538 +
113539 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113540 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113541 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113542 + compat_param,
113543 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113544 + XX_Free(compat_param);
113545 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113546 + }
113547 + XX_Free(compat_param);
113548 + }
113549 + else
113550 +#endif
113551 + {
113552 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113553 + &param,
113554 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113555 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113556 + }
113557 +
113558 + break;
113559 + }
113560 +
113561 +
113562 +#if defined(CONFIG_COMPAT)
113563 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT:
113564 +#endif
113565 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT:
113566 + {
113567 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113568 +
113569 +#if defined(CONFIG_COMPAT)
113570 + if (compat)
113571 + {
113572 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113573 +
113574 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113575 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113576 + if (!compat_param)
113577 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113578 +
113579 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113580 + if (copy_from_user(compat_param,
113581 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113582 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113583 + {
113584 + XX_Free(compat_param);
113585 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113586 + }
113587 +
113588 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113589 +
113590 + XX_Free(compat_param);
113591 + }
113592 + else
113593 +#endif
113594 + {
113595 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113596 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113597 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113598 + }
113599 +
113600 +
113601 + err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id,
113602 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113603 +
113604 +#if defined(CONFIG_COMPAT)
113605 + if (compat)
113606 + {
113607 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113608 +
113609 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113610 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113611 + if (!compat_param)
113612 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113613 +
113614 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113615 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113616 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113617 + compat_param,
113618 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113619 + XX_Free(compat_param);
113620 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113621 + }
113622 + XX_Free(compat_param);
113623 + }
113624 + else
113625 +#endif
113626 + {
113627 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113628 + &param,
113629 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113630 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113631 + }
113632 +
113633 + break;
113634 + }
113635 +
113636 +#if defined(CONFIG_COMPAT)
113637 + case FM_PCD_IOC_HASH_TABLE_SET_COMPAT:
113638 +#endif
113639 + case FM_PCD_IOC_HASH_TABLE_SET:
113640 + {
113641 + ioc_fm_pcd_hash_table_params_t *param;
113642 +
113643 + param = (ioc_fm_pcd_hash_table_params_t*) XX_Malloc(
113644 + sizeof(ioc_fm_pcd_hash_table_params_t));
113645 + if (!param)
113646 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113647 +
113648 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_params_t));
113649 +
113650 +#if defined(CONFIG_COMPAT)
113651 + if (compat)
113652 + {
113653 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
113654 +
113655 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
113656 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113657 + if (!compat_param)
113658 + {
113659 + XX_Free(param);
113660 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113661 + }
113662 +
113663 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113664 + if (copy_from_user(compat_param,
113665 + (ioc_compat_fm_pcd_hash_table_params_t*)compat_ptr(arg),
113666 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
113667 + {
113668 + XX_Free(compat_param);
113669 + XX_Free(param);
113670 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113671 + }
113672 +
113673 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_US_TO_K);
113674 +
113675 + XX_Free(compat_param);
113676 + }
113677 + else
113678 +#endif
113679 + {
113680 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_params_t *)arg,
113681 + sizeof(ioc_fm_pcd_hash_table_params_t)))
113682 + {
113683 + XX_Free(param);
113684 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113685 + }
113686 + }
113687 +
113688 + param->id = FM_PCD_HashTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdHashTableParams *) param);
113689 +
113690 + if (!param->id)
113691 + {
113692 + XX_Free(param);
113693 + err = E_INVALID_VALUE;
113694 + /* Since the LLD has no errno-style error reporting,
113695 + we're left here with no other option than to report
113696 + a generic E_INVALID_VALUE */
113697 + break;
113698 + }
113699 +
113700 +#if defined(CONFIG_COMPAT)
113701 + if (compat)
113702 + {
113703 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
113704 +
113705 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
113706 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113707 + if (!compat_param)
113708 + {
113709 + XX_Free(param);
113710 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113711 + }
113712 +
113713 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113714 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_K_TO_US);
113715 + if (copy_to_user((ioc_compat_fm_pcd_hash_table_params_t*) compat_ptr(arg),
113716 + compat_param,
113717 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
113718 + err = E_READ_FAILED;
113719 +
113720 + XX_Free(compat_param);
113721 + }
113722 + else
113723 +#endif
113724 + {
113725 + if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg,
113726 + param,
113727 + sizeof(ioc_fm_pcd_hash_table_params_t)))
113728 + err = E_READ_FAILED;
113729 + }
113730 +
113731 + XX_Free(param);
113732 + break;
113733 + }
113734 +
113735 +#if defined(CONFIG_COMPAT)
113736 + case FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT:
113737 +#endif
113738 + case FM_PCD_IOC_HASH_TABLE_DELETE:
113739 + {
113740 + ioc_fm_obj_t id;
113741 +
113742 + memset(&id, 0, sizeof(ioc_fm_obj_t));
113743 +
113744 +#if defined(CONFIG_COMPAT)
113745 + if (compat)
113746 + {
113747 + ioc_compat_fm_obj_t compat_id;
113748 +
113749 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113750 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113751 +
113752 + id.obj = compat_pcd_id2ptr(compat_id.obj);
113753 + }
113754 + else
113755 +#endif
113756 + {
113757 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113758 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113759 + }
113760 +
113761 + err = FM_PCD_HashTableDelete(id.obj);
113762 + break;
113763 + }
113764 +
113765 +#if defined(CONFIG_COMPAT)
113766 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT:
113767 +#endif
113768 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY:
113769 + {
113770 + ioc_fm_pcd_hash_table_add_key_params_t *param = NULL;
113771 +
113772 + param = (ioc_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
113773 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
113774 + if (!param)
113775 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113776 +
113777 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
113778 +
113779 +#if defined(CONFIG_COMPAT)
113780 + if (compat)
113781 + {
113782 + ioc_compat_fm_pcd_hash_table_add_key_params_t *compat_param;
113783 +
113784 + compat_param = (ioc_compat_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
113785 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
113786 + if (!compat_param)
113787 + {
113788 + XX_Free(param);
113789 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113790 + }
113791 +
113792 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
113793 + if (copy_from_user(compat_param,
113794 + (ioc_compat_fm_pcd_hash_table_add_key_params_t*) compat_ptr(arg),
113795 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t)))
113796 + {
113797 + XX_Free(compat_param);
113798 + XX_Free(param);
113799 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113800 + }
113801 +
113802 + if (compat_param->key_size)
113803 + {
113804 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
113805 + param->key_size = compat_param->key_size;
113806 +
113807 + compat_copy_fm_pcd_cc_key(&compat_param->key_params, &param->key_params, COMPAT_US_TO_K);
113808 + }
113809 + else
113810 + {
113811 + XX_Free(compat_param);
113812 + XX_Free(param);
113813 + err = E_INVALID_VALUE;
113814 + break;
113815 + }
113816 +
113817 + XX_Free(compat_param);
113818 + }
113819 + else
113820 +#endif
113821 + {
113822 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_add_key_params_t*) arg,
113823 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t)))
113824 + {
113825 + XX_Free(param);
113826 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113827 + }
113828 + }
113829 +
113830 + if (param->key_size)
113831 + {
113832 + int size = 0;
113833 +
113834 + if (param->key_params.p_key) size += param->key_size;
113835 + if (param->key_params.p_mask) size += param->key_size;
113836 +
113837 + if (size)
113838 + {
113839 + uint8_t *p_tmp;
113840 +
113841 + p_tmp = (uint8_t*) XX_Malloc(size);
113842 + if (!p_tmp)
113843 + {
113844 + XX_Free(param);
113845 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
113846 + }
113847 +
113848 + if (param->key_params.p_key)
113849 + {
113850 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
113851 + {
113852 + XX_Free(p_tmp);
113853 + XX_Free(param);
113854 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113855 + }
113856 +
113857 + param->key_params.p_key = p_tmp;
113858 + }
113859 +
113860 + if (param->key_params.p_mask)
113861 + {
113862 + p_tmp += param->key_size;
113863 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
113864 + {
113865 + XX_Free(p_tmp - param->key_size);
113866 + XX_Free(param);
113867 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113868 + }
113869 +
113870 + param->key_params.p_mask = p_tmp;
113871 + }
113872 + }
113873 + }
113874 +
113875 + err = FM_PCD_HashTableAddKey(
113876 + param->p_hash_tbl,
113877 + param->key_size,
113878 + (t_FmPcdCcKeyParams*)&param->key_params);
113879 +
113880 + if (param->key_params.p_key)
113881 + XX_Free(param->key_params.p_key);
113882 + XX_Free(param);
113883 + break;
113884 + }
113885 +
113886 +#if defined(CONFIG_COMPAT)
113887 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT:
113888 +#endif
113889 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY:
113890 + {
113891 + ioc_fm_pcd_hash_table_remove_key_params_t *param = NULL;
113892 +
113893 + param = (ioc_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
113894 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
113895 + if (!param)
113896 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113897 +
113898 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
113899 +
113900 +#if defined(CONFIG_COMPAT)
113901 + if (compat)
113902 + {
113903 + ioc_compat_fm_pcd_hash_table_remove_key_params_t *compat_param;
113904 +
113905 + compat_param = (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
113906 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
113907 + if (!compat_param)
113908 + {
113909 + XX_Free(param);
113910 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113911 + }
113912 +
113913 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
113914 + if (copy_from_user(compat_param,
113915 + (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) compat_ptr(arg),
113916 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t)))
113917 + {
113918 + XX_Free(compat_param);
113919 + XX_Free(param);
113920 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113921 + }
113922 +
113923 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
113924 + param->key_size = compat_param->key_size;
113925 +
113926 + XX_Free(compat_param);
113927 + }
113928 + else
113929 +#endif
113930 + {
113931 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_remove_key_params_t*)arg,
113932 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t)))
113933 + {
113934 + XX_Free(param);
113935 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113936 + }
113937 + }
113938 +
113939 + if (param->key_size)
113940 + {
113941 + uint8_t *p_key;
113942 +
113943 + p_key = (uint8_t*) XX_Malloc(param->key_size);
113944 + if (!p_key)
113945 + {
113946 + XX_Free(param);
113947 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113948 + }
113949 +
113950 + if (param->p_key && copy_from_user(p_key, param->p_key, param->key_size))
113951 + {
113952 + XX_Free(p_key);
113953 + XX_Free(param);
113954 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113955 + }
113956 + param->p_key = p_key;
113957 + }
113958 +
113959 + err = FM_PCD_HashTableRemoveKey(
113960 + param->p_hash_tbl,
113961 + param->key_size,
113962 + param->p_key);
113963 +
113964 + if (param->p_key)
113965 + XX_Free(param->p_key);
113966 + XX_Free(param);
113967 + break;
113968 + }
113969 +
113970 +#if defined(CONFIG_COMPAT)
113971 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT:
113972 +#endif
113973 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY:
113974 + {
113975 + ioc_fm_pcd_cc_node_modify_key_params_t *param;
113976 +
113977 + param = (ioc_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
113978 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
113979 + if (!param)
113980 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113981 +
113982 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
113983 +
113984 +#if defined(CONFIG_COMPAT)
113985 + if (compat)
113986 + {
113987 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param;
113988 +
113989 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
113990 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
113991 + if (!compat_param)
113992 + {
113993 + XX_Free(param);
113994 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113995 + }
113996 +
113997 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
113998 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_key_params_t *)compat_ptr(arg),
113999 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t)))
114000 + {
114001 + XX_Free(compat_param);
114002 + XX_Free(param);
114003 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114004 + }
114005 +
114006 + compat_copy_fm_pcd_cc_node_modify_key(compat_param, param, COMPAT_US_TO_K);
114007 +
114008 + XX_Free(compat_param);
114009 + }
114010 + else
114011 +#endif
114012 + {
114013 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_params_t *)arg,
114014 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t)))
114015 + {
114016 + XX_Free(param);
114017 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114018 + }
114019 + }
114020 +
114021 + if (param->key_size)
114022 + {
114023 + int size = 0;
114024 +
114025 + if (param->p_key) size += param->key_size;
114026 + if (param->p_mask) size += param->key_size;
114027 +
114028 + if (size)
114029 + {
114030 + uint8_t *p_tmp;
114031 +
114032 + p_tmp = (uint8_t*) XX_Malloc(size);
114033 + if (!p_tmp)
114034 + {
114035 + XX_Free(param);
114036 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
114037 + }
114038 +
114039 + if (param->p_key)
114040 + {
114041 + if (copy_from_user(p_tmp, param->p_key, param->key_size))
114042 + {
114043 + XX_Free(p_tmp);
114044 + XX_Free(param);
114045 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114046 + }
114047 +
114048 + param->p_key = p_tmp;
114049 + }
114050 +
114051 + if (param->p_mask)
114052 + {
114053 + p_tmp += param->key_size;
114054 + if (copy_from_user(p_tmp, param->p_mask, param->key_size))
114055 + {
114056 + XX_Free(p_tmp - param->key_size);
114057 + XX_Free(param);
114058 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114059 + }
114060 +
114061 + param->p_mask = p_tmp;
114062 + }
114063 + }
114064 + }
114065 +
114066 + err = FM_PCD_MatchTableModifyKey(param->id,
114067 + param->key_indx,
114068 + param->key_size,
114069 + param->p_key,
114070 + param->p_mask);
114071 +
114072 + if (param->p_key)
114073 + XX_Free(param->p_key);
114074 + else if (param->p_mask)
114075 + XX_Free(param->p_mask);
114076 + XX_Free(param);
114077 + break;
114078 + }
114079 +
114080 +#if defined(CONFIG_COMPAT)
114081 + case FM_PCD_IOC_MANIP_NODE_SET_COMPAT:
114082 +#endif
114083 + case FM_PCD_IOC_MANIP_NODE_SET:
114084 + {
114085 + ioc_fm_pcd_manip_params_t *param;
114086 + uint8_t *p_data = NULL;
114087 + uint8_t size;
114088 +
114089 + param = (ioc_fm_pcd_manip_params_t *) XX_Malloc(
114090 + sizeof(ioc_fm_pcd_manip_params_t));
114091 +
114092 + if (!param)
114093 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114094 +
114095 + memset(param, 0, sizeof(ioc_fm_pcd_manip_params_t));
114096 +
114097 +#if defined(CONFIG_COMPAT)
114098 + if (compat)
114099 + {
114100 + ioc_compat_fm_pcd_manip_params_t *compat_param;
114101 +
114102 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
114103 + sizeof(ioc_compat_fm_pcd_manip_params_t));
114104 + if (!compat_param)
114105 + {
114106 + XX_Free(param);
114107 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114108 + }
114109 +
114110 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
114111 + if (copy_from_user(compat_param,
114112 + (ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
114113 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
114114 + {
114115 + XX_Free(compat_param);
114116 + XX_Free(param);
114117 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114118 + }
114119 +
114120 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_US_TO_K);
114121 +
114122 + XX_Free(compat_param);
114123 + }
114124 + else
114125 +#endif
114126 + {
114127 + if (copy_from_user(param, (ioc_fm_pcd_manip_params_t *)arg,
114128 + sizeof(ioc_fm_pcd_manip_params_t)))
114129 + {
114130 + XX_Free(param);
114131 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114132 + }
114133 + }
114134 +
114135 + if (param->type == e_IOC_FM_PCD_MANIP_HDR)
114136 + {
114137 + size = param->u.hdr.insrt_params.u.generic.size;
114138 + p_data = (uint8_t *) XX_Malloc(size);
114139 + if (!p_data )
114140 + {
114141 + XX_Free(param);
114142 + RETURN_ERROR(MINOR, E_NO_MEMORY, NO_MSG);
114143 + }
114144 +
114145 + if (param->u.hdr.insrt_params.u.generic.p_data &&
114146 + copy_from_user(p_data,
114147 + param->u.hdr.insrt_params.u.generic.p_data, size))
114148 + {
114149 + XX_Free(p_data);
114150 + XX_Free(param);
114151 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114152 + }
114153 +
114154 + param->u.hdr.insrt_params.u.generic.p_data = p_data;
114155 + }
114156 +
114157 + if (param->id)
114158 + {
114159 + /* Security Hole: the user can pass any piece of garbage
114160 + in 'param->id', and that will go straight through to the LLD,
114161 + no checks being done by the wrapper! */
114162 + err = FM_PCD_ManipNodeReplace(
114163 + (t_Handle) param->id,
114164 + (t_FmPcdManipParams*) param);
114165 + if (err)
114166 + {
114167 + if (p_data)
114168 + XX_Free(p_data);
114169 + XX_Free(param);
114170 + break;
114171 + }
114172 + }
114173 + else
114174 + {
114175 + param->id = FM_PCD_ManipNodeSet(
114176 + p_LnxWrpFmDev->h_PcdDev,
114177 + (t_FmPcdManipParams*) param);
114178 + if (!param->id)
114179 + {
114180 + if (p_data)
114181 + XX_Free(p_data);
114182 + XX_Free(param);
114183 + err = E_INVALID_VALUE;
114184 + /* Since the LLD has no errno-style error reporting,
114185 + we're left here with no other option than to report
114186 + a generic E_INVALID_VALUE */
114187 + break;
114188 + }
114189 + }
114190 +
114191 +#if defined(CONFIG_COMPAT)
114192 + if (compat)
114193 + {
114194 + ioc_compat_fm_pcd_manip_params_t *compat_param;
114195 +
114196 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
114197 + sizeof(ioc_compat_fm_pcd_manip_params_t));
114198 + if (!compat_param)
114199 + {
114200 + if (p_data)
114201 + XX_Free(p_data);
114202 + XX_Free(param);
114203 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114204 + }
114205 +
114206 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
114207 +
114208 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_K_TO_US);
114209 +
114210 + if (copy_to_user((ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
114211 + compat_param,
114212 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
114213 + err = E_READ_FAILED;
114214 +
114215 + XX_Free(compat_param);
114216 + }
114217 + else
114218 +#endif
114219 + {
114220 + if (copy_to_user((ioc_fm_pcd_manip_params_t *)arg,
114221 + param, sizeof(ioc_fm_pcd_manip_params_t)))
114222 + err = E_READ_FAILED;
114223 + }
114224 +
114225 + if (p_data)
114226 + XX_Free(p_data);
114227 + XX_Free(param);
114228 + break;
114229 + }
114230 +
114231 +#if defined(CONFIG_COMPAT)
114232 + case FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT:
114233 +#endif
114234 + case FM_PCD_IOC_MANIP_NODE_DELETE:
114235 + {
114236 + ioc_fm_obj_t id;
114237 +
114238 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114239 +#if defined(CONFIG_COMPAT)
114240 + if (compat)
114241 + {
114242 + ioc_compat_fm_obj_t compat_id;
114243 +
114244 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114245 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114246 +
114247 + compat_obj_delete(&compat_id, &id);
114248 + }
114249 + else
114250 +#endif
114251 + {
114252 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114253 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114254 + }
114255 +
114256 + err = FM_PCD_ManipNodeDelete(id.obj);
114257 + break;
114258 + }
114259 +
114260 +#if defined(CONFIG_COMPAT)
114261 + case FM_PCD_IOC_MANIP_GET_STATS_COMPAT:
114262 +#endif
114263 + case FM_PCD_IOC_MANIP_GET_STATS:
114264 + {
114265 + ioc_fm_pcd_manip_get_stats_t param;
114266 +
114267 +#if defined(CONFIG_COMPAT)
114268 + if (compat)
114269 + {
114270 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114271 +
114272 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t *) XX_Malloc(
114273 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114274 + if (!compat_param)
114275 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114276 +
114277 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114278 + if (copy_from_user(compat_param,
114279 + (ioc_compat_fm_pcd_manip_get_stats_t *)compat_ptr(arg),
114280 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t)))
114281 + {
114282 + XX_Free(compat_param);
114283 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114284 + }
114285 +
114286 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_US_TO_K);
114287 +
114288 + XX_Free(compat_param);
114289 + }
114290 + else
114291 +#endif
114292 + {
114293 + if (copy_from_user(&param, (ioc_fm_pcd_manip_get_stats_t *)arg,
114294 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114295 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114296 + }
114297 +
114298 + err = FM_PCD_ManipGetStatistics((t_Handle) param.id,
114299 + (t_FmPcdManipStats*) &param.stats);
114300 +
114301 +#if defined(CONFIG_COMPAT)
114302 + if (compat)
114303 + {
114304 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114305 +
114306 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t*) XX_Malloc(
114307 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114308 + if (!compat_param)
114309 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114310 +
114311 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114312 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_K_TO_US);
114313 + if (copy_to_user((ioc_compat_fm_pcd_manip_get_stats_t*) compat_ptr(arg),
114314 + compat_param,
114315 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t))){
114316 + XX_Free(compat_param);
114317 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114318 + }
114319 + XX_Free(compat_param);
114320 + }
114321 + else
114322 +#endif
114323 + if (copy_to_user((ioc_fm_pcd_manip_get_stats_t *)arg,
114324 + &param,
114325 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114326 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114327 +
114328 + break;
114329 + }
114330 +
114331 +#if (DPAA_VERSION >= 11)
114332 +#if defined(CONFIG_COMPAT)
114333 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT:
114334 +#endif
114335 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET:
114336 + {
114337 + ioc_fm_pcd_frm_replic_group_params_t *param;
114338 +
114339 + param = (ioc_fm_pcd_frm_replic_group_params_t *) XX_Malloc(
114340 + sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114341 + if (!param)
114342 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114343 +
114344 + memset(param, 0, sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114345 +
114346 +#if defined(CONFIG_COMPAT)
114347 + if (compat)
114348 + {
114349 + ioc_compat_fm_pcd_frm_replic_group_params_t
114350 + *compat_param;
114351 +
114352 + compat_param =
114353 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114354 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114355 + if (!compat_param)
114356 + {
114357 + XX_Free(param);
114358 + RETURN_ERROR(MINOR, E_NO_MEMORY,
114359 + ("IOCTL FM PCD"));
114360 + }
114361 +
114362 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114363 + if (copy_from_user(compat_param,
114364 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114365 + compat_ptr(arg),
114366 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t))) {
114367 + XX_Free(compat_param);
114368 + XX_Free(param);
114369 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114370 + }
114371 +
114372 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
114373 + param, COMPAT_US_TO_K);
114374 +
114375 + XX_Free(compat_param);
114376 + }
114377 + else
114378 +#endif
114379 + {
114380 + if (copy_from_user(param,
114381 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
114382 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
114383 + {
114384 + XX_Free(param);
114385 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114386 + }
114387 + }
114388 +
114389 + param->id = FM_PCD_FrmReplicSetGroup(p_LnxWrpFmDev->h_PcdDev,
114390 + (t_FmPcdFrmReplicGroupParams*)param);
114391 +
114392 + if (!param->id) {
114393 + XX_Free(param);
114394 + err = E_INVALID_VALUE;
114395 + /*
114396 + * Since the LLD has no errno-style error reporting,
114397 + * we're left here with no other option than to report
114398 + * a generic E_INVALID_VALUE
114399 + */
114400 + break;
114401 + }
114402 +
114403 +#if defined(CONFIG_COMPAT)
114404 + if (compat)
114405 + {
114406 + ioc_compat_fm_pcd_frm_replic_group_params_t
114407 + *compat_param;
114408 +
114409 + compat_param =
114410 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114411 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114412 + if (!compat_param)
114413 + {
114414 + XX_Free(param);
114415 + RETURN_ERROR(MINOR, E_NO_MEMORY,
114416 + ("IOCTL FM PCD"));
114417 + }
114418 +
114419 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114420 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
114421 + param, COMPAT_K_TO_US);
114422 + if (copy_to_user(
114423 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114424 + compat_ptr(arg),
114425 + compat_param,
114426 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)))
114427 + err = E_WRITE_FAILED;
114428 +
114429 + XX_Free(compat_param);
114430 + }
114431 + else
114432 +#endif
114433 + {
114434 + if (copy_to_user(
114435 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
114436 + param,
114437 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
114438 + err = E_WRITE_FAILED;
114439 + }
114440 +
114441 + XX_Free(param);
114442 + break;
114443 + }
114444 + break;
114445 +
114446 +#if defined(CONFIG_COMPAT)
114447 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT:
114448 +#endif
114449 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE:
114450 + {
114451 + ioc_fm_obj_t id;
114452 +
114453 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114454 +#if defined(CONFIG_COMPAT)
114455 + if (compat)
114456 + {
114457 + ioc_compat_fm_obj_t compat_id;
114458 +
114459 + if (copy_from_user(&compat_id,
114460 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114461 + sizeof(ioc_compat_fm_obj_t)))
114462 + break;
114463 + compat_obj_delete(&compat_id, &id);
114464 + }
114465 + else
114466 +#endif
114467 + {
114468 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114469 + sizeof(ioc_fm_obj_t)))
114470 + break;
114471 + }
114472 +
114473 + return FM_PCD_FrmReplicDeleteGroup(id.obj);
114474 + }
114475 + break;
114476 +
114477 +#if defined(CONFIG_COMPAT)
114478 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT:
114479 +#endif
114480 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD:
114481 + {
114482 + ioc_fm_pcd_frm_replic_member_params_t param;
114483 +
114484 +#if defined(CONFIG_COMPAT)
114485 + if (compat)
114486 + {
114487 + ioc_compat_fm_pcd_frm_replic_member_params_t compat_param;
114488 +
114489 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114490 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114491 +
114492 + compat_copy_fm_pcd_frm_replic_member_params(&compat_param, &param, COMPAT_US_TO_K);
114493 + }
114494 + else
114495 +#endif
114496 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114497 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114498 +
114499 + return FM_PCD_FrmReplicAddMember(param.member.h_replic_group,
114500 + param.member.member_index,
114501 + (t_FmPcdCcNextEngineParams*)&param.next_engine_params);
114502 + }
114503 + break;
114504 +
114505 +#if defined(CONFIG_COMPAT)
114506 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT:
114507 +#endif
114508 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE:
114509 + {
114510 + ioc_fm_pcd_frm_replic_member_t param;
114511 +
114512 +#if defined(CONFIG_COMPAT)
114513 + if (compat)
114514 + {
114515 + ioc_compat_fm_pcd_frm_replic_member_t compat_param;
114516 +
114517 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114518 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114519 +
114520 + compat_copy_fm_pcd_frm_replic_member(&compat_param, &param, COMPAT_US_TO_K);
114521 + }
114522 + else
114523 +#endif
114524 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114525 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114526 +
114527 + return FM_PCD_FrmReplicRemoveMember(param.h_replic_group, param.member_index);
114528 + }
114529 + break;
114530 +
114531 +#if defined(CONFIG_COMPAT)
114532 + case FM_IOC_VSP_CONFIG_COMPAT:
114533 +#endif
114534 + case FM_IOC_VSP_CONFIG:
114535 + {
114536 + ioc_fm_vsp_params_t param;
114537 +
114538 +#if defined(CONFIG_COMPAT)
114539 + if (compat)
114540 + {
114541 + ioc_compat_fm_vsp_params_t compat_param;
114542 +
114543 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114544 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114545 +
114546 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_US_TO_K);
114547 + }
114548 + else
114549 +#endif
114550 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114551 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114552 + {
114553 + uint8_t portId = param.port_params.port_id;
114554 + param.liodn_offset =
114555 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
114556 + }
114557 + param.p_fm = p_LnxWrpFmDev->h_Dev;
114558 + param.id = FM_VSP_Config((t_FmVspParams *)&param);
114559 +
114560 +#if defined(CONFIG_COMPAT)
114561 + if (compat)
114562 + {
114563 + ioc_compat_fm_vsp_params_t compat_param;
114564 +
114565 + memset(&compat_param, 0, sizeof(compat_param));
114566 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_K_TO_US);
114567 +
114568 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
114569 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114570 + }
114571 + else
114572 +#endif
114573 + if (copy_to_user((void *)arg, &param, sizeof(param)))
114574 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114575 + break;
114576 + }
114577 +
114578 +#if defined(CONFIG_COMPAT)
114579 + case FM_IOC_VSP_INIT_COMPAT:
114580 +#endif
114581 + case FM_IOC_VSP_INIT:
114582 + {
114583 + ioc_fm_obj_t id;
114584 +
114585 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114586 +#if defined(CONFIG_COMPAT)
114587 + if (compat)
114588 + {
114589 + ioc_compat_fm_obj_t compat_id;
114590 +
114591 + if (copy_from_user(&compat_id,
114592 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114593 + sizeof(ioc_compat_fm_obj_t)))
114594 + break;
114595 + id.obj = compat_pcd_id2ptr(compat_id.obj);
114596 + }
114597 + else
114598 +#endif
114599 + {
114600 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114601 + sizeof(ioc_fm_obj_t)))
114602 + break;
114603 + }
114604 +
114605 + return FM_VSP_Init(id.obj);
114606 + }
114607 +
114608 +#if defined(CONFIG_COMPAT)
114609 + case FM_IOC_VSP_FREE_COMPAT:
114610 +#endif
114611 + case FM_IOC_VSP_FREE:
114612 + {
114613 + ioc_fm_obj_t id;
114614 +
114615 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114616 +#if defined(CONFIG_COMPAT)
114617 + if (compat)
114618 + {
114619 + ioc_compat_fm_obj_t compat_id;
114620 +
114621 + if (copy_from_user(&compat_id,
114622 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114623 + sizeof(ioc_compat_fm_obj_t)))
114624 + break;
114625 + compat_obj_delete(&compat_id, &id);
114626 + }
114627 + else
114628 +#endif
114629 + {
114630 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114631 + sizeof(ioc_fm_obj_t)))
114632 + break;
114633 + }
114634 +
114635 + return FM_VSP_Free(id.obj);
114636 + }
114637 +
114638 +#if defined(CONFIG_COMPAT)
114639 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT:
114640 +#endif
114641 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION:
114642 + {
114643 + ioc_fm_buf_pool_depletion_params_t param;
114644 +
114645 +#if defined(CONFIG_COMPAT)
114646 + if (compat)
114647 + {
114648 + ioc_compat_fm_buf_pool_depletion_params_t compat_param;
114649 +
114650 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114651 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114652 +
114653 + compat_copy_fm_buf_pool_depletion_params(&compat_param, &param, COMPAT_US_TO_K);
114654 + }
114655 + else
114656 +#endif
114657 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114658 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114659 +
114660 + if (FM_VSP_ConfigPoolDepletion(param.p_fm_vsp,
114661 + (t_FmBufPoolDepletion *)&param.fm_buf_pool_depletion))
114662 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114663 +
114664 + break;
114665 + }
114666 +
114667 +
114668 +#if defined(CONFIG_COMPAT)
114669 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT:
114670 +#endif
114671 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT:
114672 + {
114673 + ioc_fm_buffer_prefix_content_params_t param;
114674 +
114675 +#if defined(CONFIG_COMPAT)
114676 + if (compat)
114677 + {
114678 + ioc_compat_fm_buffer_prefix_content_params_t compat_param;
114679 +
114680 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114681 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114682 +
114683 + compat_copy_fm_buffer_prefix_content_params(&compat_param, &param, COMPAT_US_TO_K);
114684 + }
114685 + else
114686 +#endif
114687 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114688 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114689 +
114690 + if (FM_VSP_ConfigBufferPrefixContent(param.p_fm_vsp,
114691 + (t_FmBufferPrefixContent *)&param.fm_buffer_prefix_content))
114692 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114693 +
114694 + break;
114695 + }
114696 +
114697 +#if defined(CONFIG_COMPAT)
114698 + case FM_IOC_VSP_CONFIG_NO_SG_COMPAT:
114699 +#endif
114700 + case FM_IOC_VSP_CONFIG_NO_SG:
114701 + {
114702 + ioc_fm_vsp_config_no_sg_params_t param;
114703 +
114704 +#if defined(CONFIG_COMPAT)
114705 + if (compat)
114706 + {
114707 + ioc_compat_fm_vsp_config_no_sg_params_t compat_param;
114708 +
114709 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114710 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114711 +
114712 + compat_copy_fm_vsp_config_no_sg_params(&compat_param, &param, COMPAT_US_TO_K);
114713 + }
114714 + else
114715 +#endif
114716 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114717 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114718 +
114719 + if (FM_VSP_ConfigNoScatherGather(param.p_fm_vsp, param.no_sg))
114720 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114721 +
114722 + break;
114723 + }
114724 +
114725 +#if defined(CONFIG_COMPAT)
114726 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT:
114727 +#endif
114728 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT:
114729 + {
114730 + ioc_fm_vsp_prs_result_params_t param;
114731 +
114732 +#if defined(CONFIG_COMPAT)
114733 + if (compat)
114734 + {
114735 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
114736 +
114737 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114738 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114739 +
114740 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_US_TO_K);
114741 + }
114742 + else
114743 +#endif
114744 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114745 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114746 +
114747 + /* this call just adds the parse results offset to p_data */
114748 + param.p_data = FM_VSP_GetBufferPrsResult(param.p_fm_vsp, param.p_data);
114749 +
114750 + if (!param.p_data)
114751 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114752 +
114753 +#if defined(CONFIG_COMPAT)
114754 + if (compat)
114755 + {
114756 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
114757 +
114758 + memset(&compat_param, 0, sizeof(compat_param));
114759 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_K_TO_US);
114760 +
114761 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
114762 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114763 + }
114764 + else
114765 +#endif
114766 + if (copy_to_user((void *)arg, &param, sizeof(param)))
114767 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114768 +
114769 + break;
114770 + }
114771 +#endif /* (DPAA_VERSION >= 11) */
114772 +
114773 +#ifdef FM_CAPWAP_SUPPORT
114774 +#warning "feature not supported!"
114775 +#if defined(CONFIG_COMPAT)
114776 + case FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT:
114777 +#endif
114778 + case FM_PCD_IOC_STATISTICS_SET_NODE:
114779 + {
114780 +/* ioc_fm_pcd_stats_params_t param;
114781 + ...
114782 + param->id = FM_PCD_StatisticsSetNode(p_LnxWrpFmDev->h_PcdDev,
114783 + (t_FmPcdStatsParams *)&param);
114784 +*/
114785 + err = E_NOT_SUPPORTED;
114786 + break;
114787 + }
114788 +#endif /* FM_CAPWAP_SUPPORT */
114789 +
114790 + default:
114791 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
114792 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr: %d.\n",
114793 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
114794 + }
114795 +
114796 + if (err)
114797 + RETURN_ERROR(MINOR, err, ("IOCTL FM PCD"));
114798 +
114799 + return E_OK;
114800 +}
114801 +
114802 +void FM_Get_Api_Version(ioc_fm_api_version_t *p_version)
114803 +{
114804 + p_version->version.major = FMD_API_VERSION_MAJOR;
114805 + p_version->version.minor = FMD_API_VERSION_MINOR;
114806 + p_version->version.respin = FMD_API_VERSION_RESPIN;
114807 + p_version->version.reserved = 0;
114808 +}
114809 +
114810 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
114811 +{
114812 + t_Error err = E_OK;
114813 +
114814 + switch (cmd)
114815 + {
114816 + case FM_IOC_SET_PORTS_BANDWIDTH:
114817 + {
114818 + ioc_fm_port_bandwidth_params *param;
114819 +
114820 + param = (ioc_fm_port_bandwidth_params*) XX_Malloc(sizeof(ioc_fm_port_bandwidth_params));
114821 + if (!param)
114822 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114823 +
114824 + memset(param, 0, sizeof(ioc_fm_port_bandwidth_params));
114825 +
114826 +#if defined(CONFIG_COMPAT)
114827 + if (compat)
114828 + {
114829 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)compat_ptr(arg), sizeof(ioc_fm_port_bandwidth_params)))
114830 + {
114831 + XX_Free(param);
114832 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114833 + }
114834 + }
114835 + else
114836 +#endif
114837 + {
114838 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)arg, sizeof(ioc_fm_port_bandwidth_params)))
114839 + {
114840 + XX_Free(param);
114841 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114842 + }
114843 + }
114844 +
114845 + err = FM_SetPortsBandwidth(p_LnxWrpFmDev->h_Dev, (t_FmPortsBandwidthParams*) param);
114846 +
114847 + XX_Free(param);
114848 + break;
114849 + }
114850 +
114851 + case FM_IOC_GET_REVISION:
114852 + {
114853 + ioc_fm_revision_info_t *param;
114854 +
114855 + param = (ioc_fm_revision_info_t *) XX_Malloc(sizeof(ioc_fm_revision_info_t));
114856 + if (!param)
114857 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114858 +
114859 + FM_GetRevision(p_LnxWrpFmDev->h_Dev, (t_FmRevisionInfo*)param);
114860 + /* This one never returns anything other than E_OK */
114861 +
114862 +#if defined(CONFIG_COMPAT)
114863 + if (compat)
114864 + {
114865 + if (copy_to_user((ioc_fm_revision_info_t *)compat_ptr(arg),
114866 + param,
114867 + sizeof(ioc_fm_revision_info_t))){
114868 + XX_Free(param);
114869 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114870 + }
114871 + }
114872 + else
114873 +#endif
114874 + {
114875 + if (copy_to_user((ioc_fm_revision_info_t *)arg,
114876 + param,
114877 + sizeof(ioc_fm_revision_info_t))){
114878 + XX_Free(param);
114879 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114880 + }
114881 + }
114882 + XX_Free(param);
114883 + break;
114884 + }
114885 +
114886 + case FM_IOC_SET_COUNTER:
114887 + {
114888 + ioc_fm_counters_params_t *param;
114889 +
114890 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
114891 + if (!param)
114892 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114893 +
114894 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
114895 +
114896 +#if defined(CONFIG_COMPAT)
114897 + if (compat)
114898 + {
114899 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
114900 + {
114901 + XX_Free(param);
114902 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114903 + }
114904 + }
114905 + else
114906 +#endif
114907 + {
114908 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
114909 + {
114910 + XX_Free(param);
114911 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114912 + }
114913 + }
114914 +
114915 + err = FM_ModifyCounter(p_LnxWrpFmDev->h_Dev, param->cnt, param->val);
114916 +
114917 + XX_Free(param);
114918 + break;
114919 + }
114920 +
114921 + case FM_IOC_GET_COUNTER:
114922 + {
114923 + ioc_fm_counters_params_t *param;
114924 +
114925 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
114926 + if (!param)
114927 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114928 +
114929 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
114930 +
114931 +#if defined(CONFIG_COMPAT)
114932 + if (compat)
114933 + {
114934 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
114935 + {
114936 + XX_Free(param);
114937 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114938 + }
114939 + }
114940 + else
114941 +#endif
114942 + {
114943 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
114944 + {
114945 + XX_Free(param);
114946 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114947 + }
114948 + }
114949 +
114950 + param->val = FM_GetCounter(p_LnxWrpFmDev->h_Dev, param->cnt);
114951 +
114952 +#if defined(CONFIG_COMPAT)
114953 + if (compat)
114954 + {
114955 + if (copy_to_user((ioc_fm_counters_params_t *)compat_ptr(arg), param, sizeof(ioc_fm_counters_params_t)))
114956 + err = E_READ_FAILED;
114957 + }
114958 + else
114959 +#endif
114960 + {
114961 + if (copy_to_user((ioc_fm_counters_params_t *)arg, param, sizeof(ioc_fm_counters_params_t)))
114962 + err = E_READ_FAILED;
114963 + }
114964 +
114965 + XX_Free(param);
114966 + break;
114967 + }
114968 +
114969 + case FM_IOC_FORCE_INTR:
114970 + {
114971 + ioc_fm_exceptions param;
114972 +
114973 +#if defined(CONFIG_COMPAT)
114974 + if (compat)
114975 + {
114976 + if (get_user(param, (ioc_fm_exceptions*) compat_ptr(arg)))
114977 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114978 + }
114979 + else
114980 +#endif
114981 + {
114982 + if (get_user(param, (ioc_fm_exceptions*)arg))
114983 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114984 + }
114985 +
114986 + err = FM_ForceIntr(p_LnxWrpFmDev->h_Dev, (e_FmExceptions)param);
114987 + break;
114988 + }
114989 +
114990 + case FM_IOC_GET_API_VERSION:
114991 + {
114992 + ioc_fm_api_version_t version;
114993 +
114994 + FM_Get_Api_Version(&version);
114995 +
114996 +#if defined(CONFIG_COMPAT)
114997 + if (compat)
114998 + {
114999 + if (copy_to_user(
115000 + (ioc_fm_api_version_t *)compat_ptr(arg),
115001 + &version, sizeof(version)))
115002 + err = E_READ_FAILED;
115003 + }
115004 + else
115005 +#endif
115006 + {
115007 + if (copy_to_user((ioc_fm_api_version_t *)arg,
115008 + &version, sizeof(version)))
115009 + err = E_READ_FAILED;
115010 + }
115011 + }
115012 + break;
115013 +
115014 + case FM_IOC_CTRL_MON_START:
115015 + {
115016 + FM_CtrlMonStart(p_LnxWrpFmDev->h_Dev);
115017 + }
115018 + break;
115019 +
115020 + case FM_IOC_CTRL_MON_STOP:
115021 + {
115022 + FM_CtrlMonStop(p_LnxWrpFmDev->h_Dev);
115023 + }
115024 + break;
115025 +
115026 +#if defined(CONFIG_COMPAT)
115027 + case FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT:
115028 +#endif
115029 + case FM_IOC_CTRL_MON_GET_COUNTERS:
115030 + {
115031 + ioc_fm_ctrl_mon_counters_params_t param;
115032 + t_FmCtrlMon mon;
115033 +
115034 +#if defined(CONFIG_COMPAT)
115035 + ioc_compat_fm_ctrl_mon_counters_params_t compat_param;
115036 +
115037 + if (compat)
115038 + {
115039 + if (copy_from_user(&compat_param, (void *)compat_ptr(arg),
115040 + sizeof(compat_param)))
115041 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115042 +
115043 + param.fm_ctrl_index = compat_param.fm_ctrl_index;
115044 + param.p_mon = (fm_ctrl_mon_t *)compat_ptr(compat_param.p_mon);
115045 + }
115046 + else
115047 +#endif
115048 + {
115049 + if (copy_from_user(&param, (void *)arg, sizeof(ioc_fm_ctrl_mon_counters_params_t)))
115050 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115051 + }
115052 +
115053 + if (FM_CtrlMonGetCounters(p_LnxWrpFmDev->h_Dev, param.fm_ctrl_index, &mon))
115054 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115055 +
115056 + if (copy_to_user(param.p_mon, &mon, sizeof(t_FmCtrlMon)))
115057 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115058 + }
115059 + break;
115060 +
115061 + default:
115062 + return LnxwrpFmPcdIOCTL(p_LnxWrpFmDev, cmd, arg, compat);
115063 + }
115064 +
115065 + if (err)
115066 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM"));
115067 +
115068 + return E_OK;
115069 +}
115070 +
115071 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat)
115072 +{
115073 + t_Error err = E_OK;
115074 +
115075 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
115076 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 70);
115077 +
115078 + switch (cmd)
115079 + {
115080 + case FM_PORT_IOC_DISABLE:
115081 + FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
115082 + /* deliberately ignoring error codes here */
115083 + return E_OK;
115084 +
115085 + case FM_PORT_IOC_ENABLE:
115086 + FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
115087 + /* deliberately ignoring error codes here */
115088 + return E_OK;
115089 +
115090 + case FM_PORT_IOC_SET_ERRORS_ROUTE:
115091 + {
115092 + ioc_fm_port_frame_err_select_t errs;
115093 +
115094 +#if defined(CONFIG_COMPAT)
115095 + if (compat)
115096 + {
115097 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)compat_ptr(arg)))
115098 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115099 + }
115100 + else
115101 +#endif
115102 + {
115103 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)arg))
115104 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115105 + }
115106 +
115107 + err = FM_PORT_SetErrorsRoute(p_LnxWrpFmPortDev->h_Dev, (fmPortFrameErrSelect_t)errs);
115108 + break;
115109 + }
115110 +
115111 + case FM_PORT_IOC_SET_RATE_LIMIT:
115112 + {
115113 + ioc_fm_port_rate_limit_t *param;
115114 +
115115 + param = (ioc_fm_port_rate_limit_t *) XX_Malloc(sizeof(ioc_fm_port_rate_limit_t));
115116 + if (!param)
115117 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115118 +
115119 + memset(param, 0, sizeof(ioc_fm_port_rate_limit_t));
115120 +
115121 +#if defined(CONFIG_COMPAT)
115122 + if (compat)
115123 + {
115124 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)compat_ptr(arg), sizeof(ioc_fm_port_rate_limit_t)))
115125 + {
115126 + XX_Free(param);
115127 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115128 + }
115129 + }
115130 + else
115131 +#endif
115132 + {
115133 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)arg, sizeof(ioc_fm_port_rate_limit_t)))
115134 + {
115135 + XX_Free(param);
115136 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115137 + }
115138 + }
115139 +
115140 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, (t_FmPortRateLimit *)param);
115141 +
115142 + XX_Free(param);
115143 + break;
115144 + }
115145 +
115146 + case FM_PORT_IOC_REMOVE_RATE_LIMIT:
115147 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
115148 + /* deliberately ignoring error codes here */
115149 + return E_OK;
115150 +
115151 + case FM_PORT_IOC_ALLOC_PCD_FQIDS:
115152 + {
115153 + ioc_fm_port_pcd_fqids_params_t *param;
115154 +
115155 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cba)
115156 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
115157 +
115158 + param = (ioc_fm_port_pcd_fqids_params_t *) XX_Malloc(sizeof(ioc_fm_port_pcd_fqids_params_t));
115159 + if (!param)
115160 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115161 +
115162 + memset(param, 0, sizeof(ioc_fm_port_pcd_fqids_params_t));
115163 +
115164 +#if defined(CONFIG_COMPAT)
115165 + if (compat)
115166 + {
115167 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115168 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115169 + {
115170 + XX_Free(param);
115171 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115172 + }
115173 + }
115174 + else
115175 +#endif
115176 + {
115177 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)arg,
115178 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115179 + {
115180 + XX_Free(param);
115181 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115182 + }
115183 + }
115184 +
115185 + if (p_LnxWrpFmPortDev->pcd_owner_params.cba(p_LnxWrpFmPortDev->pcd_owner_params.dev,
115186 + param->num_fqids,
115187 + param->alignment,
115188 + &param->base_fqid))
115189 + {
115190 + XX_Free(param);
115191 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("can't allocate fqids for PCD!!!"));
115192 + }
115193 +
115194 +#if defined(CONFIG_COMPAT)
115195 + if (compat)
115196 + {
115197 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115198 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115199 + err = E_READ_FAILED;
115200 + }
115201 + else
115202 +#endif
115203 + {
115204 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)arg,
115205 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115206 + err = E_READ_FAILED;
115207 + }
115208 +
115209 + XX_Free(param);
115210 + break;
115211 + }
115212 +
115213 + case FM_PORT_IOC_FREE_PCD_FQIDS:
115214 + {
115215 + uint32_t base_fqid;
115216 +
115217 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cbf)
115218 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
115219 +
115220 +#if defined(CONFIG_COMPAT)
115221 + if (compat)
115222 + {
115223 + if (get_user(base_fqid, (uint32_t*) compat_ptr(arg)))
115224 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115225 + }
115226 + else
115227 +#endif
115228 + {
115229 + if (get_user(base_fqid, (uint32_t*)arg))
115230 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115231 + }
115232 +
115233 + if (p_LnxWrpFmPortDev->pcd_owner_params.cbf(p_LnxWrpFmPortDev->pcd_owner_params.dev, base_fqid))
115234 + err = E_WRITE_FAILED;
115235 +
115236 + break;
115237 + }
115238 +
115239 +#if defined(CONFIG_COMPAT)
115240 + case FM_PORT_IOC_SET_PCD_COMPAT:
115241 +#endif
115242 + case FM_PORT_IOC_SET_PCD:
115243 + {
115244 + ioc_fm_port_pcd_params_t *port_pcd_params;
115245 + ioc_fm_port_pcd_prs_params_t *port_pcd_prs_params;
115246 + ioc_fm_port_pcd_cc_params_t *port_pcd_cc_params;
115247 + ioc_fm_port_pcd_kg_params_t *port_pcd_kg_params;
115248 + ioc_fm_port_pcd_plcr_params_t *port_pcd_plcr_params;
115249 +
115250 + port_pcd_params = (ioc_fm_port_pcd_params_t *) XX_Malloc(
115251 + sizeof(ioc_fm_port_pcd_params_t) +
115252 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115253 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115254 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115255 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115256 + if (!port_pcd_params)
115257 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115258 +
115259 + memset(port_pcd_params, 0,
115260 + sizeof(ioc_fm_port_pcd_params_t) +
115261 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115262 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115263 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115264 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115265 +
115266 + port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (port_pcd_params + 1);
115267 + port_pcd_cc_params = (ioc_fm_port_pcd_cc_params_t *) (port_pcd_prs_params + 1);
115268 + port_pcd_kg_params = (ioc_fm_port_pcd_kg_params_t *) (port_pcd_cc_params + 1);
115269 + port_pcd_plcr_params = (ioc_fm_port_pcd_plcr_params_t *) (port_pcd_kg_params + 1);
115270 +
115271 +#if defined(CONFIG_COMPAT)
115272 + if (compat)
115273 + {
115274 + ioc_compat_fm_port_pcd_params_t *compat_port_pcd_params;
115275 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
115276 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
115277 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
115278 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
115279 +
115280 + compat_port_pcd_params = (ioc_compat_fm_port_pcd_params_t *) XX_Malloc(
115281 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115282 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115283 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115284 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115285 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115286 + if (!compat_port_pcd_params)
115287 + {
115288 + XX_Free(port_pcd_params);
115289 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115290 + }
115291 +
115292 + memset(compat_port_pcd_params, 0,
115293 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115294 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115295 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115296 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115297 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115298 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_port_pcd_params + 1);
115299 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
115300 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
115301 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
115302 +
115303 + if (copy_from_user(compat_port_pcd_params,
115304 + (ioc_compat_fm_port_pcd_params_t*) compat_ptr(arg),
115305 + sizeof(ioc_compat_fm_port_pcd_params_t)))
115306 + err = E_WRITE_FAILED;
115307 +
115308 + while (!err) /* pseudo-while */
115309 + {
115310 + /* set pointers from where to copy from: */
115311 + port_pcd_params->p_prs_params = compat_ptr(compat_port_pcd_params->p_prs_params); /* same structure */
115312 + port_pcd_params->p_cc_params = compat_ptr(compat_port_pcd_params->p_cc_params);
115313 + port_pcd_params->p_kg_params = compat_ptr(compat_port_pcd_params->p_kg_params);
115314 + port_pcd_params->p_plcr_params = compat_ptr(compat_port_pcd_params->p_plcr_params);
115315 + port_pcd_params->p_ip_reassembly_manip = compat_ptr(compat_port_pcd_params->p_ip_reassembly_manip);
115316 +#if (DPAA_VERSION >= 11)
115317 + port_pcd_params->p_capwap_reassembly_manip = compat_ptr(compat_port_pcd_params->p_capwap_reassembly_manip);
115318 +#endif
115319 + /* the prs member is the same, no compat structure...memcpy only */
115320 + if (port_pcd_params->p_prs_params)
115321 + {
115322 + if (copy_from_user(same_port_pcd_prs_params,
115323 + port_pcd_params->p_prs_params,
115324 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115325 + {
115326 + err = E_WRITE_FAILED;
115327 + break; /* from pseudo-while */
115328 + }
115329 +
115330 + memcpy(port_pcd_prs_params, same_port_pcd_prs_params, sizeof(ioc_fm_port_pcd_prs_params_t));
115331 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115332 + }
115333 +
115334 + if (port_pcd_params->p_cc_params)
115335 + {
115336 + if (copy_from_user(compat_port_pcd_cc_params,
115337 + port_pcd_params->p_cc_params,
115338 + sizeof(ioc_compat_fm_port_pcd_cc_params_t)))
115339 + {
115340 + err = E_WRITE_FAILED;
115341 + break; /* from pseudo-while */
115342 + }
115343 +
115344 + port_pcd_params->p_cc_params = port_pcd_cc_params;
115345 + }
115346 +
115347 + if (port_pcd_params->p_kg_params)
115348 + {
115349 + if (copy_from_user(compat_port_pcd_kg_params,
115350 + port_pcd_params->p_kg_params,
115351 + sizeof(ioc_compat_fm_port_pcd_kg_params_t)))
115352 + {
115353 + err = E_WRITE_FAILED;
115354 + break; /* from pseudo-while */
115355 + }
115356 +
115357 + port_pcd_params->p_kg_params = port_pcd_kg_params;
115358 + }
115359 +
115360 + if (port_pcd_params->p_plcr_params)
115361 + {
115362 + if (copy_from_user(compat_port_pcd_plcr_params,
115363 + port_pcd_params->p_plcr_params,
115364 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t)))
115365 + {
115366 + err = E_WRITE_FAILED;
115367 + break; /* from pseudo-while */
115368 + }
115369 +
115370 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
115371 + }
115372 +
115373 + break; /* pseudo-while: always run once! */
115374 + }
115375 +
115376 + if (!err)
115377 + compat_copy_fm_port_pcd(compat_port_pcd_params, port_pcd_params, COMPAT_US_TO_K);
115378 +
115379 + XX_Free(compat_port_pcd_params);
115380 + }
115381 + else
115382 +#endif
115383 + {
115384 + if (copy_from_user(port_pcd_params,
115385 + (ioc_fm_port_pcd_params_t*) arg,
115386 + sizeof(ioc_fm_port_pcd_params_t)))
115387 + err = E_WRITE_FAILED;
115388 +
115389 + while (!err) /* pseudo-while */
115390 + {
115391 + if (port_pcd_params->p_prs_params)
115392 + {
115393 + if (copy_from_user(port_pcd_prs_params,
115394 + port_pcd_params->p_prs_params,
115395 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115396 + {
115397 + err = E_WRITE_FAILED;
115398 + break; /* from pseudo-while */
115399 + }
115400 +
115401 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115402 + }
115403 +
115404 + if (port_pcd_params->p_cc_params)
115405 + {
115406 + if (copy_from_user(port_pcd_cc_params,
115407 + port_pcd_params->p_cc_params,
115408 + sizeof(ioc_fm_port_pcd_cc_params_t)))
115409 + {
115410 + err = E_WRITE_FAILED;
115411 + break; /* from pseudo-while */
115412 + }
115413 +
115414 + port_pcd_params->p_cc_params = port_pcd_cc_params;
115415 + }
115416 +
115417 + if (port_pcd_params->p_kg_params)
115418 + {
115419 + if (copy_from_user(port_pcd_kg_params,
115420 + port_pcd_params->p_kg_params,
115421 + sizeof(ioc_fm_port_pcd_kg_params_t)))
115422 + {
115423 + err = E_WRITE_FAILED;
115424 + break; /* from pseudo-while */
115425 + }
115426 +
115427 + port_pcd_params->p_kg_params = port_pcd_kg_params;
115428 + }
115429 +
115430 + if (port_pcd_params->p_plcr_params)
115431 + {
115432 + if (copy_from_user(port_pcd_plcr_params,
115433 + port_pcd_params->p_plcr_params,
115434 + sizeof(ioc_fm_port_pcd_plcr_params_t)))
115435 + {
115436 + err = E_WRITE_FAILED;
115437 + break; /* from pseudo-while */
115438 + }
115439 +
115440 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
115441 + }
115442 +
115443 + break; /* pseudo-while: always run once! */
115444 + }
115445 + }
115446 +
115447 + if (!err)
115448 + err = FM_PORT_SetPCD(p_LnxWrpFmPortDev->h_Dev, (t_FmPortPcdParams*) port_pcd_params);
115449 +
115450 + XX_Free(port_pcd_params);
115451 + break;
115452 + }
115453 +
115454 + case FM_PORT_IOC_DELETE_PCD:
115455 + err = FM_PORT_DeletePCD(p_LnxWrpFmPortDev->h_Dev);
115456 + break;
115457 +
115458 +#if defined(CONFIG_COMPAT)
115459 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT:
115460 +#endif
115461 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME:
115462 + {
115463 + ioc_fm_pcd_kg_scheme_select_t *param;
115464 +
115465 + param = (ioc_fm_pcd_kg_scheme_select_t *) XX_Malloc(
115466 + sizeof(ioc_fm_pcd_kg_scheme_select_t));
115467 + if (!param)
115468 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115469 +
115470 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_select_t));
115471 +
115472 +#if defined(CONFIG_COMPAT)
115473 + if (compat)
115474 + {
115475 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param;
115476 +
115477 + compat_param = (ioc_compat_fm_pcd_kg_scheme_select_t *) XX_Malloc(
115478 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
115479 + if (!compat_param)
115480 + {
115481 + XX_Free(param);
115482 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115483 + }
115484 +
115485 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
115486 + if (copy_from_user(compat_param,
115487 + (ioc_compat_fm_pcd_kg_scheme_select_t *) compat_ptr(arg),
115488 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t)))
115489 + {
115490 + XX_Free(compat_param);
115491 + XX_Free(param);
115492 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115493 + }
115494 +
115495 + compat_copy_fm_pcd_kg_scheme_select(compat_param, param, COMPAT_US_TO_K);
115496 +
115497 + XX_Free(compat_param);
115498 + }
115499 + else
115500 +#endif
115501 + {
115502 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_select_t *)arg,
115503 + sizeof(ioc_fm_pcd_kg_scheme_select_t)))
115504 + {
115505 + XX_Free(param);
115506 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115507 + }
115508 + }
115509 +
115510 + err = FM_PORT_PcdKgModifyInitialScheme(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdKgSchemeSelect *)param);
115511 +
115512 + XX_Free(param);
115513 + break;
115514 + }
115515 +
115516 +#if defined(CONFIG_COMPAT)
115517 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT:
115518 +#endif
115519 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE:
115520 + {
115521 + ioc_fm_obj_t id;
115522 +
115523 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
115524 +
115525 +#if defined(CONFIG_COMPAT)
115526 + if (compat)
115527 + {
115528 + ioc_compat_fm_obj_t compat_id;
115529 +
115530 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115531 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115532 +
115533 + id.obj = compat_ptr(compat_id.obj);
115534 + }
115535 + else
115536 +#endif
115537 + {
115538 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115539 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115540 + }
115541 +
115542 + err = FM_PORT_PcdPlcrModifyInitialProfile(p_LnxWrpFmPortDev->h_Dev, id.obj);
115543 + break;
115544 + }
115545 +
115546 +#if defined(CONFIG_COMPAT)
115547 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT:
115548 +#endif
115549 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES:
115550 + {
115551 + ioc_fm_pcd_port_schemes_params_t *param;
115552 +
115553 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
115554 + sizeof(ioc_fm_pcd_port_schemes_params_t));
115555 + if (!param)
115556 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115557 +
115558 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
115559 +
115560 +#if defined(CONFIG_COMPAT)
115561 + if (compat)
115562 + {
115563 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
115564 +
115565 + if (copy_from_user(&compat_param,
115566 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
115567 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
115568 + {
115569 + XX_Free(param);
115570 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115571 + }
115572 +
115573 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
115574 + }
115575 + else
115576 +#endif
115577 + {
115578 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
115579 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
115580 + {
115581 + XX_Free(param);
115582 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115583 + }
115584 + }
115585 +
115586 + err = FM_PORT_PcdKgBindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
115587 +
115588 + XX_Free(param);
115589 + break;
115590 + }
115591 +
115592 +#if defined(CONFIG_COMPAT)
115593 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT:
115594 +#endif
115595 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES:
115596 + {
115597 + ioc_fm_pcd_port_schemes_params_t *param;
115598 +
115599 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
115600 + sizeof(ioc_fm_pcd_port_schemes_params_t));
115601 + if (!param)
115602 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115603 +
115604 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
115605 +
115606 +#if defined(CONFIG_COMPAT)
115607 + if (compat)
115608 + {
115609 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
115610 +
115611 + if (copy_from_user(&compat_param,
115612 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
115613 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
115614 + {
115615 + XX_Free(param);
115616 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115617 + }
115618 +
115619 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
115620 + }
115621 + else
115622 +#endif
115623 + {
115624 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
115625 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
115626 + {
115627 + XX_Free(param);
115628 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115629 + }
115630 + }
115631 +
115632 + err = FM_PORT_PcdKgUnbindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
115633 +
115634 + XX_Free(param);
115635 + break;
115636 + }
115637 +
115638 + case FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES:
115639 + {
115640 + uint16_t num;
115641 + if (get_user(num, (uint16_t*) arg))
115642 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115643 +
115644 + err = FM_PORT_PcdPlcrAllocProfiles(p_LnxWrpFmPortDev->h_Dev, num);
115645 + break;
115646 + }
115647 +
115648 + case FM_PORT_IOC_PCD_PLCR_FREE_PROFILES:
115649 + err = FM_PORT_PcdPlcrFreeProfiles(p_LnxWrpFmPortDev->h_Dev);
115650 + break;
115651 +
115652 + case FM_PORT_IOC_DETACH_PCD:
115653 + err = FM_PORT_DetachPCD(p_LnxWrpFmPortDev->h_Dev);
115654 + break;
115655 +
115656 + case FM_PORT_IOC_ATTACH_PCD:
115657 + err = FM_PORT_AttachPCD(p_LnxWrpFmPortDev->h_Dev);
115658 + break;
115659 +
115660 +#if defined(CONFIG_COMPAT)
115661 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT:
115662 +#endif
115663 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE:
115664 + {
115665 + ioc_fm_obj_t id;
115666 +
115667 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
115668 +
115669 +#if defined(CONFIG_COMPAT)
115670 + if (compat)
115671 + {
115672 + ioc_compat_fm_obj_t compat_id;
115673 +
115674 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115675 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115676 +
115677 + compat_copy_fm_port_pcd_modify_tree(&compat_id, &id, COMPAT_US_TO_K);
115678 + }
115679 + else
115680 +#endif
115681 + {
115682 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115683 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115684 + }
115685 +
115686 + err = FM_PORT_PcdCcModifyTree(p_LnxWrpFmPortDev->h_Dev, id.obj);
115687 + break;
115688 + }
115689 +
115690 + case FM_PORT_IOC_ADD_CONGESTION_GRPS:
115691 + case FM_PORT_IOC_REMOVE_CONGESTION_GRPS:
115692 + {
115693 + ioc_fm_port_congestion_groups_t *param;
115694 +
115695 + param = (ioc_fm_port_congestion_groups_t*) XX_Malloc(sizeof(ioc_fm_port_congestion_groups_t));
115696 + if (!param)
115697 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115698 +
115699 + memset(param, 0, sizeof(ioc_fm_port_congestion_groups_t));
115700 +
115701 +#if defined(CONFIG_COMPAT)
115702 + if (compat)
115703 + {
115704 + if (copy_from_user(param, (t_FmPortCongestionGrps*) compat_ptr(arg),
115705 + sizeof(t_FmPortCongestionGrps)))
115706 + {
115707 + XX_Free(param);
115708 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115709 + }
115710 + }
115711 + else
115712 +#endif /* CONFIG_COMPAT */
115713 + {
115714 + if (copy_from_user(param, (t_FmPortCongestionGrps*) arg,
115715 + sizeof(t_FmPortCongestionGrps)))
115716 + {
115717 + XX_Free(param);
115718 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115719 + }
115720 + }
115721 +
115722 + err = (cmd == FM_PORT_IOC_ADD_CONGESTION_GRPS)
115723 + ? FM_PORT_AddCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
115724 + : FM_PORT_RemoveCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
115725 + ;
115726 +
115727 + XX_Free(param);
115728 + break;
115729 + }
115730 +
115731 + case FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR:
115732 + case FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR:
115733 + {
115734 + ioc_fm_port_mac_addr_params_t *param;
115735 +
115736 + param = (ioc_fm_port_mac_addr_params_t*) XX_Malloc(
115737 + sizeof(ioc_fm_port_mac_addr_params_t));
115738 + if (!param)
115739 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115740 +
115741 + memset(param, 0, sizeof(ioc_fm_port_mac_addr_params_t));
115742 +
115743 +#if defined(CONFIG_COMPAT)
115744 + if (compat)
115745 + {
115746 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) compat_ptr(arg),
115747 + sizeof(ioc_fm_port_mac_addr_params_t)))
115748 + {
115749 + XX_Free(param);
115750 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115751 + }
115752 + }
115753 + else
115754 +#endif /* CONFIG_COMPAT */
115755 + {
115756 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) arg,
115757 + sizeof(ioc_fm_port_mac_addr_params_t)))
115758 + {
115759 + XX_Free(param);
115760 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115761 + }
115762 + }
115763 +
115764 + if (p_LnxWrpFmPortDev->pcd_owner_params.dev)
115765 + {
115766 + int id = -1;
115767 +
115768 + switch(p_LnxWrpFmPortDev->settings.param.portType)
115769 + {
115770 + case e_FM_PORT_TYPE_RX:
115771 + case e_FM_PORT_TYPE_TX:
115772 + id = p_LnxWrpFmPortDev->id;
115773 + break;
115774 + case e_FM_PORT_TYPE_RX_10G:
115775 + case e_FM_PORT_TYPE_TX_10G:
115776 + id = p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_MACS;
115777 + break;
115778 + default:
115779 + err = E_NOT_AVAILABLE;
115780 + REPORT_ERROR(MINOR, err, ("Attempt to add/remove hash MAC addr. to/from MAC-less port!"));
115781 + }
115782 + if (id >= 0)
115783 + {
115784 + t_LnxWrpFmDev *fm = (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115785 + t_Handle mac_handle = fm->macs[id].h_Dev;
115786 +
115787 + err = (cmd == FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR)
115788 + ? FM_MAC_AddHashMacAddr(mac_handle, (t_EnetAddr*) param)
115789 + : FM_MAC_RemoveHashMacAddr(mac_handle, (t_EnetAddr*) param);
115790 + }
115791 + }
115792 + else
115793 + {
115794 + err = E_NOT_AVAILABLE;
115795 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!?!?"));
115796 + }
115797 +
115798 + XX_Free(param);
115799 + break;
115800 + }
115801 +
115802 + case FM_PORT_IOC_SET_TX_PAUSE_FRAMES:
115803 + {
115804 + t_LnxWrpFmDev *p_LnxWrpFmDev =
115805 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115806 + ioc_fm_port_tx_pause_frames_params_t param;
115807 + int mac_id = p_LnxWrpFmPortDev->id;
115808 +
115809 + if(&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev)
115810 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
115811 +
115812 + if (copy_from_user(&param, (ioc_fm_port_tx_pause_frames_params_t *)arg,
115813 + sizeof(ioc_fm_port_tx_pause_frames_params_t)))
115814 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115815 +
115816 + if (p_LnxWrpFmDev && p_LnxWrpFmDev->macs[mac_id].h_Dev)
115817 + {
115818 + FM_MAC_SetTxPauseFrames(p_LnxWrpFmDev->macs[mac_id].h_Dev,
115819 + param.priority,
115820 + param.pause_time,
115821 + param.thresh_time);
115822 + }
115823 + else
115824 + {
115825 + err = E_NOT_AVAILABLE;
115826 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!"));
115827 + }
115828 +
115829 + break;
115830 + }
115831 +
115832 + case FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT:
115833 + {
115834 + ioc_fm_buffer_prefix_content_t *param;
115835 +
115836 + param = (ioc_fm_buffer_prefix_content_t*) XX_Malloc(sizeof(ioc_fm_buffer_prefix_content_t));
115837 + if (!param)
115838 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115839 +
115840 + memset(param, 0, sizeof(ioc_fm_buffer_prefix_content_t));
115841 +
115842 + if (copy_from_user(param, (ioc_fm_buffer_prefix_content_t*) arg,
115843 + sizeof(ioc_fm_buffer_prefix_content_t)))
115844 + {
115845 + XX_Free(param);
115846 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115847 + }
115848 +
115849 + if (FM_PORT_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_Dev,
115850 + (t_FmBufferPrefixContent *)param))
115851 + {
115852 + XX_Free(param);
115853 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115854 + }
115855 +
115856 + XX_Free(param);
115857 + break;
115858 + }
115859 +
115860 +#if (DPAA_VERSION >= 11)
115861 +#if defined(CONFIG_COMPAT)
115862 + case FM_PORT_IOC_VSP_ALLOC_COMPAT:
115863 +#endif
115864 + case FM_PORT_IOC_VSP_ALLOC:
115865 + {
115866 + ioc_fm_port_vsp_alloc_params_t *param;
115867 + t_LnxWrpFmDev *p_LnxWrpFmDev;
115868 + t_LnxWrpFmPortDev *p_LnxWrpFmTxPortDev;
115869 +
115870 + param = (ioc_fm_port_vsp_alloc_params_t *) XX_Malloc(
115871 + sizeof(ioc_fm_port_vsp_alloc_params_t));
115872 + if (!param)
115873 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115874 +
115875 + memset(param, 0, sizeof(ioc_fm_port_vsp_alloc_params_t));
115876 +
115877 +#if defined(CONFIG_COMPAT)
115878 + if (compat)
115879 + {
115880 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param;
115881 +
115882 + compat_param = (ioc_compat_fm_port_vsp_alloc_params_t *) XX_Malloc(
115883 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
115884 + if (!compat_param)
115885 + {
115886 + XX_Free(param);
115887 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115888 + }
115889 +
115890 + memset(compat_param, 0, sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
115891 + if (copy_from_user(compat_param,
115892 + (ioc_compat_fm_port_vsp_alloc_params_t *) compat_ptr(arg),
115893 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t)))
115894 + {
115895 + XX_Free(compat_param);
115896 + XX_Free(param);
115897 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115898 + }
115899 +
115900 + compat_copy_fm_port_vsp_alloc_params(compat_param, param, COMPAT_US_TO_K);
115901 +
115902 + XX_Free(compat_param);
115903 + }
115904 + else
115905 +#endif
115906 + {
115907 + if (copy_from_user(param, (ioc_fm_port_vsp_alloc_params_t *)arg,
115908 + sizeof(ioc_fm_port_vsp_alloc_params_t)))
115909 + {
115910 + XX_Free(param);
115911 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115912 + }
115913 + }
115914 +
115915 + /* Userspace may not have the Tx port t_handle when issuing the IOCTL */
115916 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
115917 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G)
115918 + {
115919 + /* Determine the Tx port t_Handle from the Rx port id */
115920 + p_LnxWrpFmDev = p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115921 + p_LnxWrpFmTxPortDev = &p_LnxWrpFmDev->txPorts[p_LnxWrpFmPortDev->id];
115922 + param->p_fm_tx_port = p_LnxWrpFmTxPortDev->h_Dev;
115923 + }
115924 +
115925 + if (FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev, (t_FmPortVSPAllocParams *)param))
115926 + {
115927 + XX_Free(param);
115928 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115929 + }
115930 +
115931 + XX_Free(param);
115932 + break;
115933 + }
115934 +#endif /* (DPAA_VERSION >= 11) */
115935 +
115936 + case FM_PORT_IOC_GET_MAC_STATISTICS:
115937 + {
115938 + t_LnxWrpFmDev *p_LnxWrpFmDev =
115939 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115940 + ioc_fm_port_mac_statistics_t param;
115941 + int mac_id = p_LnxWrpFmPortDev->id;
115942 +
115943 + if (!p_LnxWrpFmDev)
115944 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
115945 +
115946 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
115947 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
115948 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
115949 +
115950 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
115951 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
115952 +
115953 + if (FM_MAC_GetStatistics(p_LnxWrpFmDev->macs[mac_id].h_Dev,
115954 + (t_FmMacStatistics *)&param))
115955 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115956 +
115957 + if (copy_to_user((ioc_fm_port_mac_statistics_t *)arg, &param,
115958 + sizeof(ioc_fm_port_mac_statistics_t)))
115959 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115960 +
115961 + break;
115962 + }
115963 +
115964 + case FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS:
115965 + {
115966 + t_LnxWrpFmDev *p_LnxWrpFmDev =
115967 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115968 + ioc_fm_port_mac_frame_size_counters_t param;
115969 + t_FmMacFrameSizeCounters frameSizeCounters;
115970 + int mac_id = p_LnxWrpFmPortDev->id;
115971 +
115972 + if (!p_LnxWrpFmDev)
115973 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
115974 +
115975 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
115976 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
115977 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
115978 +
115979 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
115980 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
115981 +
115982 + if (copy_from_user(&param, (ioc_fm_port_mac_frame_size_counters_t *)arg,
115983 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
115984 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115985 +
115986 + if (FM_MAC_GetFrameSizeCounters(p_LnxWrpFmDev->macs[mac_id].h_Dev,
115987 + &frameSizeCounters, param.type))
115988 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115989 +
115990 + param.count_pkts_64 = frameSizeCounters.count_pkts_64;
115991 + param.count_pkts_65_to_127 = frameSizeCounters.count_pkts_65_to_127;
115992 + param.count_pkts_128_to_255 = frameSizeCounters.count_pkts_128_to_255;
115993 + param.count_pkts_256_to_511 = frameSizeCounters.count_pkts_256_to_511;
115994 + param.count_pkts_512_to_1023 = frameSizeCounters.count_pkts_512_to_1023;
115995 + param.count_pkts_1024_to_1518 = frameSizeCounters.count_pkts_1024_to_1518;
115996 + param.count_pkts_1519_to_1522 = frameSizeCounters.count_pkts_1519_to_1522;
115997 +
115998 + if (copy_to_user((ioc_fm_port_mac_frame_size_counters_t *)arg, &param,
115999 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
116000 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116001 +
116002 + break;
116003 + }
116004 +
116005 + case FM_PORT_IOC_GET_BMI_COUNTERS:
116006 + {
116007 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116008 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116009 + ioc_fm_port_bmi_stats_t param;
116010 +
116011 + if (!p_LnxWrpFmDev)
116012 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116013 +
116014 + if (FM_PORT_GetBmiCounters(p_LnxWrpFmPortDev->h_Dev,
116015 + (t_FmPortBmiStats *)&param))
116016 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116017 +
116018 + if (copy_to_user((ioc_fm_port_bmi_stats_t *)arg, &param,
116019 + sizeof(ioc_fm_port_bmi_stats_t)))
116020 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116021 +
116022 + break;
116023 + }
116024 +
116025 + default:
116026 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
116027 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
116028 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
116029 + }
116030 +
116031 + if (err)
116032 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM PORT"));
116033 +
116034 + return E_OK;
116035 +}
116036 +
116037 +/*****************************************************************************/
116038 +/* API routines for the FM Linux Device */
116039 +/*****************************************************************************/
116040 +
116041 +static int fm_open(struct inode *inode, struct file *file)
116042 +{
116043 + t_LnxWrpFmDev *p_LnxWrpFmDev = NULL;
116044 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
116045 + unsigned int major = imajor(inode);
116046 + unsigned int minor = iminor(inode);
116047 + struct device_node *fm_node;
116048 + static struct of_device_id fm_node_of_match[] = {
116049 + { .compatible = "fsl,fman", },
116050 + { /* end of list */ },
116051 + };
116052 +
116053 + DBG(TRACE, ("Opening minor - %d - ", minor));
116054 +
116055 + if (file->private_data != NULL)
116056 + return 0;
116057 +
116058 + /* Get all the FM nodes */
116059 + for_each_matching_node(fm_node, fm_node_of_match) {
116060 + struct platform_device *of_dev;
116061 +
116062 + of_dev = of_find_device_by_node(fm_node);
116063 + if (unlikely(of_dev == NULL)) {
116064 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
116065 + return -ENXIO;
116066 + }
116067 +
116068 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)fm_bind(&of_dev->dev);
116069 + if (p_LnxWrpFmDev->major == major)
116070 + break;
116071 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116072 + p_LnxWrpFmDev = NULL;
116073 + }
116074 +
116075 + if (!p_LnxWrpFmDev)
116076 + return -ENODEV;
116077 +
116078 + if (minor == DEV_FM_MINOR_BASE)
116079 + file->private_data = p_LnxWrpFmDev;
116080 + else if (minor == DEV_FM_PCD_MINOR_BASE)
116081 + file->private_data = p_LnxWrpFmDev;
116082 + else {
116083 + if (minor == DEV_FM_OH_PORTS_MINOR_BASE)
116084 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
116085 + else if ((minor > DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE))
116086 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->opPorts[minor-DEV_FM_OH_PORTS_MINOR_BASE-1];
116087 + else if ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE))
116088 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[minor-DEV_FM_RX_PORTS_MINOR_BASE];
116089 + else if ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS))
116090 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[minor-DEV_FM_TX_PORTS_MINOR_BASE];
116091 + else
116092 + return -EINVAL;
116093 +
116094 + /* if trying to open port, check if it initialized */
116095 + if (!p_LnxWrpFmPortDev->h_Dev)
116096 + return -ENODEV;
116097 +
116098 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)fm_port_bind(p_LnxWrpFmPortDev->dev);
116099 + file->private_data = p_LnxWrpFmPortDev;
116100 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116101 + }
116102 +
116103 + if (file->private_data == NULL)
116104 + return -ENXIO;
116105 +
116106 + return 0;
116107 +}
116108 +
116109 +static int fm_close(struct inode *inode, struct file *file)
116110 +{
116111 + t_LnxWrpFmDev *p_LnxWrpFmDev;
116112 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
116113 + unsigned int minor = iminor(inode);
116114 + int err = 0;
116115 +
116116 + DBG(TRACE, ("Closing minor - %d - ", minor));
116117 +
116118 + if ((minor == DEV_FM_MINOR_BASE) ||
116119 + (minor == DEV_FM_PCD_MINOR_BASE))
116120 + {
116121 + p_LnxWrpFmDev = (t_LnxWrpFmDev*)file->private_data;
116122 + if (!p_LnxWrpFmDev)
116123 + return -ENODEV;
116124 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116125 + }
116126 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
116127 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
116128 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
116129 + {
116130 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)file->private_data;
116131 + if (!p_LnxWrpFmPortDev)
116132 + return -ENODEV;
116133 + fm_port_unbind((struct fm_port *)p_LnxWrpFmPortDev);
116134 + }
116135 +
116136 + return err;
116137 +}
116138 +
116139 +static int fm_ioctls(unsigned int minor, struct file *file, unsigned int cmd, unsigned long arg, bool compat)
116140 +{
116141 + DBG(TRACE, ("IOCTL minor - %u, cmd - 0x%08x, arg - 0x%08lx \n", minor, cmd, arg));
116142 +
116143 + if ((minor == DEV_FM_MINOR_BASE) ||
116144 + (minor == DEV_FM_PCD_MINOR_BASE))
116145 + {
116146 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_LnxWrpFmDev*)file->private_data);
116147 + if (!p_LnxWrpFmDev)
116148 + return -ENODEV;
116149 + if (LnxwrpFmIOCTL(p_LnxWrpFmDev, cmd, arg, compat))
116150 + return -EFAULT;
116151 + }
116152 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
116153 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
116154 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
116155 + {
116156 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = ((t_LnxWrpFmPortDev*)file->private_data);
116157 + if (!p_LnxWrpFmPortDev)
116158 + return -ENODEV;
116159 + if (LnxwrpFmPortIOCTL(p_LnxWrpFmPortDev, cmd, arg, compat))
116160 + return -EFAULT;
116161 + }
116162 + else
116163 + {
116164 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("minor"));
116165 + return -ENODEV;
116166 + }
116167 +
116168 + return 0;
116169 +}
116170 +
116171 +#ifdef CONFIG_COMPAT
116172 +static long fm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
116173 +{
116174 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
116175 + long res;
116176 +
116177 + fm_mutex_lock();
116178 + res = fm_ioctls(minor, file, cmd, arg, true);
116179 + fm_mutex_unlock();
116180 +
116181 + return res;
116182 +}
116183 +#endif
116184 +
116185 +static long fm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
116186 +{
116187 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
116188 + long res;
116189 +
116190 + fm_mutex_lock();
116191 + res = fm_ioctls(minor, file, cmd, arg, false);
116192 + fm_mutex_unlock();
116193 +
116194 + return res;
116195 +}
116196 +
116197 +/* Globals for FM character device */
116198 +struct file_operations fm_fops =
116199 +{
116200 + .owner = THIS_MODULE,
116201 + .unlocked_ioctl = fm_ioctl,
116202 +#ifdef CONFIG_COMPAT
116203 + .compat_ioctl = fm_compat_ioctl,
116204 +#endif
116205 + .open = fm_open,
116206 + .release = fm_close,
116207 +};
116208 --- /dev/null
116209 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
116210 @@ -0,0 +1,1297 @@
116211 +/*
116212 + * Copyright 2008-2012 Freescale Semiconductor Inc.
116213 + *
116214 + * Redistribution and use in source and binary forms, with or without
116215 + * modification, are permitted provided that the following conditions are met:
116216 + * * Redistributions of source code must retain the above copyright
116217 + * notice, this list of conditions and the following disclaimer.
116218 + * * Redistributions in binary form must reproduce the above copyright
116219 + * notice, this list of conditions and the following disclaimer in the
116220 + * documentation and/or other materials provided with the distribution.
116221 + * * Neither the name of Freescale Semiconductor nor the
116222 + * names of its contributors may be used to endorse or promote products
116223 + * derived from this software without specific prior written permission.
116224 + *
116225 + *
116226 + * ALTERNATIVELY, this software may be distributed under the terms of the
116227 + * GNU General Public License ("GPL") as published by the Free Software
116228 + * Foundation, either version 2 of that License or (at your option) any
116229 + * later version.
116230 + *
116231 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
116232 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
116233 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
116234 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
116235 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
116236 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
116237 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
116238 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
116239 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
116240 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
116241 + */
116242 +
116243 +/*
116244 + @File lnxwrp_fm_compat_ioctls.c
116245 +
116246 + @Description FM PCD compat functions
116247 +
116248 +*/
116249 +
116250 +#if !defined(CONFIG_COMPAT)
116251 +#error "missing COMPAT layer..."
116252 +#endif
116253 +
116254 +
116255 +#include <linux/kernel.h>
116256 +#include <linux/module.h>
116257 +#include <linux/fs.h>
116258 +#include <linux/cdev.h>
116259 +#include <linux/device.h>
116260 +#include <linux/irq.h>
116261 +#include <linux/interrupt.h>
116262 +#include <linux/io.h>
116263 +#include <linux/ioport.h>
116264 +#include <asm/uaccess.h>
116265 +#include <asm/errno.h>
116266 +#ifndef CONFIG_FMAN_ARM
116267 +#include <sysdev/fsl_soc.h>
116268 +#endif
116269 +
116270 +#include "part_ext.h"
116271 +#include "fm_ioctls.h"
116272 +#include "fm_pcd_ioctls.h"
116273 +#include "fm_port_ioctls.h"
116274 +#include "lnxwrp_ioctls_fm_compat.h"
116275 +
116276 +#if defined(FM_COMPAT_DBG)
116277 +static void hex_dump(void * p_addr, unsigned int size)
116278 +{
116279 + int i;
116280 +
116281 + for(i=0; i<size; i+=16)
116282 + {
116283 + printk("%p: 0x%08x 0x%08x 0x%08x 0x%08x\n", p_addr + i,
116284 + *(unsigned int *)(p_addr + i),
116285 + *(unsigned int *)(p_addr + i + 4),
116286 + *(unsigned int *)(p_addr + i + 8),
116287 + *(unsigned int *)(p_addr + i +12)
116288 + );
116289 + }
116290 +}
116291 +#endif
116292 +
116293 +/* maping kernel pointers w/ UserSpace id's { */
116294 +struct map_node {
116295 + void *ptr;
116296 + u8 node_type;
116297 +};
116298 +
116299 +static struct map_node compat_ptr2id_array[COMPAT_PTR2ID_ARRAY_MAX] = {{NULL},{FM_MAP_TYPE_UNSPEC}};
116300 +
116301 +void compat_del_ptr2id(void *p, enum fm_map_node_type node_type)
116302 +{
116303 + compat_uptr_t k;
116304 +
116305 + _fm_cpt_dbg(COMPAT_GENERIC, "delete (%p)\n", p);
116306 +
116307 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116308 + if(compat_ptr2id_array[k].ptr == p){
116309 + compat_ptr2id_array[k].ptr = NULL;
116310 + compat_ptr2id_array[k].node_type = FM_MAP_TYPE_UNSPEC;
116311 + }
116312 +}
116313 +EXPORT_SYMBOL(compat_del_ptr2id);
116314 +
116315 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type node_type)
116316 +{
116317 + compat_uptr_t k;
116318 +
116319 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) do ->\n", p);
116320 +
116321 + if(!p)
116322 + return 0;
116323 +
116324 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116325 + if(compat_ptr2id_array[k].ptr == NULL)
116326 + {
116327 + compat_ptr2id_array[k].ptr = p;
116328 + compat_ptr2id_array[k].node_type = node_type;
116329 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x \n", k | COMPAT_PTR2ID_WATERMARK);
116330 + return k | COMPAT_PTR2ID_WATERMARK;
116331 + }
116332 +
116333 + printk(KERN_WARNING "FMan map list full! No more PCD space on kernel!\n");
116334 + return 0;
116335 +}
116336 +EXPORT_SYMBOL(compat_add_ptr2id);
116337 +
116338 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type node_type)
116339 +{
116340 + compat_uptr_t k;
116341 +
116342 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) get -> \n", p);
116343 +
116344 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116345 + if(compat_ptr2id_array[k].ptr == p &&
116346 + compat_ptr2id_array[k].node_type == node_type) {
116347 +
116348 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x\n", k | COMPAT_PTR2ID_WATERMARK);
116349 + return k | COMPAT_PTR2ID_WATERMARK;
116350 + }
116351 +
116352 + return 0;
116353 +}
116354 +EXPORT_SYMBOL(compat_get_ptr2id);
116355 +
116356 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type node_type)
116357 +{
116358 +
116359 + _fm_cpt_dbg(COMPAT_GENERIC, " (0x%08x) get -> \n", comp);
116360 +
116361 + if((COMPAT_PTR2ID_WM_MASK & comp) != COMPAT_PTR2ID_WATERMARK) {
116362 + _fm_cpt_dbg(COMPAT_GENERIC, "Error, invalid watermark (0x%08x)!\n\n", comp);
116363 + dump_stack();
116364 + return compat_ptr(comp);
116365 + }
116366 +
116367 + comp &= ~COMPAT_PTR2ID_WM_MASK;
116368 +
116369 + if(((0 < comp) && (comp < COMPAT_PTR2ID_ARRAY_MAX) && (compat_ptr2id_array[comp].ptr != NULL)
116370 + && compat_ptr2id_array[comp].node_type == node_type)) {
116371 + _fm_cpt_dbg(COMPAT_GENERIC, "%p\n", compat_ptr2id_array[comp].ptr);
116372 + return compat_ptr2id_array[comp].ptr;
116373 + }
116374 + return NULL;
116375 +}
116376 +EXPORT_SYMBOL(compat_get_id2ptr);
116377 +/* } maping kernel pointers w/ UserSpace id's */
116378 +
116379 +void compat_obj_delete(
116380 + ioc_compat_fm_obj_t *compat_id,
116381 + ioc_fm_obj_t *id)
116382 +{
116383 + id->obj = compat_pcd_id2ptr(compat_id->obj);
116384 + compat_del_ptr2id(id->obj, FM_MAP_TYPE_PCD_NODE);
116385 +}
116386 +
116387 +static inline void compat_copy_fm_pcd_plcr_next_engine(
116388 + ioc_compat_fm_pcd_plcr_next_engine_params_u *compat_param,
116389 + ioc_fm_pcd_plcr_next_engine_params_u *param,
116390 + ioc_fm_pcd_engine next_engine,
116391 + uint8_t compat)
116392 +{
116393 + _fm_cpt_dbg (compat, " {->...\n");
116394 +
116395 + switch (next_engine)
116396 + {
116397 + case e_IOC_FM_PCD_PLCR:
116398 + if (compat == COMPAT_US_TO_K)
116399 + param->p_profile = compat_pcd_id2ptr(compat_param->p_profile);
116400 + else
116401 + compat_param->p_profile = compat_pcd_ptr2id(param->p_profile);
116402 + break;
116403 + case e_IOC_FM_PCD_KG:
116404 + if (compat == COMPAT_US_TO_K)
116405 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
116406 + else
116407 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
116408 + break;
116409 + default:
116410 + if (compat == COMPAT_US_TO_K)
116411 + param->action = compat_param->action;
116412 + else
116413 + compat_param->action = param->action;
116414 + break;
116415 + }
116416 +
116417 + _fm_cpt_dbg (compat, " ...->}\n");
116418 +}
116419 +
116420 +void compat_copy_fm_pcd_plcr_profile(
116421 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
116422 + ioc_fm_pcd_plcr_profile_params_t *param,
116423 + uint8_t compat)
116424 +{
116425 + _fm_cpt_dbg (compat, " {->...\n");
116426 +
116427 + if (compat == COMPAT_US_TO_K)
116428 + {
116429 + param->modify = compat_param->modify;
116430 +
116431 + /* profile_select */
116432 + if (!compat_param->modify)
116433 + {
116434 + param->profile_select.new_params.profile_type =
116435 + compat_param->profile_select.new_params.profile_type;
116436 + param->profile_select.new_params.p_fm_port =
116437 + compat_ptr(compat_param->profile_select.new_params.p_fm_port);
116438 + param->profile_select.new_params.relative_profile_id =
116439 + compat_param->profile_select.new_params.relative_profile_id;
116440 + }
116441 + else
116442 + param->profile_select.p_profile =
116443 + compat_pcd_id2ptr(compat_param->profile_select.p_profile);
116444 +
116445 + param->alg_selection = compat_param->alg_selection;
116446 + param->color_mode = compat_param->color_mode;
116447 +
116448 + /* both parameters in the union has the same size, so memcpy works */
116449 + memcpy(&param->color, &compat_param->color, sizeof(param->color));
116450 +
116451 + memcpy(&param->non_passthrough_alg_param,
116452 + &compat_param->non_passthrough_alg_param,
116453 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
116454 +
116455 + param->next_engine_on_green = compat_param->next_engine_on_green;
116456 + param->next_engine_on_yellow = compat_param->next_engine_on_yellow;
116457 + param->next_engine_on_red = compat_param->next_engine_on_red;
116458 +
116459 + param->trap_profile_on_flow_A = compat_param->trap_profile_on_flow_A;
116460 + param->trap_profile_on_flow_B = compat_param->trap_profile_on_flow_B;
116461 + param->trap_profile_on_flow_C = compat_param->trap_profile_on_flow_C;
116462 + }
116463 + else
116464 + {
116465 + compat_param->modify = param->modify;
116466 +
116467 + /* profile_select */
116468 + if (!param->modify)
116469 + {
116470 + compat_param->profile_select.new_params.profile_type =
116471 + param->profile_select.new_params.profile_type;
116472 + compat_param->profile_select.new_params.p_fm_port =
116473 + ptr_to_compat(param->profile_select.new_params.p_fm_port);
116474 + compat_param->profile_select.new_params.relative_profile_id =
116475 + param->profile_select.new_params.relative_profile_id;
116476 + }
116477 + else
116478 + compat_param->profile_select.p_profile =
116479 + compat_pcd_ptr2id(param->profile_select.p_profile);
116480 +
116481 + compat_param->alg_selection = param->alg_selection;
116482 + compat_param->color_mode = param->color_mode;
116483 +
116484 + /* both parameters in the union has the same size, so memcpy works */
116485 + memcpy(&compat_param->color, &param->color, sizeof(compat_param->color));
116486 +
116487 + memcpy(&compat_param->non_passthrough_alg_param,
116488 + &param->non_passthrough_alg_param,
116489 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
116490 +
116491 + compat_param->next_engine_on_green = param->next_engine_on_green;
116492 + compat_param->next_engine_on_yellow = param->next_engine_on_yellow;
116493 + compat_param->next_engine_on_red = param->next_engine_on_red;
116494 +
116495 + compat_param->trap_profile_on_flow_A = param->trap_profile_on_flow_A;
116496 + compat_param->trap_profile_on_flow_B = param->trap_profile_on_flow_B;
116497 + compat_param->trap_profile_on_flow_C = param->trap_profile_on_flow_C;
116498 +
116499 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116500 + }
116501 +
116502 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_green,
116503 + &param->params_on_green, param->next_engine_on_green, compat);
116504 +
116505 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_yellow,
116506 + &param->params_on_yellow, param->next_engine_on_yellow, compat);
116507 +
116508 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_red,
116509 + &param->params_on_red, param->next_engine_on_red, compat);
116510 +
116511 + _fm_cpt_dbg (compat, " ...->}\n");
116512 +}
116513 +
116514 +static inline void compat_copy_fm_pcd_cc_next_kg(
116515 + ioc_compat_fm_pcd_cc_next_kg_params_t *compat_param,
116516 + ioc_fm_pcd_cc_next_kg_params_t *param,
116517 + uint8_t compat)
116518 +{
116519 + _fm_cpt_dbg (compat, " {->...\n");
116520 +
116521 + if (compat == COMPAT_US_TO_K)
116522 + {
116523 + param->new_fqid = compat_param->new_fqid;
116524 + param->override_fqid = compat_param->override_fqid;
116525 +#if DPAA_VERSION >= 11
116526 + param->new_relative_storage_profile_id = compat_param->new_relative_storage_profile_id;
116527 +#endif
116528 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
116529 + }
116530 + else
116531 + {
116532 + compat_param->new_fqid = param->new_fqid;
116533 + compat_param->override_fqid = param->override_fqid;
116534 +#if DPAA_VERSION >= 11
116535 + compat_param->new_relative_storage_profile_id = param->new_relative_storage_profile_id;
116536 +#endif
116537 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
116538 + }
116539 +
116540 + _fm_cpt_dbg (compat, " ...->}\n");
116541 +}
116542 +
116543 +static inline void compat_copy_fm_pcd_cc_next_cc(
116544 + ioc_compat_fm_pcd_cc_next_cc_params_t *compat_param,
116545 + ioc_fm_pcd_cc_next_cc_params_t *param,
116546 + uint8_t compat)
116547 +{
116548 + _fm_cpt_dbg (compat, " {->...\n");
116549 +
116550 + if (compat == COMPAT_US_TO_K)
116551 + param->cc_node_id = compat_pcd_id2ptr(compat_param->cc_node_id);
116552 + else
116553 + compat_param->cc_node_id = compat_pcd_ptr2id(param->cc_node_id);
116554 +
116555 + _fm_cpt_dbg (compat, " ...->}\n");
116556 +}
116557 +
116558 +static inline void compat_copy_fm_pcd_cc_next_engine(
116559 + ioc_compat_fm_pcd_cc_next_engine_params_t *compat_param,
116560 + ioc_fm_pcd_cc_next_engine_params_t *param,
116561 + uint8_t compat)
116562 +{
116563 + _fm_cpt_dbg (compat, " {->...\n");
116564 +
116565 + if (compat == COMPAT_US_TO_K)
116566 + {
116567 + param->next_engine = compat_param->next_engine;
116568 + if (param->next_engine != e_IOC_FM_PCD_INVALID )
116569 + _fm_cpt_dbg(compat, " param->next_engine = %i \n", param->next_engine);
116570 +
116571 + switch (param->next_engine)
116572 + {
116573 +#if DPAA_VERSION >= 11
116574 + case e_IOC_FM_PCD_FR:
116575 + param->params.fr_params.frm_replic_id = compat_pcd_id2ptr(compat_param->params.fr_params.frm_replic_id);
116576 + break;
116577 +#endif /* DPAA_VERSION >= 11 */
116578 + case e_IOC_FM_PCD_CC:
116579 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116580 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
116581 + break;
116582 + case e_IOC_FM_PCD_KG:
116583 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116584 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
116585 + break;
116586 + case e_IOC_FM_PCD_DONE:
116587 + case e_IOC_FM_PCD_PLCR:
116588 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116589 + default:
116590 + memcpy(&param->params, &compat_param->params, sizeof(param->params));
116591 + }
116592 + param->statistics_en = compat_param->statistics_en;
116593 + }
116594 + else
116595 + {
116596 + compat_param->next_engine = param->next_engine;
116597 +
116598 + switch (compat_param->next_engine)
116599 + {
116600 +#if DPAA_VERSION >= 11
116601 + case e_IOC_FM_PCD_FR:
116602 + compat_param->params.fr_params.frm_replic_id = compat_pcd_ptr2id(param->params.fr_params.frm_replic_id);
116603 + break;
116604 +#endif /* DPAA_VERSION >= 11 */
116605 + case e_IOC_FM_PCD_CC:
116606 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116607 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
116608 + break;
116609 + case e_IOC_FM_PCD_KG:
116610 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116611 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
116612 + break;
116613 + case e_IOC_FM_PCD_DONE:
116614 + case e_IOC_FM_PCD_PLCR:
116615 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116616 + default:
116617 + memcpy(&compat_param->params, &param->params, sizeof(compat_param->params));
116618 + }
116619 + compat_param->statistics_en = param->statistics_en;
116620 + }
116621 +
116622 + _fm_cpt_dbg (compat, " ...->}\n");
116623 +}
116624 +
116625 +void compat_copy_fm_pcd_cc_key(
116626 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
116627 + ioc_fm_pcd_cc_key_params_t *param,
116628 + uint8_t compat)
116629 +{
116630 + if (compat == COMPAT_US_TO_K)
116631 + {
116632 + param->p_key = compat_ptr(compat_param->p_key);
116633 + param->p_mask = compat_ptr(compat_param->p_mask);
116634 + }
116635 + else
116636 + {
116637 + compat_param->p_key = ptr_to_compat(param->p_key);
116638 + compat_param->p_mask = ptr_to_compat(param->p_mask);
116639 + }
116640 +
116641 + compat_copy_fm_pcd_cc_next_engine(
116642 + &compat_param->cc_next_engine_params,
116643 + &param->cc_next_engine_params,
116644 + compat);
116645 +}
116646 +
116647 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
116648 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
116649 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
116650 + uint8_t compat)
116651 +{
116652 + if (compat == COMPAT_US_TO_K)
116653 + {
116654 + param->id = compat_pcd_id2ptr(compat_param->id);
116655 + param->key_indx = compat_param->key_indx;
116656 + param->key_size = compat_param->key_size;
116657 + compat_copy_fm_pcd_cc_key(
116658 + &compat_param->key_params,
116659 + &param->key_params,
116660 + compat);
116661 + }
116662 + else
116663 + {
116664 + compat_param->id = compat_pcd_ptr2id(param->id);
116665 + compat_param->key_indx = param->key_indx;
116666 + compat_param->key_size = param->key_size;
116667 + compat_copy_fm_pcd_cc_key(
116668 + &compat_param->key_params,
116669 + &param->key_params,
116670 + compat);
116671 + }
116672 +}
116673 +
116674 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
116675 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
116676 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
116677 + uint8_t compat)
116678 +{
116679 + if (compat == COMPAT_US_TO_K)
116680 + {
116681 + param->id = compat_pcd_id2ptr(compat_param->id);
116682 + param->key_indx = compat_param->key_indx;
116683 + param->key_size = compat_param->key_size;
116684 + }
116685 + else
116686 + {
116687 + compat_param->id = compat_pcd_ptr2id(param->id);
116688 + compat_param->key_indx = param->key_indx;
116689 + compat_param->key_size = param->key_size;
116690 + }
116691 +
116692 + compat_copy_fm_pcd_cc_next_engine(
116693 + &compat_param->cc_next_engine_params,
116694 + &param->cc_next_engine_params,
116695 + compat);
116696 +}
116697 +
116698 +void compat_fm_pcd_cc_tree_modify_next_engine(
116699 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
116700 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
116701 + uint8_t compat)
116702 +{
116703 + if (compat == COMPAT_US_TO_K)
116704 + {
116705 + param->id = compat_pcd_id2ptr(compat_param->id);
116706 + param->grp_indx = compat_param->grp_indx;
116707 + param->indx = compat_param->indx;
116708 + }
116709 + else
116710 + {
116711 + compat_param->id = compat_pcd_ptr2id(param->id);
116712 + compat_param->grp_indx = param->grp_indx;
116713 + compat_param->indx = param->indx;
116714 + }
116715 +
116716 + compat_copy_fm_pcd_cc_next_engine(
116717 + &compat_param->cc_next_engine_params,
116718 + &param->cc_next_engine_params,
116719 + compat);
116720 +}
116721 +
116722 +void compat_copy_fm_pcd_hash_table(
116723 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
116724 + ioc_fm_pcd_hash_table_params_t *param,
116725 + uint8_t compat)
116726 +{
116727 + if (compat == COMPAT_US_TO_K)
116728 + {
116729 + param->max_num_of_keys = compat_param->max_num_of_keys;
116730 + param->statistics_mode = compat_param->statistics_mode;
116731 + param->kg_hash_shift = compat_param->kg_hash_shift;
116732 + param->hash_res_mask = compat_param->hash_res_mask;
116733 + param->hash_shift = compat_param->hash_shift;
116734 + param->match_key_size = compat_param->match_key_size;
116735 + param->id = compat_pcd_id2ptr(compat_param->id);
116736 + }
116737 + else
116738 + {
116739 + compat_param->max_num_of_keys = param->max_num_of_keys;
116740 + compat_param->statistics_mode = param->statistics_mode;
116741 + compat_param->kg_hash_shift = param->kg_hash_shift;
116742 + compat_param->hash_res_mask = param->hash_res_mask;
116743 + compat_param->hash_shift = param->hash_shift;
116744 + compat_param->match_key_size = param->match_key_size;
116745 +
116746 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116747 + }
116748 +
116749 + compat_copy_fm_pcd_cc_next_engine(
116750 + &compat_param->cc_next_engine_params_for_miss,
116751 + &param->cc_next_engine_params_for_miss,
116752 + compat);
116753 +}
116754 +
116755 +void compat_copy_fm_pcd_cc_grp(
116756 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
116757 + ioc_fm_pcd_cc_grp_params_t *param,
116758 + uint8_t compat)
116759 +{
116760 + int k;
116761 +
116762 + _fm_cpt_dbg (compat, " {->...\n");
116763 +
116764 + if (compat == COMPAT_US_TO_K)
116765 + {
116766 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
116767 + memcpy(param->unit_ids, compat_param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
116768 + }
116769 + else
116770 + {
116771 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
116772 + memcpy(compat_param->unit_ids, param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
116773 + }
116774 +
116775 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP; k++)
116776 + compat_copy_fm_pcd_cc_next_engine(
116777 + &compat_param->next_engine_per_entries_in_grp[k],
116778 + &param->next_engine_per_entries_in_grp[k],
116779 + compat);
116780 +
116781 + _fm_cpt_dbg (compat, " ...->}\n");
116782 +}
116783 +
116784 +void compat_copy_fm_pcd_cc_tree(
116785 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
116786 + ioc_fm_pcd_cc_tree_params_t *param,
116787 + uint8_t compat)
116788 +{
116789 + int k;
116790 + _fm_cpt_dbg (compat, " {->...\n");
116791 +
116792 + if (compat == COMPAT_US_TO_K)
116793 + {
116794 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
116795 + param->num_of_groups = compat_param->num_of_groups;
116796 + }
116797 + else
116798 + {
116799 + compat_param->net_env_id = compat_pcd_ptr2id(param->net_env_id);
116800 + compat_param->num_of_groups = param->num_of_groups;
116801 +
116802 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116803 + }
116804 +
116805 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS; k++)
116806 + compat_copy_fm_pcd_cc_grp(
116807 + &compat_param->fm_pcd_cc_group_params[k],
116808 + &param->fm_pcd_cc_group_params[k],
116809 + compat);
116810 +
116811 + _fm_cpt_dbg (compat, " ...->}\n");
116812 +}
116813 +
116814 +void compat_fm_pcd_prs_sw(
116815 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
116816 + ioc_fm_pcd_prs_sw_params_t *param,
116817 + uint8_t compat)
116818 +{
116819 + if (compat == COMPAT_US_TO_K)
116820 + {
116821 + param->override = compat_param->override;
116822 + param->size = compat_param->size;
116823 + param->base = compat_param->base;
116824 + param->p_code = compat_ptr(compat_param->p_code);
116825 + memcpy(param->sw_prs_data_params,compat_param->sw_prs_data_params,IOC_FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t));
116826 + param->num_of_labels = compat_param->num_of_labels;
116827 + memcpy(param->labels_table,compat_param->labels_table,IOC_FM_PCD_PRS_NUM_OF_LABELS*sizeof(ioc_fm_pcd_prs_label_params_t));
116828 + }
116829 +}
116830 +
116831 +void compat_copy_fm_pcd_kg_scheme(
116832 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
116833 + ioc_fm_pcd_kg_scheme_params_t *param,
116834 + uint8_t compat)
116835 +{
116836 + _fm_cpt_dbg(compat," {->...\n");
116837 +
116838 + if (compat == COMPAT_US_TO_K)
116839 + {
116840 + param->modify = compat_param->modify;
116841 +
116842 + /* scm_id */
116843 + if (compat_param->modify)
116844 + {
116845 + param->scm_id.scheme_id = compat_pcd_id2ptr(compat_param->scm_id.scheme_id);
116846 + _fm_cpt_dbg(compat," param->scm_id.scheme_id = %p \n", param->scm_id.scheme_id);
116847 + }
116848 + else
116849 + param->scm_id.relative_scheme_id = compat_param->scm_id.relative_scheme_id;
116850 +
116851 + param->always_direct = compat_param->always_direct;
116852 + /* net_env_params */
116853 + param->net_env_params.net_env_id = compat_pcd_id2ptr(compat_param->net_env_params.net_env_id);
116854 + param->net_env_params.num_of_distinction_units = compat_param->net_env_params.num_of_distinction_units;
116855 + memcpy(param->net_env_params.unit_ids,
116856 + compat_param->net_env_params.unit_ids,
116857 + IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
116858 +
116859 + param->use_hash = compat_param->use_hash;
116860 + memcpy(&param->key_extract_and_hash_params,
116861 + &compat_param->key_extract_and_hash_params,
116862 + sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t));
116863 + param->bypass_fqid_generation = compat_param->bypass_fqid_generation;
116864 + param->base_fqid = compat_param->base_fqid;
116865 +#if DPAA_VERSION >= 11
116866 + param->override_storage_profile =
116867 + compat_param->override_storage_profile;
116868 + param->storage_profile = compat_param->storage_profile;
116869 +#endif
116870 + param->num_of_used_extracted_ors = compat_param->num_of_used_extracted_ors;
116871 + memcpy(param->extracted_ors,
116872 + compat_param->extracted_ors,
116873 + IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t));
116874 + param->next_engine = compat_param->next_engine;
116875 +
116876 + /* kg_next_engine_params */
116877 + if (param->next_engine == e_IOC_FM_PCD_CC)
116878 + {
116879 + param->kg_next_engine_params.cc.tree_id = compat_pcd_id2ptr(compat_param->kg_next_engine_params.cc.tree_id);
116880 + param->kg_next_engine_params.cc.grp_id = compat_param->kg_next_engine_params.cc.grp_id;
116881 + param->kg_next_engine_params.cc.plcr_next = compat_param->kg_next_engine_params.cc.plcr_next;
116882 + param->kg_next_engine_params.cc.bypass_plcr_profile_generation
116883 + = compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
116884 + memcpy(&param->kg_next_engine_params.cc.plcr_profile,
116885 + &compat_param->kg_next_engine_params.cc.plcr_profile,
116886 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
116887 + }
116888 + else
116889 + memcpy(&param->kg_next_engine_params,
116890 + &compat_param->kg_next_engine_params,
116891 + sizeof(param->kg_next_engine_params));
116892 +
116893 + memcpy(&param->scheme_counter,
116894 + &compat_param->scheme_counter,
116895 + sizeof(ioc_fm_pcd_kg_scheme_counter_t));
116896 + }
116897 + else
116898 + {
116899 + compat_param->modify = param->modify;
116900 +
116901 + /* scm_id */
116902 + if (param->modify)
116903 + compat_param->scm_id.scheme_id = compat_pcd_ptr2id(param->scm_id.scheme_id);
116904 + else
116905 + compat_param->scm_id.relative_scheme_id = param->scm_id.relative_scheme_id;
116906 +
116907 + compat_param->always_direct = param->always_direct;
116908 +
116909 + /* net_env_params */
116910 + compat_param->net_env_params.net_env_id = compat_pcd_ptr2id(param->net_env_params.net_env_id);
116911 + compat_param->net_env_params.num_of_distinction_units = param->net_env_params.num_of_distinction_units;
116912 + memcpy(compat_param->net_env_params.unit_ids, param->net_env_params.unit_ids, IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
116913 +
116914 + compat_param->use_hash = param->use_hash;
116915 + 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));
116916 + compat_param->bypass_fqid_generation = param->bypass_fqid_generation;
116917 + compat_param->base_fqid = param->base_fqid;
116918 +#if DPAA_VERSION >= 11
116919 + compat_param->override_storage_profile =
116920 + param->override_storage_profile;
116921 + compat_param->storage_profile = param->storage_profile;
116922 +#endif
116923 + compat_param->num_of_used_extracted_ors = param->num_of_used_extracted_ors;
116924 + 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));
116925 + compat_param->next_engine = param->next_engine;
116926 +
116927 + /* kg_next_engine_params */
116928 + if (compat_param->next_engine == e_IOC_FM_PCD_CC)
116929 + {
116930 + compat_param->kg_next_engine_params.cc.tree_id = compat_pcd_ptr2id(param->kg_next_engine_params.cc.tree_id);
116931 + compat_param->kg_next_engine_params.cc.grp_id = param->kg_next_engine_params.cc.grp_id;
116932 + compat_param->kg_next_engine_params.cc.plcr_next = param->kg_next_engine_params.cc.plcr_next;
116933 + compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation
116934 + = param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
116935 + memcpy(&compat_param->kg_next_engine_params.cc.plcr_profile,
116936 + &param->kg_next_engine_params.cc.plcr_profile,
116937 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
116938 + }
116939 + else
116940 + memcpy(&param->kg_next_engine_params, &compat_param->kg_next_engine_params, sizeof(compat_param->kg_next_engine_params));
116941 +
116942 + memcpy(&compat_param->scheme_counter, &param->scheme_counter, sizeof(ioc_fm_pcd_kg_scheme_counter_t));
116943 +
116944 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116945 + }
116946 +
116947 + _fm_cpt_dbg(compat," ...->}\n");
116948 +}
116949 +
116950 +void compat_copy_fm_pcd_kg_scheme_spc(
116951 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
116952 + ioc_fm_pcd_kg_scheme_spc_t *param,
116953 + uint8_t compat)
116954 +{
116955 + if (compat == COMPAT_US_TO_K)
116956 + {
116957 + param->id = compat_pcd_id2ptr(compat_param->id);
116958 + param->val = compat_param->val;
116959 + } else {
116960 + compat_param->id = compat_pcd_ptr2id(param->id);
116961 + compat_param->val = param->val;
116962 + }
116963 +}
116964 +
116965 +
116966 +void compat_copy_fm_pcd_kg_scheme_select(
116967 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
116968 + ioc_fm_pcd_kg_scheme_select_t *param,
116969 + uint8_t compat)
116970 +{
116971 + if (compat == COMPAT_US_TO_K)
116972 + {
116973 + param->direct = compat_param->direct;
116974 + if (param->direct)
116975 + param->scheme_id = compat_pcd_id2ptr(compat_param->scheme_id);
116976 + }
116977 +}
116978 +
116979 +void compat_copy_fm_pcd_kg_schemes_params(
116980 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
116981 + ioc_fm_pcd_port_schemes_params_t *param,
116982 + uint8_t compat)
116983 +{
116984 + int k;
116985 +
116986 + if (compat == COMPAT_US_TO_K) {
116987 + param->num_of_schemes = compat_param->num_of_schemes;
116988 + for(k=0; k < compat_param->num_of_schemes; k++)
116989 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
116990 + }
116991 +}
116992 +
116993 +void compat_copy_fm_port_pcd_cc(
116994 + ioc_compat_fm_port_pcd_cc_params_t *compat_cc_params ,
116995 + ioc_fm_port_pcd_cc_params_t *p_cc_params,
116996 + uint8_t compat)
116997 +{
116998 + if (compat == COMPAT_US_TO_K){
116999 + p_cc_params->cc_tree_id = compat_pcd_id2ptr(compat_cc_params->cc_tree_id);
117000 + }
117001 +}
117002 +
117003 +void compat_copy_fm_port_pcd_kg(
117004 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
117005 + ioc_fm_port_pcd_kg_params_t *param,
117006 + uint8_t compat)
117007 +{
117008 + if (compat == COMPAT_US_TO_K){
117009 + uint8_t k;
117010 +
117011 + param->num_of_schemes = compat_param->num_of_schemes;
117012 + for(k=0; k<compat_param->num_of_schemes; k++)
117013 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
117014 +
117015 + param->direct_scheme = compat_param->direct_scheme;
117016 + if (param->direct_scheme)
117017 + param->direct_scheme_id = compat_pcd_id2ptr(compat_param->direct_scheme_id);
117018 + }
117019 +}
117020 +
117021 +void compat_copy_fm_port_pcd(
117022 + ioc_compat_fm_port_pcd_params_t *compat_param,
117023 + ioc_fm_port_pcd_params_t *param,
117024 + uint8_t compat)
117025 +{
117026 + if (compat == COMPAT_US_TO_K)
117027 + {
117028 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
117029 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
117030 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
117031 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
117032 +
117033 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_param + 1);
117034 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
117035 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
117036 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
117037 +
117038 + _fm_cpt_dbg(compat,"\n param->p_prs_params=%p \n", param->p_prs_params);
117039 + _fm_cpt_dbg(compat," param->p_cc_params=%p \n", param->p_cc_params);
117040 + _fm_cpt_dbg(compat," param->p_kg_params=%p \n", param->p_kg_params);
117041 + _fm_cpt_dbg(compat," param->p_plcr_params=%p \n", param->p_plcr_params);
117042 + _fm_cpt_dbg(compat," param->p_ip_reassembly_manip=%p \n", param->p_ip_reassembly_manip);
117043 +#if (DPAA_VERSION >= 11)
117044 + _fm_cpt_dbg(compat," param->p_capwap_reassembly_manip=%p \n", param->p_capwap_reassembly_manip);
117045 +#endif
117046 + param->pcd_support = compat_param->pcd_support;
117047 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
117048 +
117049 + if (param->p_cc_params)
117050 + compat_copy_fm_port_pcd_cc(compat_port_pcd_cc_params, param->p_cc_params, COMPAT_US_TO_K);
117051 + if (param->p_kg_params)
117052 + compat_copy_fm_port_pcd_kg(compat_port_pcd_kg_params, param->p_kg_params, COMPAT_US_TO_K);
117053 + if (param->p_plcr_params)
117054 + param->p_plcr_params->plcr_profile_id = compat_pcd_id2ptr(compat_port_pcd_plcr_params->plcr_profile_id);
117055 + param->p_ip_reassembly_manip = compat_pcd_id2ptr(compat_param->p_ip_reassembly_manip);
117056 +#if (DPAA_VERSION >= 11)
117057 + param->p_capwap_reassembly_manip = compat_pcd_id2ptr(compat_param->p_capwap_reassembly_manip);
117058 +#endif
117059 + }
117060 +}
117061 +
117062 +void compat_copy_fm_port_pcd_modify_tree(
117063 + ioc_compat_fm_obj_t *compat_id,
117064 + ioc_fm_obj_t *id,
117065 + uint8_t compat)
117066 +{
117067 + if (compat == COMPAT_US_TO_K)
117068 + id->obj = compat_pcd_id2ptr(compat_id->obj);
117069 +}
117070 +
117071 +#if (DPAA_VERSION >= 11)
117072 +void compat_copy_fm_port_vsp_alloc_params(
117073 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
117074 + ioc_fm_port_vsp_alloc_params_t *param,
117075 + uint8_t compat)
117076 +{
117077 + if (compat == COMPAT_US_TO_K)
117078 + {
117079 + _fm_cpt_dbg(compat," param->p_fm_tx_port=%p \n", param->p_fm_tx_port);
117080 +
117081 + param->dflt_relative_id = compat_param->dflt_relative_id;
117082 + param->num_of_profiles = compat_param->num_of_profiles;
117083 + param->p_fm_tx_port = compat_pcd_id2ptr(compat_param->p_fm_tx_port);
117084 + }
117085 +}
117086 +#endif /* (DPAA_VERSION >= 11) */
117087 +
117088 +void compat_copy_fm_pcd_cc_tbl_get_stats(
117089 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
117090 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
117091 + uint8_t compat)
117092 +{
117093 + if (compat == COMPAT_US_TO_K)
117094 + {
117095 + param->id = compat_pcd_id2ptr(compat_param->id);
117096 + param->key_index = compat_param->key_index;
117097 + memcpy(&param->statistics, &compat_param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
117098 + } else {
117099 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117100 + compat_param->key_index = param->key_index;
117101 + memcpy(&compat_param->statistics, &param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
117102 + }
117103 +}
117104 +
117105 +
117106 +void compat_copy_fm_pcd_net_env(
117107 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
117108 + ioc_fm_pcd_net_env_params_t *param,
117109 + uint8_t compat)
117110 +{
117111 + if (compat == COMPAT_US_TO_K)
117112 + {
117113 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
117114 + memcpy(param->units, compat_param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117115 + param->id = NULL; /* to avoid passing garbage to the kernel */
117116 + }
117117 + else
117118 + {
117119 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
117120 + memcpy(compat_param->units, param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117121 +
117122 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117123 + }
117124 +}
117125 +
117126 +void compat_copy_fm_pcd_cc_node_modify_key(
117127 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
117128 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
117129 + uint8_t compat)
117130 +{
117131 + if (compat == COMPAT_US_TO_K)
117132 + {
117133 + param->key_indx = compat_param->key_indx;
117134 + param->key_size = compat_param->key_size;
117135 + param->p_key = (uint8_t *)compat_ptr(compat_param->p_key);
117136 + _fm_cpt_dbg(compat," param->p_key = %p \n", param->p_key);
117137 + param->p_mask = (uint8_t *)compat_ptr(compat_param->p_mask);
117138 + _fm_cpt_dbg(compat," param->p_mask = %p\n", param->p_mask);
117139 + param->id = compat_pcd_id2ptr(compat_param->id);
117140 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
117141 + }
117142 + else
117143 + {
117144 + compat_param->key_indx = param->key_indx;
117145 + compat_param->key_size = param->key_size;
117146 + compat_param->p_key = ptr_to_compat((void *)param->p_key);
117147 + compat_param->p_mask = ptr_to_compat((void *)param->p_mask);
117148 +
117149 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117150 + }
117151 +}
117152 +
117153 +void compat_copy_keys(
117154 + ioc_compat_keys_params_t *compat_param,
117155 + ioc_keys_params_t *param,
117156 + uint8_t compat)
117157 +{
117158 + int k = 0;
117159 +
117160 + _fm_cpt_dbg(compat," {->...\n");
117161 +
117162 + if (compat == COMPAT_US_TO_K) {
117163 + param->max_num_of_keys = compat_param->max_num_of_keys;
117164 + param->mask_support = compat_param->mask_support;
117165 + param->statistics_mode = compat_param->statistics_mode;
117166 + param->num_of_keys = compat_param->num_of_keys;
117167 + param->key_size = compat_param->key_size;
117168 +#if (DPAA_VERSION >= 11)
117169 + memcpy(&param->frame_length_ranges,
117170 + &compat_param->frame_length_ranges,
117171 + sizeof(param->frame_length_ranges[0]) *
117172 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
117173 +#endif /* (DPAA_VERSION >= 11) */
117174 + }
117175 + else {
117176 + compat_param->max_num_of_keys = param->max_num_of_keys;
117177 + compat_param->mask_support = param->mask_support;
117178 + compat_param->statistics_mode = param->statistics_mode;
117179 + compat_param->num_of_keys = param->num_of_keys;
117180 + compat_param->key_size = param->key_size;
117181 +#if (DPAA_VERSION >= 11)
117182 + memcpy(&compat_param->frame_length_ranges,
117183 + &param->frame_length_ranges,
117184 + sizeof(compat_param->frame_length_ranges[0]) *
117185 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
117186 +#endif /* (DPAA_VERSION >= 11) */
117187 + }
117188 +
117189 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_KEYS; k++)
117190 + compat_copy_fm_pcd_cc_key(
117191 + &compat_param->key_params[k],
117192 + &param->key_params[k],
117193 + compat);
117194 +
117195 + compat_copy_fm_pcd_cc_next_engine(
117196 + &compat_param->cc_next_engine_params_for_miss,
117197 + &param->cc_next_engine_params_for_miss,
117198 + compat);
117199 +
117200 + _fm_cpt_dbg(compat," ...->}\n");
117201 +}
117202 +
117203 +void compat_copy_fm_pcd_cc_node(
117204 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
117205 + ioc_fm_pcd_cc_node_params_t *param,
117206 + uint8_t compat)
117207 +{
117208 + _fm_cpt_dbg(compat," {->...\n");
117209 +
117210 + if (compat == COMPAT_US_TO_K)
117211 + memcpy(&param->extract_cc_params, &compat_param->extract_cc_params, sizeof(ioc_fm_pcd_extract_entry_t));
117212 +
117213 + else
117214 + {
117215 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117216 +
117217 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117218 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
117219 + }
117220 +
117221 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117222 +
117223 + _fm_cpt_dbg(compat," ...->}\n");
117224 +}
117225 +
117226 +void compat_fm_pcd_manip_set_node(
117227 + ioc_compat_fm_pcd_manip_params_t *compat_param,
117228 + ioc_fm_pcd_manip_params_t *param,
117229 + uint8_t compat)
117230 +{
117231 + if (compat == COMPAT_US_TO_K) {
117232 + param->type = compat_param->type;
117233 + switch (param->type) {
117234 + case e_IOC_FM_PCD_MANIP_HDR:
117235 + param->u.hdr.rmv = compat_param->u.hdr.rmv;
117236 + memcpy(&param->u.hdr.rmv_params,
117237 + &compat_param->u.hdr.rmv_params,
117238 + sizeof(param->u.hdr.rmv_params));
117239 +
117240 + param->u.hdr.insrt = compat_param->u.hdr.insrt;
117241 + param->u.hdr.insrt_params.type =
117242 + compat_param->u.hdr.insrt_params.type;
117243 + switch (compat_param->u.hdr.insrt_params.type)
117244 + {
117245 + case e_IOC_FM_PCD_MANIP_INSRT_GENERIC:
117246 + param->u.hdr.insrt_params.u.generic.offset =
117247 + compat_param->u.hdr.insrt_params.u.generic.offset;
117248 + param->u.hdr.insrt_params.u.generic.size =
117249 + compat_param->u.hdr.insrt_params.u.generic.size;
117250 + param->u.hdr.insrt_params.u.generic.replace =
117251 + compat_param->u.hdr.insrt_params.u.generic.replace;
117252 + param->u.hdr.insrt_params.u.generic.p_data =
117253 + compat_ptr(compat_param->u.hdr.insrt_params.u.generic.p_data);
117254 + break;
117255 + case e_IOC_FM_PCD_MANIP_INSRT_BY_HDR:
117256 + param->u.hdr.insrt_params.u.by_hdr.type =
117257 + compat_param->u.hdr.insrt_params.u.by_hdr.type;
117258 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2 =
117259 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2;
117260 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update =
117261 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update;
117262 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size =
117263 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size;
117264 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data =
117265 + compat_ptr(compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data);
117266 + break;
117267 + default:
117268 + _fm_cpt_err("Unsupported type: %d", compat_param->u.hdr.insrt_params.type);
117269 + }
117270 +
117271 + param->u.hdr.field_update = compat_param->u.hdr.field_update;
117272 + memcpy(&param->u.hdr.field_update_params,
117273 + &compat_param->u.hdr.field_update_params,
117274 + sizeof(param->u.hdr.field_update_params));
117275 +
117276 + param->u.hdr.custom = compat_param->u.hdr.custom;
117277 + memcpy(&param->u.hdr.custom_params,
117278 + &compat_param->u.hdr.custom_params,
117279 + sizeof(param->u.hdr.custom_params));
117280 +
117281 + param->u.hdr.dont_parse_after_manip =
117282 + compat_param->u.hdr.dont_parse_after_manip;
117283 + break;
117284 + case e_IOC_FM_PCD_MANIP_REASSEM:
117285 + memcpy(&param->u.reassem, &compat_param->u.reassem, sizeof(param->u.reassem));
117286 + break;
117287 + case e_IOC_FM_PCD_MANIP_FRAG:
117288 + memcpy(&param->u.frag, &compat_param->u.frag, sizeof(param->u.frag));
117289 + break;
117290 + case e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD:
117291 + memcpy(&param->u.special_offload,
117292 + &compat_param->u.special_offload,
117293 + sizeof(param->u.special_offload));
117294 + break;
117295 + }
117296 +
117297 + param->p_next_manip = compat_pcd_id2ptr(compat_param->p_next_manip);
117298 + param->id = compat_pcd_id2ptr(compat_param->id);
117299 + }
117300 + else {
117301 + compat_param->type = param->type;
117302 + memcpy(&compat_param->u, &param->u, sizeof(compat_param->u));
117303 +
117304 + if (param->type == e_IOC_FM_PCD_MANIP_HDR &&
117305 + param->u.hdr.insrt_params.type == e_IOC_FM_PCD_MANIP_INSRT_GENERIC)
117306 + compat_param->u.hdr.insrt_params.u.generic.p_data =
117307 + ptr_to_compat(param->u.hdr.insrt_params.u.generic.p_data);
117308 +
117309 + compat_param->p_next_manip = compat_pcd_ptr2id(param->id);
117310 + /* ... should be one that was added previously by the very call to
117311 + compat_add_ptr2id() below: */
117312 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117313 + }
117314 +}
117315 +
117316 +void compat_copy_fm_pcd_manip_get_stats(
117317 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
117318 + ioc_fm_pcd_manip_get_stats_t *param,
117319 + uint8_t compat)
117320 +{
117321 + _fm_cpt_dbg (compat, " {->...\n");
117322 +
117323 + if (compat == COMPAT_US_TO_K)
117324 + {
117325 + param->id = compat_pcd_id2ptr(compat_param->id);
117326 + memcpy(&param->stats, &compat_param->stats,
117327 + sizeof(ioc_fm_pcd_manip_stats_t));
117328 + }
117329 + else
117330 + {
117331 + compat_param->id = compat_add_ptr2id(param->id,
117332 + FM_MAP_TYPE_PCD_NODE);
117333 + memcpy(&compat_param->stats, &param->stats,
117334 + sizeof(ioc_fm_pcd_manip_stats_t));
117335 + }
117336 +
117337 + _fm_cpt_dbg (compat, " ...->}\n");
117338 +}
117339 +
117340 +#if (DPAA_VERSION >= 11)
117341 +void compat_copy_fm_pcd_frm_replic_group_params(
117342 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
117343 + ioc_fm_pcd_frm_replic_group_params_t *param,
117344 + uint8_t compat)
117345 +{
117346 + int k;
117347 +
117348 + _fm_cpt_dbg (compat, " {->...\n");
117349 +
117350 + if (compat == COMPAT_US_TO_K)
117351 + {
117352 + param->max_num_of_entries = compat_param->max_num_of_entries;
117353 + param->num_of_entries = compat_param->num_of_entries;
117354 + param->id = compat_pcd_id2ptr(compat_param->id);
117355 + }
117356 + else
117357 + {
117358 + compat_param->max_num_of_entries = param->max_num_of_entries;
117359 + compat_param->num_of_entries = param->num_of_entries;
117360 + compat_param->id = compat_add_ptr2id(param->id,
117361 + FM_MAP_TYPE_PCD_NODE);
117362 + }
117363 +
117364 + for (k=0; k < IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES; k++)
117365 + compat_copy_fm_pcd_cc_next_engine(
117366 + &compat_param->next_engine_params[k],
117367 + &param->next_engine_params[k],
117368 + compat);
117369 +
117370 + _fm_cpt_dbg (compat, " ...->}\n");
117371 +}
117372 +
117373 +void compat_copy_fm_pcd_frm_replic_member(
117374 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
117375 + ioc_fm_pcd_frm_replic_member_t *param,
117376 + uint8_t compat)
117377 +{
117378 + _fm_cpt_dbg (compat, " {->...\n");
117379 +
117380 + if (compat == COMPAT_US_TO_K)
117381 + {
117382 + param->h_replic_group = compat_pcd_id2ptr(compat_param->h_replic_group);
117383 + param->member_index = compat_param->member_index;
117384 + }
117385 +
117386 + _fm_cpt_dbg (compat, " ...->}\n");
117387 +}
117388 +
117389 +void compat_copy_fm_pcd_frm_replic_member_params(
117390 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
117391 + ioc_fm_pcd_frm_replic_member_params_t *param,
117392 + uint8_t compat)
117393 +{
117394 + _fm_cpt_dbg (compat, " {->...\n");
117395 +
117396 + compat_copy_fm_pcd_frm_replic_member(&compat_param->member,
117397 + &param->member, compat);
117398 +
117399 + compat_copy_fm_pcd_cc_next_engine(&compat_param->next_engine_params,
117400 + &param->next_engine_params, compat);
117401 +
117402 + _fm_cpt_dbg (compat, " ...->}\n");
117403 +}
117404 +
117405 +void compat_copy_fm_vsp_params(
117406 + ioc_compat_fm_vsp_params_t *compat_param,
117407 + ioc_fm_vsp_params_t *param,
117408 + uint8_t compat)
117409 +{
117410 + _fm_cpt_dbg (compat, " {->...\n");
117411 +
117412 + if (compat == COMPAT_US_TO_K)
117413 + {
117414 + memcpy(&param->ext_buf_pools, &compat_param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
117415 + param->liodn_offset = compat_param->liodn_offset;
117416 + param->port_params.port_id = compat_param->port_params.port_id;
117417 + param->port_params.port_type = compat_param->port_params.port_type;
117418 + param->relative_profile_id = compat_param->relative_profile_id;
117419 + }
117420 + else
117421 + {
117422 + memcpy(&compat_param->ext_buf_pools, &param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
117423 + compat_param->liodn_offset = param->liodn_offset;
117424 + compat_param->port_params.port_id = param->port_params.port_id;
117425 + compat_param->port_params.port_type = param->port_params.port_type;
117426 + compat_param->relative_profile_id = param->relative_profile_id;
117427 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117428 + }
117429 +
117430 + _fm_cpt_dbg (compat, " ...->}\n");
117431 +}
117432 +
117433 +void compat_copy_fm_buf_pool_depletion_params(
117434 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
117435 + ioc_fm_buf_pool_depletion_params_t *param,
117436 + uint8_t compat)
117437 +{
117438 + _fm_cpt_dbg (compat, " {->...\n");
117439 +
117440 + if (compat == COMPAT_US_TO_K)
117441 + {
117442 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117443 + memcpy(&param->fm_buf_pool_depletion,
117444 + &compat_param->fm_buf_pool_depletion,
117445 + sizeof(ioc_fm_buf_pool_depletion_t));
117446 + }
117447 +
117448 + _fm_cpt_dbg (compat, " ...->}\n");
117449 +}
117450 +
117451 +void compat_copy_fm_buffer_prefix_content_params(
117452 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
117453 + ioc_fm_buffer_prefix_content_params_t *param,
117454 + uint8_t compat)
117455 +{
117456 + _fm_cpt_dbg (compat, " {->...\n");
117457 +
117458 + if (compat == COMPAT_US_TO_K)
117459 + {
117460 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117461 + memcpy(&param->fm_buffer_prefix_content,
117462 + &compat_param->fm_buffer_prefix_content,
117463 + sizeof(ioc_fm_buffer_prefix_content_t));
117464 + }
117465 +
117466 + _fm_cpt_dbg (compat, " ...->}\n");
117467 +}
117468 +
117469 +void compat_copy_fm_vsp_config_no_sg_params(
117470 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
117471 + ioc_fm_vsp_config_no_sg_params_t *param,
117472 + uint8_t compat)
117473 +{
117474 + _fm_cpt_dbg (compat, " {->...\n");
117475 +
117476 + if (compat == COMPAT_US_TO_K)
117477 + {
117478 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117479 + param->no_sg = compat_param->no_sg;
117480 + }
117481 +
117482 + _fm_cpt_dbg (compat, " ...->}\n");
117483 +}
117484 +
117485 +void compat_copy_fm_vsp_prs_result_params(
117486 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
117487 + ioc_fm_vsp_prs_result_params_t *param,
117488 + uint8_t compat)
117489 +{
117490 + _fm_cpt_dbg (compat, " {->...\n");
117491 +
117492 + if (compat == COMPAT_US_TO_K)
117493 + {
117494 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117495 + /* p_data is an user-space pointer that needs to remain unmodified */
117496 + param->p_data = (void *)(unsigned long long)compat_param->p_data;
117497 + }
117498 + else
117499 + {
117500 + compat_param->p_fm_vsp = compat_pcd_ptr2id(param->p_fm_vsp);
117501 + /* p_data is an user-space pointer that needs to remain unmodified */
117502 + compat_param->p_data = (compat_uptr_t)((unsigned long long)param->p_data & 0xFFFFFFFF);
117503 + }
117504 +
117505 + _fm_cpt_dbg (compat, " ...->}\n");
117506 +}
117507 +#endif /* (DPAA_VERSION >= 11) */
117508 --- /dev/null
117509 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
117510 @@ -0,0 +1,755 @@
117511 +/*
117512 + * Copyright 2008-2012 Freescale Semiconductor Inc.
117513 + *
117514 + * Redistribution and use in source and binary forms, with or without
117515 + * modification, are permitted provided that the following conditions are met:
117516 + * * Redistributions of source code must retain the above copyright
117517 + * notice, this list of conditions and the following disclaimer.
117518 + * * Redistributions in binary form must reproduce the above copyright
117519 + * notice, this list of conditions and the following disclaimer in the
117520 + * documentation and/or other materials provided with the distribution.
117521 + * * Neither the name of Freescale Semiconductor nor the
117522 + * names of its contributors may be used to endorse or promote products
117523 + * derived from this software without specific prior written permission.
117524 + *
117525 + *
117526 + * ALTERNATIVELY, this software may be distributed under the terms of the
117527 + * GNU General Public License ("GPL") as published by the Free Software
117528 + * Foundation, either version 2 of that License or (at your option) any
117529 + * later version.
117530 + *
117531 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
117532 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
117533 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
117534 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
117535 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
117536 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
117537 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
117538 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
117539 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
117540 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
117541 + */
117542 +
117543 +/*
117544 + @File lnxwrp_ioctls_fm_compat.h
117545 +
117546 + @Description FM PCD compat structures definition.
117547 +
117548 +*/
117549 +
117550 +#ifndef __FM_COMPAT_IOCTLS_H
117551 +#define __FM_COMPAT_IOCTLS_H
117552 +
117553 +#include <linux/compat.h>
117554 +
117555 +#define COMPAT_K_TO_US 0 /* copy from Kernel to User */
117556 +#define COMPAT_US_TO_K 1 /* copy from User to Kernel */
117557 +#define COMPAT_GENERIC 2
117558 +
117559 +#define COMPAT_COPY_K2US(dest, src, type) compat_copy_##type(src, dest, 0)
117560 +#define COMPAT_COPY_US2K(dest, src, type) compat_copy_##type(dest, src, 1)
117561 +
117562 +/* mapping kernel pointers w/ UserSpace id's { */
117563 +/* Because compat_ptr(ptr_to_compat(X)) != X, this way we cannot exchange pointers
117564 + back and forth (US - KS). compat_ptr is a cast and pointers are broken. */
117565 +#define COMPAT_PTR2ID_ARRAY_MAX (512+1) /* first location is not used */
117566 +#define COMPAT_PTR2ID_WATERMARK 0xface0000
117567 +#define COMPAT_PTR2ID_WM_MASK 0xffff0000
117568 +
117569 +/* define it for debug trace */
117570 +/*#define FM_COMPAT_DBG*/
117571 +
117572 +#define _fm_cpt_prk(stage, format, arg...) \
117573 + printk(stage "fm_cpt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
117574 +
117575 +#define _fm_cpt_inf(format, arg...) _fm_cpt_prk(KERN_INFO, format, ##arg)
117576 +#define _fm_cpt_wrn(format, arg...) _fm_cpt_prk(KERN_WARNING, format, ##arg)
117577 +#define _fm_cpt_err(format, arg...) _fm_cpt_prk(KERN_ERR, format, ##arg)
117578 +
117579 +/* used for compat IOCTL debugging */
117580 +#if defined(FM_COMPAT_DBG)
117581 + #define _fm_cpt_dbg(from, format, arg...) \
117582 + do{ \
117583 + if (from == COMPAT_US_TO_K) \
117584 + printk("fm_cpt to KS [%s:%u](cpu:%u) - " format, \
117585 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117586 + else if (from == COMPAT_K_TO_US) \
117587 + printk("fm_cpt to US [%s:%u](cpu:%u) - " format, \
117588 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117589 + else \
117590 + printk("fm_cpt [%s:%u](cpu:%u) - " format, \
117591 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117592 + }while(0)
117593 +#else
117594 +# define _fm_cpt_dbg(arg...)
117595 +#endif
117596 +
117597 +/*TODO: per FMan module:
117598 + *
117599 + * Parser: FM_MAP_TYPE_PARSER_NODE,
117600 + * Kg: FM_MAP_TYPE_KG_NODE,
117601 + * Policer: FM_MAP_TYPE_POLICER_NODE
117602 + * Manip: FM_MAP_TYPE_MANIP_NODE
117603 + **/
117604 +enum fm_map_node_type {
117605 + FM_MAP_TYPE_UNSPEC = 0,
117606 + FM_MAP_TYPE_PCD_NODE,
117607 +
117608 + /* add types here, update the policy */
117609 +
117610 + __FM_MAP_TYPE_AFTER_LAST,
117611 + FM_MAP_TYPE_MAX = __FM_MAP_TYPE_AFTER_LAST - 1
117612 +};
117613 +
117614 +void compat_del_ptr2id(void *p, enum fm_map_node_type);
117615 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type);
117616 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type);
117617 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type);
117618 +
117619 +static inline compat_uptr_t compat_pcd_ptr2id(void *ptr) {
117620 + return (ptr)? compat_get_ptr2id(ptr, FM_MAP_TYPE_PCD_NODE)
117621 + : (compat_uptr_t) 0;
117622 +}
117623 +
117624 +static inline void *compat_pcd_id2ptr(compat_uptr_t id) {
117625 + return (id) ? compat_get_id2ptr(id, FM_MAP_TYPE_PCD_NODE)
117626 + : NULL;
117627 +}
117628 +
117629 +/* other similar inlines may be added as new nodes are added
117630 + to enum fm_map_node_type above... */
117631 +/* } mapping kernel pointers w/ UserSpace id's */
117632 +
117633 +/* pcd compat structures { */
117634 +typedef struct ioc_compat_fm_pcd_cc_node_remove_key_params_t {
117635 + compat_uptr_t id;
117636 + uint16_t key_indx;
117637 +} ioc_compat_fm_pcd_cc_node_remove_key_params_t;
117638 +
117639 +typedef union ioc_compat_fm_pcd_plcr_next_engine_params_u {
117640 + ioc_fm_pcd_done_action action;
117641 + compat_uptr_t p_profile;
117642 + compat_uptr_t p_direct_scheme;
117643 +} ioc_compat_fm_pcd_plcr_next_engine_params_u;
117644 +
117645 +typedef struct ioc_compat_fm_pcd_plcr_profile_params_t {
117646 + bool modify;
117647 + union {
117648 + struct {
117649 + ioc_fm_pcd_profile_type_selection profile_type;
117650 + compat_uptr_t p_fm_port;
117651 + uint16_t relative_profile_id;
117652 + } new_params;
117653 + compat_uptr_t p_profile;
117654 + } profile_select;
117655 + ioc_fm_pcd_plcr_algorithm_selection alg_selection;
117656 + ioc_fm_pcd_plcr_color_mode color_mode;
117657 +
117658 + union {
117659 + ioc_fm_pcd_plcr_color dflt_color;
117660 + ioc_fm_pcd_plcr_color override;
117661 + } color;
117662 +
117663 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param;
117664 +
117665 + ioc_fm_pcd_engine next_engine_on_green;
117666 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_green;
117667 +
117668 + ioc_fm_pcd_engine next_engine_on_yellow;
117669 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_yellow;
117670 +
117671 + ioc_fm_pcd_engine next_engine_on_red;
117672 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_red;
117673 +
117674 + bool trap_profile_on_flow_A;
117675 + bool trap_profile_on_flow_B;
117676 + bool trap_profile_on_flow_C;
117677 + compat_uptr_t id;
117678 +} ioc_compat_fm_pcd_plcr_profile_params_t;
117679 +
117680 +typedef struct ioc_compat_fm_obj_t {
117681 + compat_uptr_t obj;
117682 +} ioc_compat_fm_obj_t;
117683 +
117684 +typedef struct ioc_compat_fm_pcd_kg_scheme_select_t {
117685 + bool direct;
117686 + compat_uptr_t scheme_id;
117687 +} ioc_compat_fm_pcd_kg_scheme_select_t;
117688 +
117689 +typedef struct ioc_compat_fm_pcd_port_schemes_params_t {
117690 + uint8_t num_of_schemes;
117691 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
117692 +} ioc_compat_fm_pcd_port_schemes_params_t;
117693 +
117694 +#if (DPAA_VERSION >= 11)
117695 +typedef struct ioc_compat_fm_port_vsp_alloc_params_t {
117696 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
117697 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
117698 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
117699 + if relevant function called for Rx port */
117700 + compat_uptr_t p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
117701 +}ioc_compat_fm_port_vsp_alloc_params_t;
117702 +#endif /* (DPAA_VERSION >= 11) */
117703 +
117704 +typedef struct ioc_compat_fm_pcd_net_env_params_t {
117705 + uint8_t num_of_distinction_units;
117706 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* same structure*/
117707 + compat_uptr_t id;
117708 +} ioc_compat_fm_pcd_net_env_params_t;
117709 +
117710 +typedef struct ioc_compat_fm_pcd_prs_sw_params_t {
117711 + bool override;
117712 + uint32_t size;
117713 + uint16_t base;
117714 + compat_uptr_t p_code;
117715 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
117716 + uint8_t num_of_labels;
117717 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
117718 +} ioc_compat_fm_pcd_prs_sw_params_t;
117719 +
117720 +typedef struct ioc_compat_fm_pcd_cc_next_kg_params_t {
117721 + bool override_fqid;
117722 + uint32_t new_fqid;
117723 +#if DPAA_VERSION >= 11
117724 + uint8_t new_relative_storage_profile_id;
117725 +#endif
117726 + compat_uptr_t p_direct_scheme;
117727 +} ioc_compat_fm_pcd_cc_next_kg_params_t;
117728 +
117729 +typedef struct ioc_compat_fm_pcd_cc_next_cc_params_t {
117730 + compat_uptr_t cc_node_id;
117731 +} ioc_compat_fm_pcd_cc_next_cc_params_t;
117732 +
117733 +#if DPAA_VERSION >= 11
117734 +typedef struct ioc_compat_fm_pcd_cc_next_fr_params_t {
117735 + compat_uptr_t frm_replic_id;
117736 +} ioc_compat_fm_pcd_cc_next_fr_params_t;
117737 +#endif /* DPAA_VERSION >= 11 */
117738 +
117739 +typedef struct ioc_compat_fm_pcd_cc_next_engine_params_t {
117740 + ioc_fm_pcd_engine next_engine;
117741 + union {
117742 + ioc_compat_fm_pcd_cc_next_cc_params_t cc_params; /**< compat structure*/
117743 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< same structure*/
117744 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< same structure*/
117745 + ioc_compat_fm_pcd_cc_next_kg_params_t kg_params; /**< compat structure*/
117746 +#if DPAA_VERSION >= 11
117747 + ioc_compat_fm_pcd_cc_next_fr_params_t fr_params; /**< compat structure*/
117748 +#endif /* DPAA_VERSION >= 11 */
117749 + } params;
117750 + compat_uptr_t manip_id;
117751 + bool statistics_en;
117752 +} ioc_compat_fm_pcd_cc_next_engine_params_t;
117753 +
117754 +typedef struct ioc_compat_fm_pcd_cc_grp_params_t {
117755 + uint8_t num_of_distinction_units;
117756 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
117757 + 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];
117758 +} ioc_compat_fm_pcd_cc_grp_params_t;
117759 +
117760 +typedef struct ioc_compat_fm_pcd_cc_tree_params_t {
117761 + compat_uptr_t net_env_id;
117762 + uint8_t num_of_groups;
117763 + ioc_compat_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
117764 + compat_uptr_t id;
117765 +} ioc_compat_fm_pcd_cc_tree_params_t;
117766 +
117767 +typedef struct ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t {
117768 + compat_uptr_t id;
117769 + uint8_t grp_indx;
117770 + uint8_t indx;
117771 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
117772 +} ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t;
117773 +
117774 +typedef struct ioc_compat_fm_pcd_cc_key_params_t {
117775 + compat_uptr_t p_key;
117776 + compat_uptr_t p_mask;
117777 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; /**< compat structure*/
117778 +} ioc_compat_fm_pcd_cc_key_params_t;
117779 +
117780 +typedef struct ioc_compat_keys_params_t {
117781 + uint16_t max_num_of_keys;
117782 + bool mask_support;
117783 + ioc_fm_pcd_cc_stats_mode statistics_mode;
117784 +#if (DPAA_VERSION >= 11)
117785 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
117786 +#endif /* (DPAA_VERSION >= 11) */
117787 + uint16_t num_of_keys;
117788 + uint8_t key_size;
117789 + ioc_compat_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; /**< compat structure*/
117790 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; /**< compat structure*/
117791 +} ioc_compat_keys_params_t;
117792 +
117793 +typedef struct ioc_compat_fm_pcd_cc_node_params_t {
117794 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< same structure*/
117795 + ioc_compat_keys_params_t keys_params; /**< compat structure*/
117796 + compat_uptr_t id;
117797 +} ioc_compat_fm_pcd_cc_node_params_t;
117798 +
117799 +/**************************************************************************//**
117800 + @Description Parameters for defining a hash table
117801 +*//***************************************************************************/
117802 +typedef struct ioc_compat_fm_pcd_hash_table_params_t {
117803 + uint16_t max_num_of_keys;
117804 + ioc_fm_pcd_cc_stats_mode statistics_mode;
117805 + uint8_t kg_hash_shift;
117806 + uint16_t hash_res_mask;
117807 + uint8_t hash_shift;
117808 + uint8_t match_key_size;
117809 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
117810 + compat_uptr_t id;
117811 +} ioc_compat_fm_pcd_hash_table_params_t;
117812 +
117813 +typedef struct ioc_compat_fm_pcd_hash_table_add_key_params_t {
117814 + compat_uptr_t p_hash_tbl;
117815 + uint8_t key_size;
117816 + ioc_compat_fm_pcd_cc_key_params_t key_params;
117817 +} ioc_compat_fm_pcd_hash_table_add_key_params_t;
117818 +
117819 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_params_t {
117820 + compat_uptr_t id;
117821 + uint16_t key_indx;
117822 + uint8_t key_size;
117823 + compat_uptr_t p_key;
117824 + compat_uptr_t p_mask;
117825 +} ioc_compat_fm_pcd_cc_node_modify_key_params_t;
117826 +
117827 +typedef struct ioc_compat_fm_pcd_hash_table_remove_key_params_t {
117828 + compat_uptr_t p_hash_tbl;
117829 + uint8_t key_size;
117830 + compat_uptr_t p_key;
117831 +} ioc_compat_fm_pcd_hash_table_remove_key_params_t;
117832 +
117833 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
117834 + compat_uptr_t id;
117835 + uint16_t key_indx;
117836 + uint8_t key_size;
117837 + ioc_compat_fm_pcd_cc_key_params_t key_params;
117838 +} ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
117839 +
117840 +typedef struct ioc_compat_fm_port_pcd_plcr_params_t {
117841 + compat_uptr_t plcr_profile_id;
117842 +} ioc_compat_fm_port_pcd_plcr_params_t;
117843 +
117844 +typedef struct ioc_compat_fm_port_pcd_cc_params_t {
117845 + compat_uptr_t cc_tree_id;
117846 +} ioc_compat_fm_port_pcd_cc_params_t;
117847 +
117848 +typedef struct ioc_compat_fm_port_pcd_kg_params_t {
117849 + uint8_t num_of_schemes;
117850 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
117851 + bool direct_scheme;
117852 + compat_uptr_t direct_scheme_id;
117853 +} ioc_compat_fm_port_pcd_kg_params_t;
117854 +
117855 +typedef struct ioc_compat_fm_port_pcd_params_t {
117856 + ioc_fm_port_pcd_support pcd_support;
117857 + compat_uptr_t net_env_id;
117858 + compat_uptr_t p_prs_params;
117859 + compat_uptr_t p_cc_params;
117860 + compat_uptr_t p_kg_params;
117861 + compat_uptr_t p_plcr_params;
117862 + compat_uptr_t p_ip_reassembly_manip;
117863 +#if DPAA_VERSION >= 11
117864 + compat_uptr_t p_capwap_reassembly_manip;
117865 +#endif
117866 +} ioc_compat_fm_port_pcd_params_t;
117867 +
117868 +typedef struct ioc_compat_fm_pcd_kg_cc_t {
117869 + compat_uptr_t tree_id;
117870 + uint8_t grp_id;
117871 + bool plcr_next;
117872 + bool bypass_plcr_profile_generation;
117873 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
117874 +} ioc_compat_fm_pcd_kg_cc_t;
117875 +
117876 +typedef struct ioc_compat_fm_pcd_kg_scheme_params_t {
117877 + bool modify;
117878 + union {
117879 + uint8_t relative_scheme_id;
117880 + compat_uptr_t scheme_id;
117881 + } scm_id;
117882 + bool always_direct;
117883 + struct {
117884 + compat_uptr_t net_env_id;
117885 + uint8_t num_of_distinction_units;
117886 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
117887 + } net_env_params;
117888 + bool use_hash;
117889 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
117890 + bool bypass_fqid_generation;
117891 + uint32_t base_fqid;
117892 + uint8_t num_of_used_extracted_ors;
117893 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
117894 +#if DPAA_VERSION >= 11
117895 + bool override_storage_profile;
117896 + ioc_fm_pcd_kg_storage_profile_t storage_profile;
117897 +#endif /* DPAA_VERSION >= 11 */
117898 + ioc_fm_pcd_engine next_engine;
117899 + union{
117900 + ioc_fm_pcd_done_action done_action;
117901 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
117902 + ioc_compat_fm_pcd_kg_cc_t cc;
117903 + } kg_next_engine_params;
117904 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter;
117905 + compat_uptr_t id;
117906 +} ioc_compat_fm_pcd_kg_scheme_params_t;
117907 +
117908 +typedef struct ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t {
117909 + compat_uptr_t id;
117910 + uint16_t key_indx;
117911 + uint8_t key_size;
117912 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
117913 +} ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t;
117914 +
117915 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t {
117916 + uint8_t offset;
117917 + uint8_t size;
117918 + bool replace;
117919 + compat_uptr_t p_data;
117920 +} ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t;
117921 +
117922 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
117923 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2;
117924 + bool update;
117925 + uint8_t size;
117926 + compat_uptr_t p_data;
117927 +} ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
117928 +
117929 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_t {
117930 + uint8_t size; /**< size of inserted section */
117931 + compat_uptr_t p_data; /**< data to be inserted */
117932 +} ioc_compat_fm_pcd_manip_hdr_insrt_t;
117933 +
117934 +#if (DPAA_VERSION >= 11)
117935 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t {
117936 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
117937 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
117938 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
117939 + the inserted header */
117940 + uint16_t id; /**< 16 bit New IP ID */
117941 + bool dont_frag_overwrite;
117942 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
117943 + * This byte is configured to be overwritten when RPD is set. */
117944 + uint8_t last_dst_offset;
117945 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
117946 + * in order to calculate UDP checksum pseudo header;
117947 + * Otherwise set it to '0'. */
117948 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
117949 +} ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t;
117950 +#endif /* (DPAA_VERSION >= 11) */
117951 +
117952 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
117953 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type;
117954 + union {
117955 + ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
117956 +#if (DPAA_VERSION >= 11)
117957 + ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t ip_params;
117958 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt;
117959 +#endif /* (DPAA_VERSION >= 11) */
117960 + } u;
117961 +} ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
117962 +
117963 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_params_t {
117964 + ioc_fm_pcd_manip_hdr_insrt_type type;
117965 + union {
117966 + ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr;
117967 + ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t generic;
117968 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
117969 +#error "FM_CAPWAP_SUPPORT feature not supported!"
117970 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
117971 +#endif /* FM_CAPWAP_SUPPORT */
117972 + } u;
117973 +} ioc_compat_fm_pcd_manip_hdr_insrt_params_t;
117974 +
117975 +typedef struct ioc_compat_fm_pcd_manip_hdr_params_t {
117976 + bool rmv;
117977 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params;
117978 + bool insrt;
117979 + ioc_compat_fm_pcd_manip_hdr_insrt_params_t insrt_params;
117980 + bool field_update;
117981 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params;
117982 + bool custom;
117983 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params;
117984 + bool dont_parse_after_manip;
117985 +} ioc_compat_fm_pcd_manip_hdr_params_t;
117986 +
117987 +typedef struct ioc_compat_fm_pcd_manip_special_offload_params_t {
117988 + bool decryption;
117989 + bool ecn_copy;
117990 + bool dscp_copy;
117991 + bool variable_ip_hdr_len;
117992 + bool variable_ip_version;
117993 + uint8_t outer_ip_hdr_len;
117994 + uint16_t arw_size;
117995 + compat_uptr_t arw_addr;
117996 +} ioc_compat_fm_pcd_manip_special_offload_params_t;
117997 +
117998 +typedef struct ioc_compat_fm_pcd_manip_params_t {
117999 + ioc_fm_pcd_manip_type type;
118000 + union {
118001 + ioc_compat_fm_pcd_manip_hdr_params_t hdr;
118002 + ioc_fm_pcd_manip_reassem_params_t reassem;
118003 + ioc_fm_pcd_manip_frag_params_t frag;
118004 + ioc_compat_fm_pcd_manip_special_offload_params_t special_offload;
118005 + } u;
118006 + compat_uptr_t p_next_manip;
118007 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
118008 +#error "FM_CAPWAP_SUPPORT feature not supported!"
118009 + bool frag_or_reasm;
118010 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;
118011 +#endif /* FM_CAPWAP_SUPPORT */
118012 + compat_uptr_t id;
118013 +} ioc_compat_fm_pcd_manip_params_t;
118014 +
118015 +typedef struct ioc_compat_fm_pcd_manip_get_stats_t {
118016 + compat_uptr_t id;
118017 + ioc_fm_pcd_manip_stats_t stats;
118018 +} ioc_compat_fm_pcd_manip_get_stats_t;
118019 +
118020 +#if (DPAA_VERSION >= 11)
118021 +typedef struct ioc_compat_fm_pcd_frm_replic_group_params_t {
118022 + uint8_t max_num_of_entries;
118023 + uint8_t num_of_entries;
118024 + ioc_compat_fm_pcd_cc_next_engine_params_t
118025 + next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
118026 + compat_uptr_t id;
118027 +} ioc_compat_fm_pcd_frm_replic_group_params_t;
118028 +
118029 +typedef struct ioc_compat_fm_pcd_frm_replic_member_t {
118030 + compat_uptr_t h_replic_group;
118031 + uint16_t member_index;
118032 +} ioc_compat_fm_pcd_frm_replic_member_t;
118033 +
118034 +typedef struct ioc_compat_fm_pcd_frm_replic_member_params_t {
118035 + ioc_compat_fm_pcd_frm_replic_member_t member;
118036 + ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_params;
118037 +} ioc_compat_fm_pcd_frm_replic_member_params_t;
118038 +
118039 +typedef struct ioc_compat_fm_vsp_params_t {
118040 + compat_uptr_t p_fm; /**< A handle to the FM object this VSP related to */
118041 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
118042 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
118043 + parameter associated with Rx / OP port */
118044 + uint16_t liodn_offset; /**< VSP's LIODN offset */
118045 + struct {
118046 + ioc_fm_port_type port_type; /**< Port type */
118047 + uint8_t port_id; /**< Port Id - relative to type */
118048 + } port_params;
118049 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
118050 + defined in relevant FM object */
118051 + compat_uptr_t id; /**< return value */
118052 +} ioc_compat_fm_vsp_params_t;
118053 +
118054 +typedef struct ioc_compat_fm_buf_pool_depletion_params_t {
118055 + compat_uptr_t p_fm_vsp;
118056 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
118057 +} ioc_compat_fm_buf_pool_depletion_params_t;
118058 +
118059 +typedef struct ioc_compat_fm_buffer_prefix_content_params_t {
118060 + compat_uptr_t p_fm_vsp;
118061 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
118062 +} ioc_compat_fm_buffer_prefix_content_params_t;
118063 +
118064 +typedef struct ioc_compat_fm_vsp_config_no_sg_params_t {
118065 + compat_uptr_t p_fm_vsp;
118066 + bool no_sg;
118067 +} ioc_compat_fm_vsp_config_no_sg_params_t;
118068 +
118069 +typedef struct ioc_compat_fm_vsp_prs_result_params_t {
118070 + compat_uptr_t p_fm_vsp;
118071 + compat_uptr_t p_data;
118072 +} ioc_compat_fm_vsp_prs_result_params_t;
118073 +
118074 +#endif /* (DPAA_VERSION >= 11) */
118075 +typedef struct ioc_compat_fm_pcd_kg_scheme_spc_t {
118076 + uint32_t val;
118077 + compat_uptr_t id;
118078 +} ioc_compat_fm_pcd_kg_scheme_spc_t;
118079 +
118080 +typedef struct ioc_compat_fm_ctrl_mon_counters_params_t {
118081 + uint8_t fm_ctrl_index;
118082 + compat_uptr_t p_mon;
118083 +} ioc_compat_fm_ctrl_mon_counters_params_t;
118084 +
118085 +typedef struct ioc_compat_fm_pcd_cc_tbl_get_stats_t {
118086 + compat_uptr_t id;
118087 + uint16_t key_index;
118088 + ioc_fm_pcd_cc_key_statistics_t statistics;
118089 +} ioc_compat_fm_pcd_cc_tbl_get_stats_t;
118090 +
118091 +
118092 +/* } pcd compat structures */
118093 +
118094 +void compat_obj_delete(
118095 + ioc_compat_fm_obj_t *compat_id,
118096 + ioc_fm_obj_t *id);
118097 +
118098 +/* pcd compat functions { */
118099 +void compat_copy_fm_pcd_plcr_profile(
118100 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
118101 + ioc_fm_pcd_plcr_profile_params_t *param,
118102 + uint8_t compat);
118103 +
118104 +void compat_copy_fm_pcd_cc_key(
118105 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
118106 + ioc_fm_pcd_cc_key_params_t *param,
118107 + uint8_t compat);
118108 +
118109 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
118110 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
118111 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
118112 + uint8_t compat);
118113 +
118114 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
118115 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
118116 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
118117 + uint8_t compat);
118118 +
118119 +void compat_fm_pcd_cc_tree_modify_next_engine(
118120 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
118121 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
118122 + uint8_t compat);
118123 +
118124 +void compat_copy_fm_pcd_hash_table(
118125 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
118126 + ioc_fm_pcd_hash_table_params_t *param,
118127 + uint8_t compat);
118128 +
118129 +void compat_copy_fm_pcd_cc_grp(
118130 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
118131 + ioc_fm_pcd_cc_grp_params_t *param,
118132 + uint8_t compat);
118133 +
118134 +void compat_copy_fm_pcd_cc_tree(
118135 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
118136 + ioc_fm_pcd_cc_tree_params_t *param,
118137 + uint8_t compat);
118138 +
118139 +void compat_copy_fm_pcd_cc_tbl_get_stats(
118140 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
118141 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
118142 + uint8_t compat);
118143 +
118144 +void compat_fm_pcd_prs_sw(
118145 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
118146 + ioc_fm_pcd_prs_sw_params_t *param,
118147 + uint8_t compat);
118148 +
118149 +void compat_copy_fm_pcd_kg_scheme(
118150 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
118151 + ioc_fm_pcd_kg_scheme_params_t *param,
118152 + uint8_t compat);
118153 +
118154 +void compat_copy_fm_pcd_kg_scheme_select(
118155 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
118156 + ioc_fm_pcd_kg_scheme_select_t *param,
118157 + uint8_t compat);
118158 +
118159 +void compat_copy_fm_pcd_kg_schemes_params(
118160 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
118161 + ioc_fm_pcd_port_schemes_params_t *param,
118162 + uint8_t compat);
118163 +
118164 +void compat_copy_fm_port_pcd_kg(
118165 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
118166 + ioc_fm_port_pcd_kg_params_t *param,
118167 + uint8_t compat);
118168 +
118169 +void compat_copy_fm_port_pcd(
118170 + ioc_compat_fm_port_pcd_params_t *compat_param,
118171 + ioc_fm_port_pcd_params_t *param,
118172 + uint8_t compat);
118173 +
118174 +#if (DPAA_VERSION >= 11)
118175 +void compat_copy_fm_port_vsp_alloc_params(
118176 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
118177 + ioc_fm_port_vsp_alloc_params_t *param,
118178 + uint8_t compat);
118179 +#endif /* (DPAA_VERSION >= 11) */
118180 +
118181 +void compat_copy_fm_pcd_net_env(
118182 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
118183 + ioc_fm_pcd_net_env_params_t *param,
118184 + uint8_t compat);
118185 +
118186 +void compat_copy_fm_pcd_cc_node_modify_key(
118187 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
118188 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
118189 + uint8_t compat);
118190 +
118191 +void compat_copy_keys(
118192 + ioc_compat_keys_params_t *compat_param,
118193 + ioc_keys_params_t *param,
118194 + uint8_t compat);
118195 +
118196 +void compat_copy_fm_pcd_cc_node(
118197 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
118198 + ioc_fm_pcd_cc_node_params_t *param,
118199 + uint8_t compat);
118200 +
118201 +void compat_fm_pcd_manip_set_node(
118202 + ioc_compat_fm_pcd_manip_params_t *compat_param,
118203 + ioc_fm_pcd_manip_params_t *param,
118204 + uint8_t compat);
118205 +
118206 +void compat_copy_fm_pcd_manip_get_stats(
118207 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
118208 + ioc_fm_pcd_manip_get_stats_t *param,
118209 + uint8_t compat);
118210 +
118211 +void compat_copy_fm_port_pcd_modify_tree(
118212 + ioc_compat_fm_obj_t *compat_id,
118213 + ioc_fm_obj_t *id,
118214 + uint8_t compat);
118215 +
118216 +#if (DPAA_VERSION >= 11)
118217 +void compat_copy_fm_pcd_frm_replic_group_params(
118218 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
118219 + ioc_fm_pcd_frm_replic_group_params_t *param,
118220 + uint8_t compat);
118221 +
118222 +void compat_copy_fm_pcd_frm_replic_member(
118223 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
118224 + ioc_fm_pcd_frm_replic_member_t *param,
118225 + uint8_t compat);
118226 +
118227 +void compat_copy_fm_pcd_frm_replic_member_params(
118228 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
118229 + ioc_fm_pcd_frm_replic_member_params_t *param,
118230 + uint8_t compat);
118231 +
118232 +void compat_copy_fm_vsp_params(
118233 + ioc_compat_fm_vsp_params_t *compat_param,
118234 + ioc_fm_vsp_params_t *param,
118235 + uint8_t compat);
118236 +
118237 +void compat_copy_fm_buf_pool_depletion_params(
118238 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
118239 + ioc_fm_buf_pool_depletion_params_t *param,
118240 + uint8_t compat);
118241 +
118242 +void compat_copy_fm_buffer_prefix_content_params(
118243 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
118244 + ioc_fm_buffer_prefix_content_params_t *param,
118245 + uint8_t compat);
118246 +
118247 +void compat_copy_fm_vsp_config_no_sg_params(
118248 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
118249 + ioc_fm_vsp_config_no_sg_params_t *param,
118250 + uint8_t compat);
118251 +
118252 +void compat_copy_fm_vsp_prs_result_params(
118253 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
118254 + ioc_fm_vsp_prs_result_params_t *param,
118255 + uint8_t compat);
118256 +
118257 +#endif /* (DPAA_VERSION >= 11) */
118258 +
118259 +void compat_copy_fm_pcd_kg_scheme_spc(
118260 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
118261 + ioc_fm_pcd_kg_scheme_spc_t *param,
118262 + uint8_t compat);
118263 +
118264 +/* } pcd compat functions */
118265 +#endif
118266 --- /dev/null
118267 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
118268 @@ -0,0 +1,121 @@
118269 +/*
118270 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118271 + *
118272 + * Redistribution and use in source and binary forms, with or without
118273 + * modification, are permitted provided that the following conditions are met:
118274 + * * Redistributions of source code must retain the above copyright
118275 + * notice, this list of conditions and the following disclaimer.
118276 + * * Redistributions in binary form must reproduce the above copyright
118277 + * notice, this list of conditions and the following disclaimer in the
118278 + * documentation and/or other materials provided with the distribution.
118279 + * * Neither the name of Freescale Semiconductor nor the
118280 + * names of its contributors may be used to endorse or promote products
118281 + * derived from this software without specific prior written permission.
118282 + *
118283 + *
118284 + * ALTERNATIVELY, this software may be distributed under the terms of the
118285 + * GNU General Public License ("GPL") as published by the Free Software
118286 + * Foundation, either version 2 of that License or (at your option) any
118287 + * later version.
118288 + *
118289 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118290 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118291 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118292 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118293 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118294 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118295 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118296 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118297 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118298 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118299 + */
118300 +
118301 +/*
118302 + @File lnxwrp_resources.h
118303 +
118304 + @Description FMD wrapper resource allocation functions.
118305 +
118306 +*/
118307 +
118308 +#ifndef LNXWRP_RESOURCES_H_
118309 +#define LNXWRP_RESOURCES_H_
118310 +
118311 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118312 +#include "lnxwrp_fm.h"
118313 +#else
118314 +#include "lnxwrp_resources_ut.h"
118315 +#endif
118316 +
118317 +#define ROUND(X) ((2*(X)+1)/2)
118318 +#define CEIL(X) ((X)+1)
118319 +/* #define ROUND_DIV(X, Y) (((X)+(Y)/2)/(Y)) */
118320 +#define ROUND_DIV(X, Y) ((2*(X)+(Y))/(2*(Y)))
118321 +#define CEIL_DIV(X, Y) (((X)+(Y)-1)/(Y))
118322 +
118323 +/* used for resource calculus */
118324 +#define DPDE_1G 2 /* DQDP 1g - from LLD:
118325 + DEFAULT_PORT_txFifoDeqPipelineDepth_1G */
118326 +#define DPDE_10G 8 /* DQDP 10g - from LLD:
118327 + DEFAULT_PORT_txFifoDeqPipelineDepth_10G */
118328 +
118329 +int fm_set_active_fman_ports(struct platform_device *of_dev,
118330 + t_LnxWrpFmDev *p_LnxWrpFmDev);
118331 +
118332 +/* Calculate the fifosize based on MURAM allocation, number of ports, dpde
118333 + * value and s/g software support (! Kernel does not suport s/g).
118334 + *
118335 + * Algorithm summary:
118336 + * - Calculate the the minimum fifosize required for every type of port
118337 + * (TX,RX for 1G, 2.5G and 10G).
118338 + * - Set TX the minimum fifosize required.
118339 + * - Distribute the remaining buffers (after all TX were set) to RX ports
118340 + * based on:
118341 + * 1G RX = Remaining_buffers * 1/(1+2.5+10)
118342 + * 2.5G RX = Remaining_buffers * 2.5/(1+2.5+10)
118343 + * 10G RX = Remaining_buffers * 10/(1+2.5+10)
118344 + * - if the RX is smaller than the minimum required, then set the minimum
118345 + * required
118346 + * - In the end distribuite the leftovers if there are any (due to
118347 + * unprecise calculus) or if over allocation cat some buffers from all RX
118348 + * ports w/o pass over minimum required treshold, but if there must be
118349 + * pass the treshold in order to cat the over allocation ,then this
118350 + * configuration can not be set - KERN_ALERT.
118351 +*/
118352 +int fm_precalculate_fifosizes(t_LnxWrpFmDev *p_LnxWrpFmDev,
118353 + int muram_fifo_size);
118354 +
118355 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118356 +int fm_config_precalculate_fifosize(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118357 +#endif
118358 +
118359 +/* Compute FMan open DMA based on total number of open DMAs and
118360 + * number of available fman ports.
118361 + *
118362 + * By default 10g ports are set to input parameters. The other ports
118363 + * tries to keep the proportion rx=2tx open dmas or tresholds.
118364 + *
118365 + * If leftovers, then those will be set as shared.
118366 + *
118367 + * If after computing overflow appears, then it decrements open dma
118368 + * for all ports w/o cross the tresholds. If the tresholds are meet
118369 + * and is still overflow, then it returns error.
118370 +*/
118371 +int fm_precalculate_open_dma(t_LnxWrpFmDev *p_LnxWrpFmDev,
118372 + int max_fm_open_dma,
118373 + int default_tx_10g_dmas,
118374 + int default_rx_10g_dmas,
118375 + int min_tx_10g_treshold, int min_rx_10g_treshold);
118376 +
118377 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118378 +int fm_config_precalculate_open_dma(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118379 +#endif
118380 +
118381 +/* Compute FMan tnums based on available tnums and number of ports.
118382 + * Set defaults (minim tresholds) and then distribute leftovers.*/
118383 +int fm_precalculate_tnums(t_LnxWrpFmDev *p_LnxWrpFmDev, int max_fm_tnums);
118384 +
118385 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118386 +int fm_config_precalculate_tnums(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118387 +#endif
118388 +
118389 +#endif /* LNXWRP_RESOURCES_H_ */
118390 --- /dev/null
118391 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
118392 @@ -0,0 +1,191 @@
118393 +/* Copyright (c) 2012 Freescale Semiconductor, Inc.
118394 + * All rights reserved.
118395 + *
118396 + * Redistribution and use in source and binary forms, with or without
118397 + * modification, are permitted provided that the following conditions are met:
118398 + * * Redistributions of source code must retain the above copyright
118399 + * notice, this list of conditions and the following disclaimer.
118400 + * * Redistributions in binary form must reproduce the above copyright
118401 + * notice, this list of conditions and the following disclaimer in the
118402 + * documentation and/or other materials provided with the distribution.
118403 + * * Neither the name of Freescale Semiconductor nor the
118404 + * names of its contributors may be used to endorse or promote products
118405 + * derived from this software without specific prior written permission.
118406 + *
118407 + *
118408 + * ALTERNATIVELY, this software may be distributed under the terms of the
118409 + * GNU General Public License ("GPL") as published by the Free Software
118410 + * Foundation, either version 2 of that License or (at your option) any
118411 + * later version.
118412 + *
118413 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118414 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118415 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118416 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118417 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118418 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118419 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118420 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118421 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118422 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118423 + */
118424 +
118425 +#include "lnxwrp_resources.h"
118426 +#include "lnxwrp_resources_ut.h"
118427 +
118428 +#define KILOBYTE 0x400 /* 1024 */
118429 +
118430 +typedef enum e_board_type {
118431 + e_p3041,
118432 + e_p4080,
118433 + e_p5020,
118434 + e_p1023
118435 +} e_board_type;
118436 +
118437 +uint8_t board_type;
118438 +uint32_t muram_size = 0;
118439 +uint32_t dmas_num = 0;
118440 +uint32_t task_num = 0;
118441 +uint32_t frame_size = 0;
118442 +uint32_t oh_num = 0;
118443 +uint32_t num_ports_1g = 0;
118444 +uint32_t num_ports_10g = 0;
118445 +uint32_t num_ports_2g5 = 0;
118446 +uint32_t fsl_fman_phy_maxfrm = 0;
118447 +uint32_t dpa_rx_extra_headroom = 0;
118448 +
118449 +void show_help(void){
118450 + printf(" help: \n");
118451 + printf(" -b <board_type> -f <max_fram_size(mtu)> -o <num_oh_ports> -g1"
118452 + " <num_1g_ports> -g10 <num_10g_ports> -g25 <num_2g5_ports>\n");
118453 + printf(" Maxim num of DMAS availbale: P3/P4/P5:32 , P1023:16 \n");
118454 + printf(" Maxim num of TNUMs availbale: P3/P4/P5:128, P1023:32 \n");
118455 + printf(" Muram size: P3/P4/P5:160K, P1023:64K \n");
118456 + printf(" Number of ports:\n");
118457 + printf(" P3/P5: 5p 1g, 1p 10g, 7p oh \n");
118458 + printf(" P4 : 4p 1g, 1p 10g, 7p oh \n");
118459 + printf(" P1 : 2p 1g, 0p 10g, 4p oh \n");
118460 + printf(" MTU: Default:1522, Jumbo:9600 \n");
118461 +}
118462 +
118463 +int fm_set_param(t_LnxWrpFmDev *p_LnxWrpFmDev) {
118464 + struct fm_active_ports *fm_active_ports_info = NULL;
118465 + fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info;
118466 +
118467 + switch(board_type){
118468 + case e_p3041:
118469 + case e_p5020:
118470 + muram_size = 160*KILOBYTE;
118471 + dmas_num = 32;
118472 + task_num = 128;
118473 + if ((num_ports_1g+num_ports_2g5) > 5 || num_ports_10g > 1 || oh_num > 7)
118474 + goto err_fm_set_param;
118475 + break;
118476 + case e_p4080:
118477 + muram_size = 160*KILOBYTE;
118478 + dmas_num = 32;
118479 + task_num = 128;
118480 + if ((num_ports_1g+num_ports_2g5) > 4 || num_ports_10g > 1 || oh_num > 7)
118481 + goto err_fm_set_param;
118482 + break;
118483 + case e_p1023:
118484 + muram_size = 64*KILOBYTE;
118485 + dmas_num = 16;
118486 + task_num = 128;
118487 + if ((num_ports_1g+num_ports_2g5) > 2 || oh_num > 4)
118488 + goto err_fm_set_param;
118489 + break;
118490 + default:
118491 + goto err_fm_set_param;
118492 + break;
118493 + }
118494 +
118495 + p_LnxWrpFmDev->id = 0;
118496 + fsl_fman_phy_maxfrm = frame_size;
118497 + dpa_rx_extra_headroom = 0; /* ATTENTION: can be != 0 */
118498 + fm_active_ports_info->num_oh_ports = oh_num;
118499 + fm_active_ports_info->num_tx_ports = num_ports_1g;
118500 + fm_active_ports_info->num_rx_ports = num_ports_1g;
118501 + fm_active_ports_info->num_tx25_ports = num_ports_2g5;
118502 + fm_active_ports_info->num_rx25_ports = num_ports_2g5;
118503 + fm_active_ports_info->num_tx10_ports = num_ports_10g;
118504 + fm_active_ports_info->num_rx10_ports = num_ports_10g;
118505 +
118506 + return 0;
118507 +
118508 +err_fm_set_param:
118509 + printf(" ERR: To many ports!!! \n");
118510 + return -1;
118511 +}
118512 +
118513 +int main (int argc, char *argv[]){
118514 + t_LnxWrpFmDev LnxWrpFmDev;
118515 + t_LnxWrpFmDev *p_LnxWrpFmDev = &LnxWrpFmDev;
118516 + int tokens_cnt = 1;
118517 +
118518 + char *token = NULL;
118519 +
118520 + while(tokens_cnt < argc)
118521 + {
118522 + token = argv[tokens_cnt++];
118523 + if (strcmp(token, "-b") == 0){
118524 + if(strcmp(argv[tokens_cnt],"p3") == 0)
118525 + board_type = e_p3041;
118526 + else if(strcmp(argv[tokens_cnt],"p4") == 0)
118527 + board_type = e_p4080;
118528 + else if(strcmp(argv[tokens_cnt],"p5") == 0)
118529 + board_type = e_p5020;
118530 + else if(strcmp(argv[tokens_cnt],"p1") == 0)
118531 + board_type = e_p1023;
118532 + else
118533 + show_help();
118534 + tokens_cnt++;
118535 + }
118536 + else if(strcmp(token, "-d") == 0){
118537 + dmas_num = atoi(argv[tokens_cnt++]);
118538 + }
118539 + else if(strcmp(token, "-t") == 0)
118540 + task_num = atoi(argv[tokens_cnt++]);
118541 + else if(strcmp(token, "-f") == 0)
118542 + frame_size = atoi(argv[tokens_cnt++]);
118543 + else if(strcmp(token, "-o") == 0)
118544 + oh_num = atoi(argv[tokens_cnt++]);
118545 + else if(strcmp(token, "-g1") == 0)
118546 + num_ports_1g = atoi(argv[tokens_cnt++]);
118547 + else if(strcmp(token, "-g10") == 0)
118548 + num_ports_10g = atoi(argv[tokens_cnt++]);
118549 + else if(strcmp(token, "-g25") == 0)
118550 + num_ports_2g5 = atoi(argv[tokens_cnt++]);
118551 + else {
118552 + show_help();
118553 + return -1;
118554 + }
118555 + }
118556 +
118557 + if(fm_set_param(p_LnxWrpFmDev) < 0){
118558 + show_help();
118559 + return -1;
118560 + }
118561 +
118562 + if(fm_precalculate_fifosizes(
118563 + p_LnxWrpFmDev,
118564 + 128*KILOBYTE)
118565 + != 0)
118566 + return -1;
118567 + if(fm_precalculate_open_dma(
118568 + p_LnxWrpFmDev,
118569 + dmas_num, /* max open dmas:dpaa_integration_ext.h */
118570 + FM_DEFAULT_TX10G_OPENDMA, /* default TX 10g open dmas */
118571 + FM_DEFAULT_RX10G_OPENDMA, /* default RX 10g open dmas */
118572 + FM_10G_OPENDMA_MIN_TRESHOLD,/* TX 10g minimum treshold */
118573 + FM_10G_OPENDMA_MIN_TRESHOLD)/* RX 10g minimum treshold */
118574 + != 0)
118575 + return -1;
118576 + if(fm_precalculate_tnums(
118577 + p_LnxWrpFmDev,
118578 + task_num) /* max TNUMS: dpa integration file. */
118579 + != 0)
118580 + return -1;
118581 +
118582 + return 0;
118583 +}
118584 --- /dev/null
118585 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
118586 @@ -0,0 +1,144 @@
118587 +/* Copyright (c) 2012 Freescale Semiconductor, Inc
118588 + * All rights reserved.
118589 + *
118590 + * Redistribution and use in source and binary forms, with or without
118591 + * modification, are permitted provided that the following conditions are met:
118592 + * * Redistributions of source code must retain the above copyright
118593 + * notice, this list of conditions and the following disclaimer.
118594 + * * Redistributions in binary form must reproduce the above copyright
118595 + * notice, this list of conditions and the following disclaimer in the
118596 + * documentation and/or other materials provided with the distribution.
118597 + * * Neither the name of Freescale Semiconductor nor the
118598 + * names of its contributors may be used to endorse or promote products
118599 + * derived from this software without specific prior written permission.
118600 + *
118601 + *
118602 + * ALTERNATIVELY, this software may be distributed under the terms of the
118603 + * GNU General Public License ("GPL") as published by the Free Software
118604 + * Foundation, either version 2 of that License or (at your option) any
118605 + * later version.
118606 + *
118607 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118608 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118609 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118610 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118611 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118612 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118613 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118614 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118615 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118616 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118617 + */
118618 +
118619 +#ifndef FM_RESS_TEST_H_
118620 +#define FM_RESS_TEST_H_
118621 +
118622 +#include <stdint.h>
118623 +#include <stdbool.h>
118624 +#include <stdio.h>
118625 +#include <assert.h>
118626 +#include <string.h>
118627 +#include <stdlib.h>
118628 +
118629 +#define _Packed
118630 +#define _PackedType __attribute__ ((packed))
118631 +#define MAX(x, y) (((x) > (y)) ? (x) : (y))
118632 +#define MIN(x, y) (((x) < (y)) ? (x) : (y))
118633 +#define KERN_ALERT ""
118634 +#define KERN_INFO ""
118635 +#define ASSERT_COND assert
118636 +#define printk printf
118637 +#define NET_IP_ALIGN 0
118638 +#define FM_FIFO_ALLOCATION_OLD_ALG
118639 +
118640 +#if defined(CONFIG_FMAN_DISABLE_OH_AND_DISTRIBUTE_RESOURCES)
118641 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
118642 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
118643 +#else
118644 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
118645 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
118646 +#endif
118647 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
118648 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
118649 +
118650 +/* information about all active ports for an FMan.
118651 + * !Some ports may be disabled by u-boot, thus will not be available */
118652 +struct fm_active_ports {
118653 + uint32_t num_oh_ports;
118654 + uint32_t num_tx_ports;
118655 + uint32_t num_rx_ports;
118656 + uint32_t num_tx25_ports;
118657 + uint32_t num_rx25_ports;
118658 + uint32_t num_tx10_ports;
118659 + uint32_t num_rx10_ports;
118660 +};
118661 +
118662 +/* FMan resources precalculated at fm probe based
118663 + * on available FMan port. */
118664 +struct fm_resource_settings {
118665 + /* buffers - fifo sizes */
118666 + uint32_t tx1g_num_buffers;
118667 + uint32_t rx1g_num_buffers;
118668 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
118669 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
118670 + uint32_t tx10g_num_buffers;
118671 + uint32_t rx10g_num_buffers;
118672 + uint32_t oh_num_buffers;
118673 + uint32_t shared_ext_buffers;
118674 +
118675 +
118676 + /* open DMAs */
118677 + uint32_t tx_1g_dmas;
118678 + uint32_t rx_1g_dmas;
118679 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
118680 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
118681 + uint32_t tx_10g_dmas;
118682 + uint32_t rx_10g_dmas;
118683 + uint32_t oh_dmas;
118684 + uint32_t shared_ext_open_dma;
118685 +
118686 + /* Tnums */
118687 + uint32_t tx_1g_tnums;
118688 + uint32_t rx_1g_tnums;
118689 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
118690 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
118691 + uint32_t tx_10g_tnums;
118692 + uint32_t rx_10g_tnums;
118693 + uint32_t oh_tnums;
118694 + uint32_t shared_ext_tnums;
118695 +};
118696 +
118697 +typedef struct {
118698 + uint8_t id;
118699 + struct fm_active_ports fm_active_ports_info;
118700 + struct fm_resource_settings fm_resource_settings_info;
118701 +} t_LnxWrpFmDev;
118702 +
118703 +typedef struct {
118704 + uint8_t id;
118705 +} t_LnxWrpFmPortDev;
118706 +
118707 +typedef _Packed struct t_FmPrsResult {
118708 + volatile uint8_t lpid; /**< Logical port id */
118709 + volatile uint8_t shimr; /**< Shim header result */
118710 + volatile uint16_t l2r; /**< Layer 2 result */
118711 + volatile uint16_t l3r; /**< Layer 3 result */
118712 + volatile uint8_t l4r; /**< Layer 4 result */
118713 + volatile uint8_t cplan; /**< Classification plan id */
118714 + volatile uint16_t nxthdr; /**< Next Header */
118715 + volatile uint16_t cksum; /**< Checksum */
118716 + volatile uint32_t lcv; /**< LCV */
118717 + volatile uint8_t shim_off[3]; /**< Shim offset */
118718 + volatile uint8_t eth_off; /**< ETH offset */
118719 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
118720 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
118721 + volatile uint8_t etype_off; /**< ETYPE offset */
118722 + volatile uint8_t pppoe_off; /**< PPP offset */
118723 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
118724 + volatile uint8_t ip_off[2]; /**< IP offset */
118725 + volatile uint8_t gre_off; /**< GRE offset */
118726 + volatile uint8_t l4_off; /**< Layer 4 offset */
118727 + volatile uint8_t nxthdr_off; /**< Parser end point */
118728 +} _PackedType t_FmPrsResult;
118729 +
118730 +#endif
118731 --- /dev/null
118732 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
118733 @@ -0,0 +1,28 @@
118734 +CC=gcc
118735 +
118736 +LNXWRP_RESS_UT=lnxwrp_resources_ut
118737 +OBJ=lnxwrp_resources
118738 +
118739 +INC_PATH=
118740 +LIB_PATH=
118741 +
118742 +INC=$(addprefix -I,$(INC_PATH))
118743 +LIB=$(addprefix -L,$(LIB_PATH))
118744 +
118745 +CFLAGS= -gdwarf-2 -g -O0 -Wall
118746 +XFLAGS= -DFMAN_RESOURCES_UNIT_TEST
118747 +
118748 +all: $(LNXWRP_RESS_UT)
118749 +
118750 +$(LNXWRP_RESS_UT):$(addsuffix .o,$(OBJ)) $(LNXWRP_RESS_UT).o
118751 + $(CC) -o $(LNXWRP_RESS_UT) $(LNXWRP_RESS_UT).o $(addsuffix .o,$(OBJ))
118752 +
118753 +%.o: %.c
118754 + @(echo " (CC) $@")
118755 + @($(CC) $(INC) $(CFLAGS) $(XFLAGS) -o $(@) -c $<)
118756 +
118757 +.PHONY: clean
118758 +
118759 +clean:
118760 + rm -f *.o
118761 + rm -f $(LNXWRP_RESS_UT)
118762 --- /dev/null
118763 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
118764 @@ -0,0 +1,60 @@
118765 +/*
118766 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118767 + *
118768 + * Redistribution and use in source and binary forms, with or without
118769 + * modification, are permitted provided that the following conditions are met:
118770 + * * Redistributions of source code must retain the above copyright
118771 + * notice, this list of conditions and the following disclaimer.
118772 + * * Redistributions in binary form must reproduce the above copyright
118773 + * notice, this list of conditions and the following disclaimer in the
118774 + * documentation and/or other materials provided with the distribution.
118775 + * * Neither the name of Freescale Semiconductor nor the
118776 + * names of its contributors may be used to endorse or promote products
118777 + * derived from this software without specific prior written permission.
118778 + *
118779 + *
118780 + * ALTERNATIVELY, this software may be distributed under the terms of the
118781 + * GNU General Public License ("GPL") as published by the Free Software
118782 + * Foundation, either version 2 of that License or (at your option) any
118783 + * later version.
118784 + *
118785 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118786 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118787 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118788 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118789 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118790 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118791 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118792 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118793 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118794 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118795 + */
118796 +
118797 +/*
118798 + @File lnxwrp_sysfs.c
118799 +
118800 + @Description FM wrapper sysfs related functions.
118801 +
118802 +*/
118803 +
118804 +#include <linux/types.h>
118805 +#include "lnxwrp_sysfs.h"
118806 +
118807 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
118808 + const struct sysfs_stats_t *sysfs_stats,
118809 + uint8_t *offset)
118810 +{
118811 + int i = 0;
118812 +
118813 + while (sysfs_stats[i].stat_name != NULL) {
118814 + if (strcmp(sysfs_stats[i].stat_name, attr_name) == 0) {
118815 + if (offset != NULL)
118816 + *offset = i;
118817 + return sysfs_stats[i].stat_counter;
118818 + }
118819 +
118820 + i++;
118821 + }
118822 + WARN(1, "FMD: Should never get here!");
118823 + return 0;
118824 +}
118825 --- /dev/null
118826 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
118827 @@ -0,0 +1,60 @@
118828 +/*
118829 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118830 + *
118831 + * Redistribution and use in source and binary forms, with or without
118832 + * modification, are permitted provided that the following conditions are met:
118833 + * * Redistributions of source code must retain the above copyright
118834 + * notice, this list of conditions and the following disclaimer.
118835 + * * Redistributions in binary form must reproduce the above copyright
118836 + * notice, this list of conditions and the following disclaimer in the
118837 + * documentation and/or other materials provided with the distribution.
118838 + * * Neither the name of Freescale Semiconductor nor the
118839 + * names of its contributors may be used to endorse or promote products
118840 + * derived from this software without specific prior written permission.
118841 + *
118842 + *
118843 + * ALTERNATIVELY, this software may be distributed under the terms of the
118844 + * GNU General Public License ("GPL") as published by the Free Software
118845 + * Foundation, either version 2 of that License or (at your option) any
118846 + * later version.
118847 + *
118848 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118849 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118850 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118851 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118852 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118853 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118854 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118855 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118856 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118857 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118858 + */
118859 +
118860 +#ifndef LNXWRP_SYSFS_H_
118861 +#define LNXWRP_SYSFS_H_
118862 +
118863 +/* Linux Headers ------------------- */
118864 +#include <linux/version.h>
118865 +
118866 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
118867 +#define MODVERSIONS
118868 +#endif
118869 +#ifdef MODVERSIONS
118870 +#include <config/modversions.h>
118871 +#endif /* MODVERSIONS */
118872 +
118873 +#include <linux/kernel.h>
118874 +#include <linux/module.h>
118875 +#include <linux/device.h>
118876 +#include <linux/sysfs.h>
118877 +
118878 +struct sysfs_stats_t {
118879 + const char *stat_name;
118880 + uint8_t stat_counter;
118881 +};
118882 +
118883 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
118884 + const struct sysfs_stats_t *sysfs_stats,
118885 + uint8_t *offset);
118886 +
118887 +#endif /* LNXWRP_SYSFS_H_ */
118888 --- /dev/null
118889 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
118890 @@ -0,0 +1,1855 @@
118891 +/*
118892 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118893 + *
118894 + * Redistribution and use in source and binary forms, with or without
118895 + * modification, are permitted provided that the following conditions are met:
118896 + * * Redistributions of source code must retain the above copyright
118897 + * notice, this list of conditions and the following disclaimer.
118898 + * * Redistributions in binary form must reproduce the above copyright
118899 + * notice, this list of conditions and the following disclaimer in the
118900 + * documentation and/or other materials provided with the distribution.
118901 + * * Neither the name of Freescale Semiconductor nor the
118902 + * names of its contributors may be used to endorse or promote products
118903 + * derived from this software without specific prior written permission.
118904 + *
118905 + *
118906 + * ALTERNATIVELY, this software may be distributed under the terms of the
118907 + * GNU General Public License ("GPL") as published by the Free Software
118908 + * Foundation, either version 2 of that License or (at your option) any
118909 + * later version.
118910 + *
118911 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118912 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118913 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118914 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118915 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118916 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118917 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118918 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118919 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118920 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118921 + */
118922 +
118923 +#include "lnxwrp_sysfs.h"
118924 +#include "lnxwrp_sysfs_fm.h"
118925 +#include "lnxwrp_fm.h"
118926 +
118927 +#include "../../sdk_fman/Peripherals/FM/inc/fm_common.h"
118928 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h"
118929 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_kg.h"
118930 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h"
118931 +
118932 +#if defined(__ERR_MODULE__)
118933 +#undef __ERR_MODULE__
118934 +#endif
118935 +
118936 +#include "../../sdk_fman/Peripherals/FM/fm.h"
118937 +#include <linux/delay.h>
118938 +
118939 +
118940 +static int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val);
118941 +
118942 +enum fm_dma_match_stats {
118943 + FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
118944 + FM_DMA_COUNTERS_BUS_ERROR,
118945 + FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
118946 + FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
118947 + FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR
118948 +};
118949 +
118950 +static const struct sysfs_stats_t fm_sysfs_stats[] = {
118951 + /* FM statistics */
118952 + {
118953 + .stat_name = "enq_total_frame",
118954 + .stat_counter = e_FM_COUNTERS_ENQ_TOTAL_FRAME,
118955 + },
118956 + {
118957 + .stat_name = "deq_total_frame",
118958 + .stat_counter = e_FM_COUNTERS_DEQ_TOTAL_FRAME,
118959 + },
118960 + {
118961 + .stat_name = "deq_0",
118962 + .stat_counter = e_FM_COUNTERS_DEQ_0,
118963 + },
118964 + {
118965 + .stat_name = "deq_1",
118966 + .stat_counter = e_FM_COUNTERS_DEQ_1,
118967 + },
118968 + {
118969 + .stat_name = "deq_2",
118970 + .stat_counter = e_FM_COUNTERS_DEQ_2,
118971 + },
118972 + {
118973 + .stat_name = "deq_3",
118974 + .stat_counter = e_FM_COUNTERS_DEQ_3,
118975 + },
118976 + {
118977 + .stat_name = "deq_from_default",
118978 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_DEFAULT,
118979 + },
118980 + {
118981 + .stat_name = "deq_from_context",
118982 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_CONTEXT,
118983 + },
118984 + {
118985 + .stat_name = "deq_from_fd",
118986 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_FD,
118987 + },
118988 + {
118989 + .stat_name = "deq_confirm",
118990 + .stat_counter = e_FM_COUNTERS_DEQ_CONFIRM,
118991 + },
118992 + /* FM:DMA statistics */
118993 + {
118994 + .stat_name = "cmq_not_empty",
118995 + .stat_counter = FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
118996 + },
118997 + {
118998 + .stat_name = "bus_error",
118999 + .stat_counter = FM_DMA_COUNTERS_BUS_ERROR,
119000 + },
119001 + {
119002 + .stat_name = "read_buf_ecc_error",
119003 + .stat_counter = FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
119004 + },
119005 + {
119006 + .stat_name = "write_buf_ecc_sys_error",
119007 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
119008 + },
119009 + {
119010 + .stat_name = "write_buf_ecc_fm_error",
119011 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR,
119012 + },
119013 + /* FM:PCD statistics */
119014 + {
119015 + .stat_name = "pcd_kg_total",
119016 + .stat_counter = e_FM_PCD_KG_COUNTERS_TOTAL,
119017 + },
119018 + {
119019 + .stat_name = "pcd_plcr_yellow",
119020 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_YELLOW,
119021 + },
119022 + {
119023 + .stat_name = "pcd_plcr_red",
119024 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RED,
119025 + },
119026 + {
119027 + .stat_name = "pcd_plcr_recolored_to_red",
119028 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED,
119029 + },
119030 + {
119031 + .stat_name = "pcd_plcr_recolored_to_yellow",
119032 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW,
119033 + },
119034 + {
119035 + .stat_name = "pcd_plcr_total",
119036 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_TOTAL,
119037 + },
119038 + {
119039 + .stat_name = "pcd_plcr_length_mismatch",
119040 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH,
119041 + },
119042 + {
119043 + .stat_name = "pcd_prs_parse_dispatch",
119044 + .stat_counter = e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH,
119045 + },
119046 + {
119047 + .stat_name = "pcd_prs_l2_parse_result_returned",
119048 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED,
119049 + },
119050 + {
119051 + .stat_name = "pcd_prs_l3_parse_result_returned",
119052 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED,
119053 + },
119054 + {
119055 + .stat_name = "pcd_prs_l4_parse_result_returned",
119056 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED,
119057 + },
119058 + {
119059 + .stat_name = "pcd_prs_shim_parse_result_returned",
119060 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED,
119061 + },
119062 + {
119063 + .stat_name = "pcd_prs_l2_parse_result_returned_with_err",
119064 + .stat_counter =
119065 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR,
119066 + },
119067 + {
119068 + .stat_name = "pcd_prs_l3_parse_result_returned_with_err",
119069 + .stat_counter =
119070 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR,
119071 + },
119072 + {
119073 + .stat_name = "pcd_prs_l4_parse_result_returned_with_err",
119074 + .stat_counter =
119075 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR,
119076 + },
119077 + {
119078 + .stat_name = "pcd_prs_shim_parse_result_returned_with_err",
119079 + .stat_counter =
119080 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR,
119081 + },
119082 + {
119083 + .stat_name = "pcd_prs_soft_prs_cycles",
119084 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES,
119085 + },
119086 + {
119087 + .stat_name = "pcd_prs_soft_prs_stall_cycles",
119088 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES,
119089 + },
119090 + {
119091 + .stat_name = "pcd_prs_hard_prs_cycle_incl_stall_cycles",
119092 + .stat_counter =
119093 + e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES,
119094 + },
119095 + {
119096 + .stat_name = "pcd_prs_muram_read_cycles",
119097 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES,
119098 + },
119099 + {
119100 + .stat_name = "pcd_prs_muram_read_stall_cycles",
119101 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES,
119102 + },
119103 + {
119104 + .stat_name = "pcd_prs_muram_write_cycles",
119105 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES,
119106 + },
119107 + {
119108 + .stat_name = "pcd_prs_muram_write_stall_cycles",
119109 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES,
119110 + },
119111 + {
119112 + .stat_name = "pcd_prs_fpm_command_stall_cycles",
119113 + .stat_counter = e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES,
119114 + },
119115 + {}
119116 +};
119117 +
119118 +
119119 +static ssize_t show_fm_risc_load(struct device *dev,
119120 + struct device_attribute *attr, char *buf)
119121 +{
119122 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119123 + unsigned long flags;
119124 + int m =0;
119125 + int err =0;
119126 + unsigned n = 0;
119127 + t_FmCtrlMon util;
119128 + uint8_t i =0 ;
119129 +
119130 + if (attr == NULL || buf == NULL || dev == NULL)
119131 + return -EINVAL;
119132 +
119133 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119134 + if (WARN_ON(p_wrp_fm_dev == NULL))
119135 + return -EINVAL;
119136 +
119137 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119138 + return -EIO;
119139 +
119140 + local_irq_save(flags);
119141 +
119142 + /* Calculate risc load */
119143 + FM_CtrlMonStart(p_wrp_fm_dev->h_Dev);
119144 + msleep(1000);
119145 + FM_CtrlMonStop(p_wrp_fm_dev->h_Dev);
119146 +
119147 + for (i = 0; i < FM_NUM_OF_CTRL; i++) {
119148 + err |= FM_CtrlMonGetCounters(p_wrp_fm_dev->h_Dev, i, &util);
119149 + m = snprintf(&buf[n],PAGE_SIZE,"\tRisc%u: util-%u%%, efficiency-%u%%\n",
119150 + i, util.percentCnt[0], util.percentCnt[1]);
119151 + n=m+n;
119152 + }
119153 +
119154 + local_irq_restore(flags);
119155 +
119156 + return n;
119157 +}
119158 +
119159 +/* Fm stats and regs dumps via sysfs */
119160 +static ssize_t show_fm_dma_stats(struct device *dev,
119161 + struct device_attribute *attr, char *buf)
119162 +{
119163 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119164 + t_FmDmaStatus dma_status;
119165 + unsigned long flags = 0;
119166 + unsigned n = 0;
119167 + uint8_t counter_value = 0, counter = 0;
119168 +
119169 + if (attr == NULL || buf == NULL || dev == NULL)
119170 + return -EINVAL;
119171 +
119172 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119173 + if (WARN_ON(p_wrp_fm_dev == NULL))
119174 + return -EINVAL;
119175 +
119176 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119177 + return -EIO;
119178 +
119179 + counter = fm_find_statistic_counter_by_name(
119180 + attr->attr.name,
119181 + fm_sysfs_stats, NULL);
119182 +
119183 + local_irq_save(flags);
119184 +
119185 + memset(&dma_status, 0, sizeof(dma_status));
119186 + FM_GetDmaStatus(p_wrp_fm_dev->h_Dev, &dma_status);
119187 +
119188 + switch (counter) {
119189 + case FM_DMA_COUNTERS_CMQ_NOT_EMPTY:
119190 + counter_value = dma_status.cmqNotEmpty;
119191 + break;
119192 + case FM_DMA_COUNTERS_BUS_ERROR:
119193 + counter_value = dma_status.busError;
119194 + break;
119195 + case FM_DMA_COUNTERS_READ_BUF_ECC_ERROR:
119196 + counter_value = dma_status.readBufEccError;
119197 + break;
119198 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR:
119199 + counter_value = dma_status.writeBufEccSysError;
119200 + break;
119201 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR:
119202 + counter_value = dma_status.writeBufEccFmError;
119203 + break;
119204 + default:
119205 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
119206 + __func__);
119207 + break;
119208 + };
119209 +
119210 + n = snprintf(buf, PAGE_SIZE, "\tFM %u counter: %c\n",
119211 + p_wrp_fm_dev->id, counter_value ? 'T' : 'F');
119212 +
119213 + local_irq_restore(flags);
119214 +
119215 + return n;
119216 +}
119217 +
119218 +static ssize_t show_fm_stats(struct device *dev,
119219 + struct device_attribute *attr, char *buf)
119220 +{
119221 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119222 + unsigned long flags = 0;
119223 + unsigned n = 0, cnt_e = 0;
119224 + uint32_t cnt_val;
119225 + int err;
119226 +
119227 + if (attr == NULL || buf == NULL || dev == NULL)
119228 + return -EINVAL;
119229 +
119230 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119231 + if (WARN_ON(p_wrp_fm_dev == NULL))
119232 + return -EINVAL;
119233 +
119234 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119235 + return -EIO;
119236 +
119237 + cnt_e = fm_find_statistic_counter_by_name(
119238 + attr->attr.name,
119239 + fm_sysfs_stats, NULL);
119240 +
119241 + err = fm_get_counter(p_wrp_fm_dev->h_Dev,
119242 + (e_FmCounters) cnt_e, &cnt_val);
119243 +
119244 + if (err)
119245 + return err;
119246 +
119247 + local_irq_save(flags);
119248 +
119249 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119250 + p_wrp_fm_dev->id, cnt_val);
119251 +
119252 + local_irq_restore(flags);
119253 +
119254 + return n;
119255 +}
119256 +
119257 +static ssize_t show_fm_muram_free_sz(struct device *dev,
119258 + struct device_attribute *attr, char *buf)
119259 +{
119260 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119261 + unsigned long flags = 0;
119262 + unsigned n = 0;
119263 + uint64_t muram_free_size = 0;
119264 +
119265 + if (attr == NULL || buf == NULL || dev == NULL)
119266 + return -EINVAL;
119267 +
119268 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119269 + if (WARN_ON(p_wrp_fm_dev == NULL))
119270 + return -EINVAL;
119271 +
119272 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119273 + return -EIO;
119274 +
119275 + muram_free_size = FM_MURAM_GetFreeMemSize(p_wrp_fm_dev->h_MuramDev);
119276 +
119277 + local_irq_save(flags);
119278 +
119279 + n = snprintf(buf, PAGE_SIZE, "\tFM %d muram_free_size: %lld\n",
119280 + p_wrp_fm_dev->id, muram_free_size);
119281 +
119282 + local_irq_restore(flags);
119283 +
119284 + return n;
119285 +}
119286 +
119287 +static ssize_t show_fm_ctrl_code_ver(struct device *dev,
119288 + struct device_attribute *attr, char *buf)
119289 +{
119290 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119291 + unsigned long flags = 0;
119292 + unsigned n = 0;
119293 + t_FmCtrlCodeRevisionInfo rv_info;
119294 +
119295 + if (attr == NULL || buf == NULL || dev == NULL)
119296 + return -EINVAL;
119297 +
119298 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119299 + if (WARN_ON(p_wrp_fm_dev == NULL))
119300 + return -EINVAL;
119301 +
119302 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119303 + return -EIO;
119304 +
119305 + FM_GetFmanCtrlCodeRevision((t_Fm *)p_wrp_fm_dev->h_Dev, &rv_info);
119306 +
119307 + local_irq_save(flags);
119308 +
119309 + FM_DMP_LN(buf, n, "- FM %d ctrl code pkg info:\n", p_wrp_fm_dev->id);
119310 + FM_DMP_LN(buf, n, "Package rev: %d\n", rv_info.packageRev);
119311 + FM_DMP_LN(buf, n, "major rev: %d\n", rv_info.majorRev);
119312 + FM_DMP_LN(buf, n, "minor rev: %d\n", rv_info.minorRev);
119313 +
119314 + local_irq_restore(flags);
119315 +
119316 + return n;
119317 +}
119318 +
119319 +static ssize_t show_fm_pcd_stats(struct device *dev,
119320 + struct device_attribute *attr, char *buf)
119321 +{
119322 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119323 + unsigned long flags = 0;
119324 + unsigned n = 0, counter = 0;
119325 +
119326 + if (attr == NULL || buf == NULL || dev == NULL)
119327 + return -EINVAL;
119328 +
119329 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119330 + if (WARN_ON(p_wrp_fm_dev == NULL))
119331 + return -EINVAL;
119332 +
119333 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev ||
119334 + !p_wrp_fm_dev->h_PcdDev)
119335 + return -EIO;
119336 +
119337 + counter = fm_find_statistic_counter_by_name(
119338 + attr->attr.name,
119339 + fm_sysfs_stats, NULL);
119340 +
119341 + local_irq_save(flags);
119342 +
119343 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119344 + p_wrp_fm_dev->id,
119345 + FM_PCD_GetCounter(p_wrp_fm_dev->h_PcdDev,
119346 + (e_FmPcdCounters) counter));
119347 +
119348 + local_irq_restore(flags);
119349 +
119350 + return n;
119351 +}
119352 +
119353 +static ssize_t show_fm_tnum_dbg(struct device *dev,
119354 + struct device_attribute *attr,
119355 + char *buf)
119356 +{
119357 + unsigned long flags;
119358 + unsigned n = 0;
119359 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119360 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119361 +#endif
119362 +
119363 + if (attr == NULL || buf == NULL || dev == NULL)
119364 + return -EINVAL;
119365 +
119366 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119367 +
119368 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119369 + if (WARN_ON(p_wrp_fm_dev == NULL))
119370 + return -EINVAL;
119371 +
119372 + local_irq_save(flags);
119373 +
119374 + if (!p_wrp_fm_dev->active)
119375 + return -EIO;
119376 + else {
119377 + int tn_s;
119378 +
119379 + if (!sscanf(attr->attr.name, "tnum_dbg_%d", &tn_s))
119380 + return -EINVAL;
119381 +
119382 + n = fm_dump_tnum_dbg(p_wrp_fm_dev->h_Dev,
119383 + tn_s, tn_s + 15, buf, n);
119384 + }
119385 + local_irq_restore(flags);
119386 +#else
119387 +
119388 + local_irq_save(flags);
119389 + n = snprintf(buf, PAGE_SIZE,
119390 + "Debug level is too low to dump registers!!!\n");
119391 + local_irq_restore(flags);
119392 +#endif /* (defined(DEBUG_ERRORS) && ... */
119393 +
119394 + return n;
119395 +}
119396 +
119397 +static ssize_t show_fm_cls_plan(struct device *dev,
119398 + struct device_attribute *attr,
119399 + char *buf)
119400 +{
119401 + unsigned long flags;
119402 + unsigned n = 0;
119403 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119404 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119405 +#endif
119406 +
119407 + if (attr == NULL || buf == NULL || dev == NULL)
119408 + return -EINVAL;
119409 +
119410 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119411 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119412 + if (WARN_ON(p_wrp_fm_dev == NULL))
119413 + return -EINVAL;
119414 +
119415 + local_irq_save(flags);
119416 +
119417 + n = snprintf(buf, PAGE_SIZE, "\n FM-KG classification plan dump.\n");
119418 +
119419 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119420 + return -EIO;
119421 + else {
119422 + int cpn;
119423 +
119424 + if (!sscanf(attr->attr.name, "cls_plan_%d", &cpn))
119425 + return -EINVAL;
119426 +
119427 + n = fm_dump_cls_plan(p_wrp_fm_dev->h_PcdDev, cpn, buf, n);
119428 + }
119429 + local_irq_restore(flags);
119430 +#else
119431 + local_irq_save(flags);
119432 + n = snprintf(buf, PAGE_SIZE,
119433 + "Debug level is too low to dump registers!!!\n");
119434 + local_irq_restore(flags);
119435 +#endif /* (defined(DEBUG_ERRORS) && ... */
119436 +
119437 + return n;
119438 +}
119439 +
119440 +static ssize_t show_fm_profiles(struct device *dev,
119441 + struct device_attribute *attr,
119442 + char *buf)
119443 +{
119444 + unsigned long flags;
119445 + unsigned n = 0;
119446 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119447 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119448 +#endif
119449 +
119450 + if (attr == NULL || buf == NULL || dev == NULL)
119451 + return -EINVAL;
119452 +
119453 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119454 +
119455 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119456 + if (WARN_ON(p_wrp_fm_dev == NULL))
119457 + return -EINVAL;
119458 +
119459 + local_irq_save(flags);
119460 +
119461 + n = snprintf(buf, PAGE_SIZE, "FM policer profile dump.\n");
119462 +
119463 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119464 + return -EIO;
119465 + else {
119466 + int pn;
119467 +
119468 + if (!sscanf(attr->attr.name, "profile_%d", &pn))
119469 + return -EINVAL;
119470 +
119471 + n = fm_profile_dump_regs(p_wrp_fm_dev->h_PcdDev, pn, buf, n);
119472 + }
119473 + local_irq_restore(flags);
119474 +#else
119475 + local_irq_save(flags);
119476 + n = snprintf(buf, PAGE_SIZE,
119477 + "Debug level is too low to dump registers!!!\n");
119478 + local_irq_restore(flags);
119479 +#endif /* (defined(DEBUG_ERRORS) && ... */
119480 +
119481 + return n;
119482 +}
119483 +
119484 +static ssize_t show_fm_schemes(struct device *dev,
119485 + struct device_attribute *attr,
119486 + char *buf)
119487 +{
119488 + unsigned long flags;
119489 + unsigned n = 0;
119490 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119491 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119492 +#endif
119493 +
119494 + if (attr == NULL || buf == NULL || dev == NULL)
119495 + return -EINVAL;
119496 +
119497 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119498 +
119499 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119500 + if (WARN_ON(p_wrp_fm_dev == NULL))
119501 + return -EINVAL;
119502 +
119503 + local_irq_save(flags);
119504 +
119505 + n = snprintf(buf, PAGE_SIZE, "FM-KG driver schemes dump.\n");
119506 +
119507 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119508 + return -EIO;
119509 + else {
119510 + int sn;
119511 +
119512 + if (!sscanf(attr->attr.name, "scheme_%d", &sn))
119513 + return -EINVAL;
119514 +
119515 + n = fm_dump_scheme(p_wrp_fm_dev->h_PcdDev, sn, buf, n);
119516 + }
119517 + local_irq_restore(flags);
119518 +#else
119519 +
119520 + local_irq_save(flags);
119521 + n = snprintf(buf, PAGE_SIZE,
119522 + "Debug level is too low to dump registers!!!\n");
119523 + local_irq_restore(flags);
119524 +#endif /* (defined(DEBUG_ERRORS) && ... */
119525 +
119526 + return n;
119527 +}
119528 +
119529 +/* FM */
119530 +static DEVICE_ATTR(enq_total_frame, S_IRUGO, show_fm_stats, NULL);
119531 +static DEVICE_ATTR(deq_total_frame, S_IRUGO, show_fm_stats, NULL);
119532 +static DEVICE_ATTR(fm_risc_load_val, S_IRUGO, show_fm_risc_load, NULL);
119533 +static DEVICE_ATTR(deq_0, S_IRUGO, show_fm_stats, NULL);
119534 +static DEVICE_ATTR(deq_1, S_IRUGO, show_fm_stats, NULL);
119535 +static DEVICE_ATTR(deq_2, S_IRUGO, show_fm_stats, NULL);
119536 +static DEVICE_ATTR(deq_3, S_IRUGO, show_fm_stats, NULL);
119537 +static DEVICE_ATTR(deq_from_default, S_IRUGO, show_fm_stats, NULL);
119538 +static DEVICE_ATTR(deq_from_context, S_IRUGO, show_fm_stats, NULL);
119539 +static DEVICE_ATTR(deq_from_fd, S_IRUGO, show_fm_stats, NULL);
119540 +static DEVICE_ATTR(deq_confirm, S_IRUGO, show_fm_stats, NULL);
119541 +/* FM:DMA */
119542 +static DEVICE_ATTR(cmq_not_empty, S_IRUGO, show_fm_dma_stats, NULL);
119543 +static DEVICE_ATTR(bus_error, S_IRUGO, show_fm_dma_stats, NULL);
119544 +static DEVICE_ATTR(read_buf_ecc_error, S_IRUGO, show_fm_dma_stats, NULL);
119545 +static DEVICE_ATTR(write_buf_ecc_sys_error, S_IRUGO, show_fm_dma_stats, NULL);
119546 +static DEVICE_ATTR(write_buf_ecc_fm_error, S_IRUGO, show_fm_dma_stats, NULL);
119547 +/* FM:PCD */
119548 +static DEVICE_ATTR(pcd_kg_total, S_IRUGO, show_fm_pcd_stats, NULL);
119549 +static DEVICE_ATTR(pcd_plcr_yellow, S_IRUGO, show_fm_pcd_stats, NULL);
119550 +static DEVICE_ATTR(pcd_plcr_red, S_IRUGO, show_fm_pcd_stats, NULL);
119551 +static DEVICE_ATTR(pcd_plcr_recolored_to_red, S_IRUGO, show_fm_pcd_stats,
119552 + NULL);
119553 +static DEVICE_ATTR(pcd_plcr_recolored_to_yellow, S_IRUGO, show_fm_pcd_stats,
119554 + NULL);
119555 +static DEVICE_ATTR(pcd_plcr_total, S_IRUGO, show_fm_pcd_stats, NULL);
119556 +static DEVICE_ATTR(pcd_plcr_length_mismatch, S_IRUGO, show_fm_pcd_stats,
119557 + NULL);
119558 +static DEVICE_ATTR(pcd_prs_parse_dispatch, S_IRUGO, show_fm_pcd_stats, NULL);
119559 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned, S_IRUGO,
119560 + show_fm_pcd_stats, NULL);
119561 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned, S_IRUGO,
119562 + show_fm_pcd_stats, NULL);
119563 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned, S_IRUGO,
119564 + show_fm_pcd_stats, NULL);
119565 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned, S_IRUGO,
119566 + show_fm_pcd_stats, NULL);
119567 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned_with_err, S_IRUGO,
119568 + show_fm_pcd_stats, NULL);
119569 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned_with_err, S_IRUGO,
119570 + show_fm_pcd_stats, NULL);
119571 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned_with_err, S_IRUGO,
119572 + show_fm_pcd_stats, NULL);
119573 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned_with_err, S_IRUGO,
119574 + show_fm_pcd_stats, NULL);
119575 +static DEVICE_ATTR(pcd_prs_soft_prs_cycles, S_IRUGO, show_fm_pcd_stats, NULL);
119576 +static DEVICE_ATTR(pcd_prs_soft_prs_stall_cycles, S_IRUGO, show_fm_pcd_stats,
119577 + NULL);
119578 +static DEVICE_ATTR(pcd_prs_hard_prs_cycle_incl_stall_cycles, S_IRUGO,
119579 + show_fm_pcd_stats, NULL);
119580 +static DEVICE_ATTR(pcd_prs_muram_read_cycles, S_IRUGO, show_fm_pcd_stats,
119581 + NULL);
119582 +static DEVICE_ATTR(pcd_prs_muram_read_stall_cycles, S_IRUGO,
119583 + show_fm_pcd_stats, NULL);
119584 +static DEVICE_ATTR(pcd_prs_muram_write_cycles, S_IRUGO, show_fm_pcd_stats,
119585 + NULL);
119586 +static DEVICE_ATTR(pcd_prs_muram_write_stall_cycles, S_IRUGO,
119587 + show_fm_pcd_stats, NULL);
119588 +static DEVICE_ATTR(pcd_prs_fpm_command_stall_cycles, S_IRUGO,
119589 + show_fm_pcd_stats, NULL);
119590 +
119591 +static DEVICE_ATTR(tnum_dbg_0, S_IRUGO, show_fm_tnum_dbg, NULL);
119592 +static DEVICE_ATTR(tnum_dbg_16, S_IRUGO, show_fm_tnum_dbg, NULL);
119593 +static DEVICE_ATTR(tnum_dbg_32, S_IRUGO, show_fm_tnum_dbg, NULL);
119594 +static DEVICE_ATTR(tnum_dbg_48, S_IRUGO, show_fm_tnum_dbg, NULL);
119595 +static DEVICE_ATTR(tnum_dbg_64, S_IRUGO, show_fm_tnum_dbg, NULL);
119596 +static DEVICE_ATTR(tnum_dbg_80, S_IRUGO, show_fm_tnum_dbg, NULL);
119597 +static DEVICE_ATTR(tnum_dbg_96, S_IRUGO, show_fm_tnum_dbg, NULL);
119598 +static DEVICE_ATTR(tnum_dbg_112, S_IRUGO, show_fm_tnum_dbg, NULL);
119599 +
119600 +static DEVICE_ATTR(cls_plan_0, S_IRUGO, show_fm_cls_plan, NULL);
119601 +static DEVICE_ATTR(cls_plan_1, S_IRUGO, show_fm_cls_plan, NULL);
119602 +static DEVICE_ATTR(cls_plan_2, S_IRUGO, show_fm_cls_plan, NULL);
119603 +static DEVICE_ATTR(cls_plan_3, S_IRUGO, show_fm_cls_plan, NULL);
119604 +static DEVICE_ATTR(cls_plan_4, S_IRUGO, show_fm_cls_plan, NULL);
119605 +static DEVICE_ATTR(cls_plan_5, S_IRUGO, show_fm_cls_plan, NULL);
119606 +static DEVICE_ATTR(cls_plan_6, S_IRUGO, show_fm_cls_plan, NULL);
119607 +static DEVICE_ATTR(cls_plan_7, S_IRUGO, show_fm_cls_plan, NULL);
119608 +static DEVICE_ATTR(cls_plan_8, S_IRUGO, show_fm_cls_plan, NULL);
119609 +static DEVICE_ATTR(cls_plan_9, S_IRUGO, show_fm_cls_plan, NULL);
119610 +static DEVICE_ATTR(cls_plan_10, S_IRUGO, show_fm_cls_plan, NULL);
119611 +static DEVICE_ATTR(cls_plan_11, S_IRUGO, show_fm_cls_plan, NULL);
119612 +static DEVICE_ATTR(cls_plan_12, S_IRUGO, show_fm_cls_plan, NULL);
119613 +static DEVICE_ATTR(cls_plan_13, S_IRUGO, show_fm_cls_plan, NULL);
119614 +static DEVICE_ATTR(cls_plan_14, S_IRUGO, show_fm_cls_plan, NULL);
119615 +static DEVICE_ATTR(cls_plan_15, S_IRUGO, show_fm_cls_plan, NULL);
119616 +static DEVICE_ATTR(cls_plan_16, S_IRUGO, show_fm_cls_plan, NULL);
119617 +static DEVICE_ATTR(cls_plan_17, S_IRUGO, show_fm_cls_plan, NULL);
119618 +static DEVICE_ATTR(cls_plan_18, S_IRUGO, show_fm_cls_plan, NULL);
119619 +static DEVICE_ATTR(cls_plan_19, S_IRUGO, show_fm_cls_plan, NULL);
119620 +static DEVICE_ATTR(cls_plan_20, S_IRUGO, show_fm_cls_plan, NULL);
119621 +static DEVICE_ATTR(cls_plan_21, S_IRUGO, show_fm_cls_plan, NULL);
119622 +static DEVICE_ATTR(cls_plan_22, S_IRUGO, show_fm_cls_plan, NULL);
119623 +static DEVICE_ATTR(cls_plan_23, S_IRUGO, show_fm_cls_plan, NULL);
119624 +static DEVICE_ATTR(cls_plan_24, S_IRUGO, show_fm_cls_plan, NULL);
119625 +static DEVICE_ATTR(cls_plan_25, S_IRUGO, show_fm_cls_plan, NULL);
119626 +static DEVICE_ATTR(cls_plan_26, S_IRUGO, show_fm_cls_plan, NULL);
119627 +static DEVICE_ATTR(cls_plan_27, S_IRUGO, show_fm_cls_plan, NULL);
119628 +static DEVICE_ATTR(cls_plan_28, S_IRUGO, show_fm_cls_plan, NULL);
119629 +static DEVICE_ATTR(cls_plan_29, S_IRUGO, show_fm_cls_plan, NULL);
119630 +static DEVICE_ATTR(cls_plan_30, S_IRUGO, show_fm_cls_plan, NULL);
119631 +static DEVICE_ATTR(cls_plan_31, S_IRUGO, show_fm_cls_plan, NULL);
119632 +
119633 +static DEVICE_ATTR(profile_0, S_IRUGO, show_fm_profiles, NULL);
119634 +static DEVICE_ATTR(profile_1, S_IRUGO, show_fm_profiles, NULL);
119635 +static DEVICE_ATTR(profile_2, S_IRUGO, show_fm_profiles, NULL);
119636 +static DEVICE_ATTR(profile_3, S_IRUGO, show_fm_profiles, NULL);
119637 +static DEVICE_ATTR(profile_4, S_IRUGO, show_fm_profiles, NULL);
119638 +static DEVICE_ATTR(profile_5, S_IRUGO, show_fm_profiles, NULL);
119639 +static DEVICE_ATTR(profile_6, S_IRUGO, show_fm_profiles, NULL);
119640 +static DEVICE_ATTR(profile_7, S_IRUGO, show_fm_profiles, NULL);
119641 +static DEVICE_ATTR(profile_8, S_IRUGO, show_fm_profiles, NULL);
119642 +static DEVICE_ATTR(profile_9, S_IRUGO, show_fm_profiles, NULL);
119643 +static DEVICE_ATTR(profile_10, S_IRUGO, show_fm_profiles, NULL);
119644 +static DEVICE_ATTR(profile_11, S_IRUGO, show_fm_profiles, NULL);
119645 +static DEVICE_ATTR(profile_12, S_IRUGO, show_fm_profiles, NULL);
119646 +static DEVICE_ATTR(profile_13, S_IRUGO, show_fm_profiles, NULL);
119647 +static DEVICE_ATTR(profile_14, S_IRUGO, show_fm_profiles, NULL);
119648 +static DEVICE_ATTR(profile_15, S_IRUGO, show_fm_profiles, NULL);
119649 +static DEVICE_ATTR(profile_16, S_IRUGO, show_fm_profiles, NULL);
119650 +static DEVICE_ATTR(profile_17, S_IRUGO, show_fm_profiles, NULL);
119651 +static DEVICE_ATTR(profile_18, S_IRUGO, show_fm_profiles, NULL);
119652 +static DEVICE_ATTR(profile_19, S_IRUGO, show_fm_profiles, NULL);
119653 +static DEVICE_ATTR(profile_20, S_IRUGO, show_fm_profiles, NULL);
119654 +static DEVICE_ATTR(profile_21, S_IRUGO, show_fm_profiles, NULL);
119655 +static DEVICE_ATTR(profile_22, S_IRUGO, show_fm_profiles, NULL);
119656 +static DEVICE_ATTR(profile_23, S_IRUGO, show_fm_profiles, NULL);
119657 +static DEVICE_ATTR(profile_24, S_IRUGO, show_fm_profiles, NULL);
119658 +static DEVICE_ATTR(profile_25, S_IRUGO, show_fm_profiles, NULL);
119659 +static DEVICE_ATTR(profile_26, S_IRUGO, show_fm_profiles, NULL);
119660 +static DEVICE_ATTR(profile_27, S_IRUGO, show_fm_profiles, NULL);
119661 +static DEVICE_ATTR(profile_28, S_IRUGO, show_fm_profiles, NULL);
119662 +static DEVICE_ATTR(profile_29, S_IRUGO, show_fm_profiles, NULL);
119663 +static DEVICE_ATTR(profile_30, S_IRUGO, show_fm_profiles, NULL);
119664 +static DEVICE_ATTR(profile_31, S_IRUGO, show_fm_profiles, NULL);
119665 +
119666 +static DEVICE_ATTR(scheme_0, S_IRUGO, show_fm_schemes, NULL);
119667 +static DEVICE_ATTR(scheme_1, S_IRUGO, show_fm_schemes, NULL);
119668 +static DEVICE_ATTR(scheme_2, S_IRUGO, show_fm_schemes, NULL);
119669 +static DEVICE_ATTR(scheme_3, S_IRUGO, show_fm_schemes, NULL);
119670 +static DEVICE_ATTR(scheme_4, S_IRUGO, show_fm_schemes, NULL);
119671 +static DEVICE_ATTR(scheme_5, S_IRUGO, show_fm_schemes, NULL);
119672 +static DEVICE_ATTR(scheme_6, S_IRUGO, show_fm_schemes, NULL);
119673 +static DEVICE_ATTR(scheme_7, S_IRUGO, show_fm_schemes, NULL);
119674 +static DEVICE_ATTR(scheme_8, S_IRUGO, show_fm_schemes, NULL);
119675 +static DEVICE_ATTR(scheme_9, S_IRUGO, show_fm_schemes, NULL);
119676 +static DEVICE_ATTR(scheme_10, S_IRUGO, show_fm_schemes, NULL);
119677 +static DEVICE_ATTR(scheme_11, S_IRUGO, show_fm_schemes, NULL);
119678 +static DEVICE_ATTR(scheme_12, S_IRUGO, show_fm_schemes, NULL);
119679 +static DEVICE_ATTR(scheme_13, S_IRUGO, show_fm_schemes, NULL);
119680 +static DEVICE_ATTR(scheme_14, S_IRUGO, show_fm_schemes, NULL);
119681 +static DEVICE_ATTR(scheme_15, S_IRUGO, show_fm_schemes, NULL);
119682 +static DEVICE_ATTR(scheme_16, S_IRUGO, show_fm_schemes, NULL);
119683 +static DEVICE_ATTR(scheme_17, S_IRUGO, show_fm_schemes, NULL);
119684 +static DEVICE_ATTR(scheme_18, S_IRUGO, show_fm_schemes, NULL);
119685 +static DEVICE_ATTR(scheme_19, S_IRUGO, show_fm_schemes, NULL);
119686 +static DEVICE_ATTR(scheme_20, S_IRUGO, show_fm_schemes, NULL);
119687 +static DEVICE_ATTR(scheme_21, S_IRUGO, show_fm_schemes, NULL);
119688 +static DEVICE_ATTR(scheme_22, S_IRUGO, show_fm_schemes, NULL);
119689 +static DEVICE_ATTR(scheme_23, S_IRUGO, show_fm_schemes, NULL);
119690 +static DEVICE_ATTR(scheme_24, S_IRUGO, show_fm_schemes, NULL);
119691 +static DEVICE_ATTR(scheme_25, S_IRUGO, show_fm_schemes, NULL);
119692 +static DEVICE_ATTR(scheme_26, S_IRUGO, show_fm_schemes, NULL);
119693 +static DEVICE_ATTR(scheme_27, S_IRUGO, show_fm_schemes, NULL);
119694 +static DEVICE_ATTR(scheme_28, S_IRUGO, show_fm_schemes, NULL);
119695 +static DEVICE_ATTR(scheme_29, S_IRUGO, show_fm_schemes, NULL);
119696 +static DEVICE_ATTR(scheme_30, S_IRUGO, show_fm_schemes, NULL);
119697 +static DEVICE_ATTR(scheme_31, S_IRUGO, show_fm_schemes, NULL);
119698 +
119699 +
119700 +static struct attribute *fm_dev_stats_attributes[] = {
119701 + &dev_attr_enq_total_frame.attr,
119702 + &dev_attr_deq_total_frame.attr,
119703 + &dev_attr_deq_0.attr,
119704 + &dev_attr_deq_1.attr,
119705 + &dev_attr_deq_2.attr,
119706 + &dev_attr_deq_3.attr,
119707 + &dev_attr_deq_from_default.attr,
119708 + &dev_attr_deq_from_context.attr,
119709 + &dev_attr_deq_from_fd.attr,
119710 + &dev_attr_deq_confirm.attr,
119711 + &dev_attr_cmq_not_empty.attr,
119712 + &dev_attr_bus_error.attr,
119713 + &dev_attr_read_buf_ecc_error.attr,
119714 + &dev_attr_write_buf_ecc_sys_error.attr,
119715 + &dev_attr_write_buf_ecc_fm_error.attr,
119716 + &dev_attr_pcd_kg_total.attr,
119717 + &dev_attr_pcd_plcr_yellow.attr,
119718 + &dev_attr_pcd_plcr_red.attr,
119719 + &dev_attr_pcd_plcr_recolored_to_red.attr,
119720 + &dev_attr_pcd_plcr_recolored_to_yellow.attr,
119721 + &dev_attr_pcd_plcr_total.attr,
119722 + &dev_attr_pcd_plcr_length_mismatch.attr,
119723 + &dev_attr_pcd_prs_parse_dispatch.attr,
119724 + &dev_attr_pcd_prs_l2_parse_result_returned.attr,
119725 + &dev_attr_pcd_prs_l3_parse_result_returned.attr,
119726 + &dev_attr_pcd_prs_l4_parse_result_returned.attr,
119727 + &dev_attr_pcd_prs_shim_parse_result_returned.attr,
119728 + &dev_attr_pcd_prs_l2_parse_result_returned_with_err.attr,
119729 + &dev_attr_pcd_prs_l3_parse_result_returned_with_err.attr,
119730 + &dev_attr_pcd_prs_l4_parse_result_returned_with_err.attr,
119731 + &dev_attr_pcd_prs_shim_parse_result_returned_with_err.attr,
119732 + &dev_attr_pcd_prs_soft_prs_cycles.attr,
119733 + &dev_attr_pcd_prs_soft_prs_stall_cycles.attr,
119734 + &dev_attr_pcd_prs_hard_prs_cycle_incl_stall_cycles.attr,
119735 + &dev_attr_pcd_prs_muram_read_cycles.attr,
119736 + &dev_attr_pcd_prs_muram_read_stall_cycles.attr,
119737 + &dev_attr_pcd_prs_muram_write_cycles.attr,
119738 + &dev_attr_pcd_prs_muram_write_stall_cycles.attr,
119739 + &dev_attr_pcd_prs_fpm_command_stall_cycles.attr,
119740 + NULL
119741 +};
119742 +
119743 +static struct attribute *fm_dev_tnums_dbg_attributes[] = {
119744 + &dev_attr_tnum_dbg_0.attr,
119745 + &dev_attr_tnum_dbg_16.attr,
119746 + &dev_attr_tnum_dbg_32.attr,
119747 + &dev_attr_tnum_dbg_48.attr,
119748 + &dev_attr_tnum_dbg_64.attr,
119749 + &dev_attr_tnum_dbg_80.attr,
119750 + &dev_attr_tnum_dbg_96.attr,
119751 + &dev_attr_tnum_dbg_112.attr,
119752 + NULL
119753 +};
119754 +
119755 +static struct attribute *fm_dev_cls_plans_attributes[] = {
119756 + &dev_attr_cls_plan_0.attr,
119757 + &dev_attr_cls_plan_1.attr,
119758 + &dev_attr_cls_plan_2.attr,
119759 + &dev_attr_cls_plan_3.attr,
119760 + &dev_attr_cls_plan_4.attr,
119761 + &dev_attr_cls_plan_5.attr,
119762 + &dev_attr_cls_plan_6.attr,
119763 + &dev_attr_cls_plan_7.attr,
119764 + &dev_attr_cls_plan_8.attr,
119765 + &dev_attr_cls_plan_9.attr,
119766 + &dev_attr_cls_plan_10.attr,
119767 + &dev_attr_cls_plan_11.attr,
119768 + &dev_attr_cls_plan_12.attr,
119769 + &dev_attr_cls_plan_13.attr,
119770 + &dev_attr_cls_plan_14.attr,
119771 + &dev_attr_cls_plan_15.attr,
119772 + &dev_attr_cls_plan_16.attr,
119773 + &dev_attr_cls_plan_17.attr,
119774 + &dev_attr_cls_plan_18.attr,
119775 + &dev_attr_cls_plan_19.attr,
119776 + &dev_attr_cls_plan_20.attr,
119777 + &dev_attr_cls_plan_21.attr,
119778 + &dev_attr_cls_plan_22.attr,
119779 + &dev_attr_cls_plan_23.attr,
119780 + &dev_attr_cls_plan_24.attr,
119781 + &dev_attr_cls_plan_25.attr,
119782 + &dev_attr_cls_plan_26.attr,
119783 + &dev_attr_cls_plan_27.attr,
119784 + &dev_attr_cls_plan_28.attr,
119785 + &dev_attr_cls_plan_29.attr,
119786 + &dev_attr_cls_plan_30.attr,
119787 + &dev_attr_cls_plan_31.attr,
119788 + NULL
119789 +};
119790 +
119791 +static struct attribute *fm_dev_profiles_attributes[] = {
119792 + &dev_attr_profile_0.attr,
119793 + &dev_attr_profile_1.attr,
119794 + &dev_attr_profile_2.attr,
119795 + &dev_attr_profile_3.attr,
119796 + &dev_attr_profile_4.attr,
119797 + &dev_attr_profile_5.attr,
119798 + &dev_attr_profile_6.attr,
119799 + &dev_attr_profile_7.attr,
119800 + &dev_attr_profile_8.attr,
119801 + &dev_attr_profile_9.attr,
119802 + &dev_attr_profile_10.attr,
119803 + &dev_attr_profile_11.attr,
119804 + &dev_attr_profile_12.attr,
119805 + &dev_attr_profile_13.attr,
119806 + &dev_attr_profile_14.attr,
119807 + &dev_attr_profile_15.attr,
119808 + &dev_attr_profile_16.attr,
119809 + &dev_attr_profile_17.attr,
119810 + &dev_attr_profile_18.attr,
119811 + &dev_attr_profile_19.attr,
119812 + &dev_attr_profile_20.attr,
119813 + &dev_attr_profile_21.attr,
119814 + &dev_attr_profile_22.attr,
119815 + &dev_attr_profile_23.attr,
119816 + &dev_attr_profile_24.attr,
119817 + &dev_attr_profile_25.attr,
119818 + &dev_attr_profile_26.attr,
119819 + &dev_attr_profile_27.attr,
119820 + &dev_attr_profile_28.attr,
119821 + &dev_attr_profile_29.attr,
119822 + &dev_attr_profile_30.attr,
119823 + &dev_attr_profile_31.attr,
119824 + NULL
119825 +};
119826 +
119827 +static struct attribute *fm_dev_schemes_attributes[] = {
119828 + &dev_attr_scheme_0.attr,
119829 + &dev_attr_scheme_1.attr,
119830 + &dev_attr_scheme_2.attr,
119831 + &dev_attr_scheme_3.attr,
119832 + &dev_attr_scheme_4.attr,
119833 + &dev_attr_scheme_5.attr,
119834 + &dev_attr_scheme_6.attr,
119835 + &dev_attr_scheme_7.attr,
119836 + &dev_attr_scheme_8.attr,
119837 + &dev_attr_scheme_9.attr,
119838 + &dev_attr_scheme_10.attr,
119839 + &dev_attr_scheme_11.attr,
119840 + &dev_attr_scheme_12.attr,
119841 + &dev_attr_scheme_13.attr,
119842 + &dev_attr_scheme_14.attr,
119843 + &dev_attr_scheme_15.attr,
119844 + &dev_attr_scheme_16.attr,
119845 + &dev_attr_scheme_17.attr,
119846 + &dev_attr_scheme_18.attr,
119847 + &dev_attr_scheme_19.attr,
119848 + &dev_attr_scheme_20.attr,
119849 + &dev_attr_scheme_21.attr,
119850 + &dev_attr_scheme_22.attr,
119851 + &dev_attr_scheme_23.attr,
119852 + &dev_attr_scheme_24.attr,
119853 + &dev_attr_scheme_25.attr,
119854 + &dev_attr_scheme_26.attr,
119855 + &dev_attr_scheme_27.attr,
119856 + &dev_attr_scheme_28.attr,
119857 + &dev_attr_scheme_29.attr,
119858 + &dev_attr_scheme_30.attr,
119859 + &dev_attr_scheme_31.attr,
119860 + NULL
119861 +};
119862 +
119863 +static const struct attribute_group fm_dev_stats_attr_grp = {
119864 + .name = "statistics",
119865 + .attrs = fm_dev_stats_attributes
119866 +};
119867 +
119868 +static const struct attribute_group fm_dev_tnums_dbg_attr_grp = {
119869 + .name = "tnums_dbg",
119870 + .attrs = fm_dev_tnums_dbg_attributes
119871 +};
119872 +
119873 +static const struct attribute_group fm_dev_cls_plans_attr_grp = {
119874 + .name = "cls_plans",
119875 + .attrs = fm_dev_cls_plans_attributes
119876 +};
119877 +
119878 +static const struct attribute_group fm_dev_schemes_attr_grp = {
119879 + .name = "schemes",
119880 + .attrs = fm_dev_schemes_attributes
119881 +};
119882 +
119883 +static const struct attribute_group fm_dev_profiles_attr_grp = {
119884 + .name = "profiles",
119885 + .attrs = fm_dev_profiles_attributes
119886 +};
119887 +
119888 +static ssize_t show_fm_regs(struct device *dev,
119889 + struct device_attribute *attr,
119890 + char *buf)
119891 +{
119892 + unsigned long flags;
119893 + unsigned n = 0;
119894 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119895 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119896 +#endif
119897 + if (attr == NULL || buf == NULL || dev == NULL)
119898 + return -EINVAL;
119899 +
119900 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119901 +
119902 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119903 + if (WARN_ON(p_wrp_fm_dev == NULL))
119904 + return -EINVAL;
119905 +
119906 + local_irq_save(flags);
119907 +
119908 + n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n");
119909 +
119910 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119911 + return -EIO;
119912 + else
119913 + n = fm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
119914 +
119915 + local_irq_restore(flags);
119916 +#else
119917 +
119918 + local_irq_save(flags);
119919 + n = snprintf(buf, PAGE_SIZE,
119920 + "Debug level is too low to dump registers!!!\n");
119921 + local_irq_restore(flags);
119922 +#endif /* (defined(DEBUG_ERRORS) && ... */
119923 +
119924 + return n;
119925 +}
119926 +
119927 +static ssize_t show_fm_kg_pe_regs(struct device *dev,
119928 + struct device_attribute *attr,
119929 + char *buf)
119930 +{
119931 + unsigned long flags;
119932 + unsigned n = 0;
119933 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119934 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119935 +#endif
119936 +
119937 + if (attr == NULL || buf == NULL || dev == NULL)
119938 + return -EINVAL;
119939 +
119940 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119941 +
119942 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119943 + if (WARN_ON(p_wrp_fm_dev == NULL))
119944 + return -EINVAL;
119945 +
119946 + local_irq_save(flags);
119947 +
119948 + n = snprintf(buf, PAGE_SIZE,
119949 + "\n FM-KG Port Partition Config registers dump.\n");
119950 +
119951 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119952 + return -EIO;
119953 + else
119954 + n = fm_kg_pe_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
119955 +
119956 + local_irq_restore(flags);
119957 +#else
119958 +
119959 + local_irq_save(flags);
119960 + n = snprintf(buf, PAGE_SIZE,
119961 + "Debug level is too low to dump registers!!!\n");
119962 + local_irq_restore(flags);
119963 +#endif /* (defined(DEBUG_ERRORS) && ... */
119964 +
119965 + return n;
119966 +}
119967 +
119968 +static ssize_t show_fm_kg_regs(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 + n = snprintf(buf, PAGE_SIZE, "FM-KG registers dump.\n");
119990 +
119991 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119992 + return -EIO;
119993 + else
119994 + n = fm_kg_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
119995 +
119996 + local_irq_restore(flags);
119997 +#else
119998 +
119999 + local_irq_save(flags);
120000 + n = snprintf(buf, PAGE_SIZE,
120001 + "Debug level is too low to dump registers!!!\n");
120002 + local_irq_restore(flags);
120003 +#endif /* (defined(DEBUG_ERRORS) && ... */
120004 +
120005 + return n;
120006 +}
120007 +
120008 +
120009 +static ssize_t show_fm_fpm_regs(struct device *dev,
120010 + struct device_attribute *attr,
120011 + char *buf)
120012 +{
120013 + unsigned long flags;
120014 + unsigned n = 0;
120015 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120016 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120017 +#endif
120018 +
120019 + if (attr == NULL || buf == NULL || dev == NULL)
120020 + return -EINVAL;
120021 +
120022 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120023 +
120024 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120025 + if (WARN_ON(p_wrp_fm_dev == NULL))
120026 + return -EINVAL;
120027 +
120028 + local_irq_save(flags);
120029 +
120030 + n = snprintf(buf, PAGE_SIZE, "FM-FPM registers dump.\n");
120031 +
120032 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120033 + return -EIO;
120034 + else
120035 + n = fm_fpm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
120036 +
120037 + local_irq_restore(flags);
120038 +#else
120039 +
120040 + local_irq_save(flags);
120041 + n = snprintf(buf, PAGE_SIZE,
120042 + "Debug level is too low to dump registers!!!\n");
120043 + local_irq_restore(flags);
120044 +#endif /* (defined(DEBUG_ERRORS) && ... */
120045 +
120046 + return n;
120047 +}
120048 +
120049 +static ssize_t show_prs_regs(struct device *dev,
120050 + struct device_attribute *attr, char *buf)
120051 +{
120052 + unsigned long flags;
120053 + unsigned n = 0;
120054 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120055 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120056 +#endif
120057 +
120058 + if (attr == NULL || buf == NULL || dev == NULL)
120059 + return -EINVAL;
120060 +
120061 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120062 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120063 + if (WARN_ON(p_wrp_fm_dev == NULL))
120064 + return -EINVAL;
120065 +
120066 + local_irq_save(flags);
120067 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
120068 +
120069 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120070 + return -EIO;
120071 + else
120072 + n = fm_prs_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120073 +
120074 + local_irq_restore(flags);
120075 +#else
120076 +
120077 + local_irq_save(flags);
120078 + n = snprintf(buf, PAGE_SIZE,
120079 + "Debug level is too low to dump registers!!!\n");
120080 + local_irq_restore(flags);
120081 +
120082 +#endif /* (defined(DEBUG_ERRORS) && ... */
120083 +
120084 + return n;
120085 +}
120086 +
120087 +static ssize_t show_plcr_regs(struct device *dev,
120088 + struct device_attribute *attr,
120089 + char *buf)
120090 +{
120091 + unsigned long flags;
120092 + unsigned n = 0;
120093 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120094 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120095 +#endif
120096 +
120097 + if (attr == NULL || buf == NULL || dev == NULL)
120098 + return -EINVAL;
120099 +
120100 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120101 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120102 + if (WARN_ON(p_wrp_fm_dev == NULL))
120103 + return -EINVAL;
120104 +
120105 + local_irq_save(flags);
120106 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
120107 +
120108 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120109 + return -EIO;
120110 + else
120111 + n = fm_plcr_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120112 +
120113 + local_irq_restore(flags);
120114 +#else
120115 +
120116 + local_irq_save(flags);
120117 + n = snprintf(buf, PAGE_SIZE,
120118 + "Debug level is too low to dump registers!!!\n");
120119 + local_irq_restore(flags);
120120 +
120121 +#endif /* (defined(DEBUG_ERRORS) && ... */
120122 +
120123 + return n;
120124 +}
120125 +
120126 +static DEVICE_ATTR(fm_regs, S_IRUGO, show_fm_regs, NULL);
120127 +static DEVICE_ATTR(fm_fpm_regs, S_IRUGO, show_fm_fpm_regs, NULL);
120128 +static DEVICE_ATTR(fm_kg_regs, S_IRUGO, show_fm_kg_regs, NULL);
120129 +static DEVICE_ATTR(fm_kg_pe_regs, S_IRUGO, show_fm_kg_pe_regs, NULL);
120130 +static DEVICE_ATTR(fm_plcr_regs, S_IRUGO, show_plcr_regs, NULL);
120131 +static DEVICE_ATTR(fm_prs_regs, S_IRUGO, show_prs_regs, NULL);
120132 +static DEVICE_ATTR(fm_muram_free_size, S_IRUGO, show_fm_muram_free_sz, NULL);
120133 +static DEVICE_ATTR(fm_ctrl_code_ver, S_IRUGO, show_fm_ctrl_code_ver, NULL);
120134 +
120135 +int fm_sysfs_create(struct device *dev)
120136 +{
120137 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120138 +
120139 + if (dev == NULL)
120140 + return -EIO;
120141 +
120142 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120143 +
120144 + /* store to remove them when module is disabled */
120145 + p_wrp_fm_dev->dev_attr_regs = &dev_attr_fm_regs;
120146 + p_wrp_fm_dev->dev_attr_risc_load = &dev_attr_fm_risc_load_val;
120147 + p_wrp_fm_dev->dev_fm_fpm_attr_regs = &dev_attr_fm_fpm_regs;
120148 + p_wrp_fm_dev->dev_fm_kg_attr_regs = &dev_attr_fm_kg_regs;
120149 + p_wrp_fm_dev->dev_fm_kg_pe_attr_regs = &dev_attr_fm_kg_pe_regs;
120150 + p_wrp_fm_dev->dev_plcr_attr_regs = &dev_attr_fm_plcr_regs;
120151 + p_wrp_fm_dev->dev_prs_attr_regs = &dev_attr_fm_prs_regs;
120152 + p_wrp_fm_dev->dev_attr_muram_free_size = &dev_attr_fm_muram_free_size;
120153 + p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver = &dev_attr_fm_ctrl_code_ver;
120154 +
120155 + /* Create sysfs statistics group for FM module */
120156 + if (sysfs_create_group(&dev->kobj, &fm_dev_stats_attr_grp) != 0)
120157 + return -EIO;
120158 +
120159 + if (sysfs_create_group(&dev->kobj, &fm_dev_schemes_attr_grp) != 0)
120160 + return -EIO;
120161 +
120162 + if (sysfs_create_group(&dev->kobj, &fm_dev_profiles_attr_grp) != 0)
120163 + return -EIO;
120164 +
120165 + if (sysfs_create_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp) != 0)
120166 + return -EIO;
120167 +
120168 + if (sysfs_create_group(&dev->kobj, &fm_dev_cls_plans_attr_grp) != 0)
120169 + return -EIO;
120170 +
120171 + /* Registers dump entry - in future will be moved to debugfs */
120172 + if (device_create_file(dev, &dev_attr_fm_regs) != 0)
120173 + return -EIO;
120174 +
120175 + if (device_create_file(dev, &dev_attr_fm_risc_load_val) != 0)
120176 + return -EIO;
120177 +
120178 + if (device_create_file(dev, &dev_attr_fm_fpm_regs) != 0)
120179 + return -EIO;
120180 +
120181 + if (device_create_file(dev, &dev_attr_fm_kg_regs) != 0)
120182 + return -EIO;
120183 +
120184 + if (device_create_file(dev, &dev_attr_fm_kg_pe_regs) != 0)
120185 + return -EIO;
120186 +
120187 + if (device_create_file(dev, &dev_attr_fm_plcr_regs) != 0)
120188 + return -EIO;
120189 +
120190 + if (device_create_file(dev, &dev_attr_fm_prs_regs) != 0)
120191 + return -EIO;
120192 +
120193 + /* muram free size */
120194 + if (device_create_file(dev, &dev_attr_fm_muram_free_size) != 0)
120195 + return -EIO;
120196 +
120197 + /* fm ctrl code version */
120198 + if (device_create_file(dev, &dev_attr_fm_ctrl_code_ver) != 0)
120199 + return -EIO;
120200 +
120201 + return 0;
120202 +}
120203 +
120204 +void fm_sysfs_destroy(struct device *dev)
120205 +{
120206 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120207 +
120208 + if (WARN_ON(dev == NULL))
120209 + return;
120210 +
120211 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120212 + if (WARN_ON(p_wrp_fm_dev == NULL))
120213 + return;
120214 +
120215 + sysfs_remove_group(&dev->kobj, &fm_dev_stats_attr_grp);
120216 + sysfs_remove_group(&dev->kobj, &fm_dev_schemes_attr_grp);
120217 + sysfs_remove_group(&dev->kobj, &fm_dev_profiles_attr_grp);
120218 + sysfs_remove_group(&dev->kobj, &fm_dev_cls_plans_attr_grp);
120219 + sysfs_remove_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp);
120220 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_regs);
120221 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_fpm_attr_regs);
120222 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_attr_regs);
120223 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_pe_attr_regs);
120224 + device_remove_file(dev, p_wrp_fm_dev->dev_plcr_attr_regs);
120225 + device_remove_file(dev, p_wrp_fm_dev->dev_prs_attr_regs);
120226 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_muram_free_size);
120227 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver);
120228 +}
120229 +
120230 +int fm_dump_regs(void *h_fm, char *buf, int nn)
120231 +{
120232 + t_Fm *p_Fm = (t_Fm *)h_fm;
120233 + uint8_t i = 0;
120234 + int n = nn;
120235 +
120236 + FM_DMP_SUBTITLE(buf, n, "\n");
120237 +
120238 + FM_DMP_TITLE(buf, n, p_Fm->p_FmDmaRegs, "FM-DMA Regs");
120239 +
120240 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsr);
120241 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmemsr);
120242 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmmr);
120243 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtr);
120244 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmhy);
120245 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsetr);
120246 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtah);
120247 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtal);
120248 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtcid);
120249 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmra);
120250 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmrd);
120251 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmwcr);
120252 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmebcr);
120253 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmdcr);
120254 +
120255 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr, "fmdmplr");
120256 +
120257 + for (i = 0; i < FM_MAX_NUM_OF_HW_PORT_IDS / 2 ; ++i)
120258 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[i]);
120259 +
120260 + FM_DMP_TITLE(buf, n, p_Fm->p_FmBmiRegs, "FM-BMI COMMON Regs");
120261 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_init);
120262 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg1);
120263 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg2);
120264 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ievr);
120265 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ier);
120266 +
120267 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb, "fmbm_arb");
120268 + for (i = 0; i < 8 ; ++i)
120269 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb[i]);
120270 +
120271 + FM_DMP_TITLE(buf, n, p_Fm->p_FmQmiRegs, "FM-QMI COMMON Regs");
120272 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gc);
120273 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eie);
120274 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eien);
120275 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eif);
120276 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ie);
120277 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ien);
120278 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_if);
120279 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gs);
120280 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_etfc);
120281 +
120282 + return n;
120283 +}
120284 +
120285 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn)
120286 +{
120287 + t_Fm *p_Fm = (t_Fm *)h_fm;
120288 + uint8_t i, j = 0;
120289 + int n = nn;
120290 +
120291 + FM_DMP_TITLE(buf, n, NULL, "Tnums and Tnum dbg regs %d - %d",
120292 + tn_s, tn_e);
120293 +
120294 + iowrite32be(tn_s << 24, &p_Fm->p_FmFpmRegs->fmfp_dra);
120295 +
120296 + mb();
120297 +
120298 + for (j = tn_s; j <= tn_e; j++) {
120299 + FM_DMP_LN(buf, n, "> fmfp_ts[%d]\n", j);
120300 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ts[j]);
120301 + FM_DMP_V32(buf, n, p_Fm->p_FmFpmRegs, fmfp_dra);
120302 + FM_DMP_LN(buf, n, "> fmfp_drd[0-3]\n");
120303 +
120304 + for (i = 0; i < 4 ; ++i)
120305 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_drd[i]);
120306 +
120307 + FM_DMP_LN(buf, n, "\n");
120308 +
120309 + }
120310 +
120311 + return n;
120312 +}
120313 +
120314 +int fm_dump_cls_plan(void *h_fm_pcd, int cpn, char *buf, int nn)
120315 +{
120316 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120317 + int i = 0;
120318 + uint32_t tmp;
120319 + unsigned long i_flg;
120320 + int n = nn;
120321 + u_FmPcdKgIndirectAccessRegs *idac;
120322 + spinlock_t *p_lk;
120323 +
120324 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
120325 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120326 +
120327 + spin_lock_irqsave(p_lk, i_flg);
120328 +
120329 + /* Read ClsPlan Block Action Regs */
120330 + tmp = (uint32_t)(FM_KG_KGAR_GO |
120331 + FM_KG_KGAR_READ |
120332 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
120333 + DUMMY_PORT_ID |
120334 + ((uint32_t)cpn << FM_PCD_KG_KGAR_NUM_SHIFT) |
120335 + FM_PCD_KG_KGAR_WSEL_MASK);
120336 +
120337 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp)) {
120338 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
120339 + spin_unlock_irqrestore(p_lk, i_flg);
120340 + return nn;
120341 + }
120342 + FM_DMP_TITLE(buf, n, &idac->clsPlanRegs,
120343 + "ClsPlan %d Indirect Access Regs", cpn);
120344 +
120345 + for (i = 0; i < 8; i++)
120346 + FM_DMP_MEM_32(buf, n, &idac->clsPlanRegs.kgcpe[i]);
120347 +
120348 + spin_unlock_irqrestore(p_lk, i_flg);
120349 +
120350 + return n;
120351 +}
120352 +
120353 +int fm_profile_dump_regs(void *h_fm_pcd, int ppn, char *buf, int nn)
120354 +{
120355 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120356 + t_FmPcdPlcrProfileRegs *p_prof_regs;
120357 + t_FmPcdPlcrRegs *p_plcr_regs;
120358 + t_FmPcdPlcr *p_plcr;
120359 + uint32_t tmp;
120360 + unsigned long i_flg;
120361 + int n = nn;
120362 + int toc = 10;
120363 + spinlock_t *p_lk;
120364 +
120365 + p_plcr = p_pcd->p_FmPcdPlcr;
120366 + p_prof_regs = &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs;
120367 + p_plcr_regs = p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
120368 +
120369 + p_lk = (spinlock_t *)((t_FmPcdPlcr *)p_plcr)->h_HwSpinlock;
120370 +
120371 + FM_DMP_SUBTITLE(buf, n, "\n");
120372 + FM_DMP_TITLE(buf, n, p_plcr_regs, "FM-PCD policer-profile regs");
120373 +
120374 + tmp = (uint32_t)(FM_PCD_PLCR_PAR_GO |
120375 + FM_PCD_PLCR_PAR_R |
120376 + ((uint32_t)ppn << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
120377 + FM_PCD_PLCR_PAR_PWSEL_MASK);
120378 +
120379 + spin_lock_irqsave(p_lk, i_flg);
120380 +
120381 + iowrite32be(tmp, &p_plcr_regs->fmpl_par);
120382 +
120383 + mb();
120384 +
120385 + /* wait for the porfile regs to be present */
120386 + do {
120387 + --toc;
120388 + udelay(10);
120389 + if (!toc) {
120390 + /* looks like PLCR_PAR_GO refuses to clear */
120391 + spin_unlock_irqrestore(p_lk, i_flg);
120392 + FM_DMP_LN(buf, n, "Profile regs not accessible -");
120393 + FM_DMP_LN(buf, n, " check profile init process\n");
120394 + return n;
120395 + }
120396 + } while ((ioread32be(&p_plcr_regs->fmpl_par) & FM_PCD_PLCR_PAR_GO));
120397 +
120398 + FM_DMP_TITLE(buf, n, p_prof_regs, "Profile %d regs", ppn);
120399 +
120400 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pemode);
120401 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegnia);
120402 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peynia);
120403 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pernia);
120404 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecir);
120405 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecbs);
120406 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepepir_eir);
120407 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepbs_ebs);
120408 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pelts);
120409 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pects);
120410 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepts_ets);
120411 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegpc);
120412 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peypc);
120413 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perpc);
120414 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perypc);
120415 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perrpc);
120416 +
120417 + spin_unlock_irqrestore(p_lk, i_flg);
120418 +
120419 + return n;
120420 +}
120421 +
120422 +int fm_dump_scheme(void *h_fm_pcd, int scnum, char *buf, int nn)
120423 +{
120424 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120425 + uint32_t tmp_ar;
120426 + unsigned long i_flg;
120427 + int i, n = nn;
120428 + spinlock_t *p_lk;
120429 + u_FmPcdKgIndirectAccessRegs *idac;
120430 +
120431 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120432 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
120433 +
120434 + spin_lock_irqsave(p_lk, i_flg);
120435 +
120436 + tmp_ar = FmPcdKgBuildReadSchemeActionReg((uint8_t)scnum);
120437 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp_ar)) {
120438 + FM_DMP_LN(buf, nn,
120439 + "Keygen scheme access violation or no such scheme");
120440 + spin_unlock_irqrestore(p_lk, i_flg);
120441 + return nn;
120442 + }
120443 +
120444 + FM_DMP_TITLE(buf, n, &idac->schemeRegs,
120445 + "Scheme %d Indirect Access Regs", scnum);
120446 +
120447 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mode);
120448 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekfc);
120449 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekdv);
120450 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmch);
120451 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmcl);
120452 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_fqb);
120453 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_hc);
120454 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ppc);
120455 +
120456 + FM_DMP_TITLE(buf, n, &idac->schemeRegs.kgse_gec, "kgse_gec");
120457 +
120458 + for (i = 0; i < FM_KG_NUM_OF_GENERIC_REGS; i++)
120459 + FM_DMP_MEM_32(buf, n, &idac->schemeRegs.kgse_gec[i]);
120460 +
120461 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_spc);
120462 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv0);
120463 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv1);
120464 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ccbs);
120465 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mv);
120466 +
120467 + FM_DMP_SUBTITLE(buf, n, "\n");
120468 +
120469 + spin_unlock_irqrestore(p_lk, i_flg);
120470 +
120471 + return n;
120472 +}
120473 +
120474 +int fm_kg_pe_dump_regs(void *h_fm_pcd, char *buf, int nn)
120475 +{
120476 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120477 + int i = 0;
120478 + uint8_t prt_id = 0;
120479 + uint32_t tmp_ar;
120480 + unsigned long i_flg;
120481 + int n = nn;
120482 + u_FmPcdKgIndirectAccessRegs *idac;
120483 + t_FmPcdKg *p_kg;
120484 + spinlock_t *p_lk;
120485 +
120486 + p_kg = p_pcd->p_FmPcdKg;
120487 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120488 + p_lk = (spinlock_t *)p_kg->h_HwSpinlock;
120489 +
120490 + spin_lock_irqsave(p_lk, i_flg);
120491 +
120492 + FM_DMP_SUBTITLE(buf, n, "\n");
120493 +
120494 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) {
120495 + SW_PORT_INDX_TO_HW_PORT_ID(prt_id, i);
120496 +
120497 + tmp_ar = FmPcdKgBuildReadPortSchemeBindActionReg(prt_id);
120498 +
120499 + if (fman_kg_write_ar_wait(p_kg->p_FmPcdKgRegs, tmp_ar)) {
120500 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
120501 + spin_unlock_irqrestore(p_lk, i_flg);
120502 + return nn;
120503 + }
120504 + FM_DMP_TITLE(buf, n, &idac->portRegs, "Port %d regs", prt_id);
120505 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_sp);
120506 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_cpp);
120507 + }
120508 +
120509 + FM_DMP_SUBTITLE(buf, n, "\n");
120510 +
120511 + spin_unlock_irqrestore(p_lk, i_flg);
120512 +
120513 + return n;
120514 +}
120515 +
120516 +int fm_kg_dump_regs(void *h_fm_pcd, char *buf, int nn)
120517 +{
120518 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120519 + int n = nn;
120520 +
120521 + FM_DMP_SUBTITLE(buf, n, "\n");
120522 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs,
120523 + "FmPcdKgRegs Regs");
120524 +
120525 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gcr);
120526 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eer);
120527 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eeer);
120528 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seer);
120529 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seeer);
120530 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gsr);
120531 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_tpc);
120532 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_serc);
120533 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_fdor);
120534 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv0r);
120535 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv1r);
120536 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_feer);
120537 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_ar);
120538 +
120539 + FM_DMP_SUBTITLE(buf, n, "\n");
120540 +
120541 + return n;
120542 +}
120543 +
120544 +
120545 +int fm_fpm_dump_regs(void *h_fm, char *buf, int nn)
120546 +{
120547 + t_Fm *p_fm = (t_Fm *)h_fm;
120548 + uint8_t i;
120549 + int n = nn;
120550 +
120551 + FM_DMP_SUBTITLE(buf, n, "\n");
120552 +
120553 + FM_DMP_TITLE(buf, n, p_fm->p_FmFpmRegs, "FM-FPM Regs");
120554 +
120555 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tnc);
120556 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_prc);
120557 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_brkc);
120558 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_mxd);
120559 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist1);
120560 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist2);
120561 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_epi);
120562 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rie);
120563 +
120564 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev, "fmfp_fcev");
120565 + for (i = 0; i < 4; ++i)
120566 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev[i]);
120567 +
120568 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee, "fmfp_cee");
120569 + for (i = 0; i < 4; ++i)
120570 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee[i]);
120571 +
120572 + FM_DMP_SUBTITLE(buf, n, "\n");
120573 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc1);
120574 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc2);
120575 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsp);
120576 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsf);
120577 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rcr);
120578 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_extc);
120579 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext1);
120580 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext2);
120581 +
120582 + FM_DMP_SUBTITLE(buf, n, "\n");
120583 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_1);
120584 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_2);
120585 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rstc);
120586 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_cld);
120587 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_npi);
120588 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ee);
120589 +
120590 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev, "fmfp_cev");
120591 + for (i = 0; i < 4; ++i)
120592 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev[i]);
120593 +
120594 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps, "fmfp_ps");
120595 + for (i = 0; i < 64; ++i)
120596 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps[i]);
120597 +
120598 + return n;
120599 +}
120600 +
120601 +int fm_prs_dump_regs(void *h_fm_pcd, char *buf, int nn)
120602 +{
120603 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120604 + int n = nn;
120605 +
120606 + FM_DMP_SUBTITLE(buf, n, "\n");
120607 +
120608 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs,
120609 + "FM-PCD parser regs");
120610 +
120611 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpclim);
120612 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpimac);
120613 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, pmeec);
120614 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pevr);
120615 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pever);
120616 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perr);
120617 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perer);
120618 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_ppsc);
120619 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pds);
120620 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rrs);
120621 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rrs);
120622 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rrs);
120623 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srrs);
120624 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rres);
120625 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rres);
120626 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rres);
120627 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srres);
120628 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spcs);
120629 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spscs);
120630 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_hxscs);
120631 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrcs);
120632 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwcs);
120633 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrscs);
120634 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwscs);
120635 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_fcscs);
120636 +
120637 + return n;
120638 +}
120639 +
120640 +int fm_plcr_dump_regs(void *h_fm_pcd, char *buf, int nn)
120641 +{
120642 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120643 + int i = 0;
120644 + int n = nn;
120645 +
120646 + FM_DMP_SUBTITLE(buf, n, "\n");
120647 +
120648 + FM_DMP_TITLE(buf, n,
120649 + p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,
120650 + "FM policer regs");
120651 +
120652 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gcr);
120653 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gsr);
120654 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_evr);
120655 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ier);
120656 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ifr);
120657 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eevr);
120658 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eier);
120659 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eifr);
120660 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rpcnt);
120661 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ypcnt);
120662 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rrpcnt);
120663 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rypcnt);
120664 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_tpcnt);
120665 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_flmcnt);
120666 +
120667 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_serc);
120668 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_upcr);
120669 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_dpmr);
120670 +
120671 + FM_DMP_TITLE(buf, n,
120672 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr,
120673 + "fmpl_pmr");
120674 +
120675 + for (i = 0; i < 63; ++i)
120676 + FM_DMP_MEM_32(buf, n,
120677 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i]);
120678 +
120679 + return n;
120680 +}
120681 +
120682 +int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val)
120683 +{
120684 + t_Fm *p_fm = (t_Fm *)h_fm;
120685 +
120686 + /* When applicable (when there is an "enable counters" bit),
120687 + check that counters are enabled */
120688 +
120689 + switch (cnt_e) {
120690 + case (e_FM_COUNTERS_DEQ_1):
120691 + case (e_FM_COUNTERS_DEQ_2):
120692 + case (e_FM_COUNTERS_DEQ_3):
120693 + if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6)
120694 + return -EINVAL; /* counter not available */
120695 +
120696 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
120697 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
120698 + case (e_FM_COUNTERS_DEQ_0):
120699 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
120700 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
120701 + case (e_FM_COUNTERS_DEQ_FROM_FD):
120702 + case (e_FM_COUNTERS_DEQ_CONFIRM):
120703 + if (!(ioread32be(&p_fm->p_FmQmiRegs->fmqm_gc) &
120704 + QMI_CFG_EN_COUNTERS))
120705 + return -EINVAL; /* Requested counter not available */
120706 + break;
120707 + default:
120708 + break;
120709 + }
120710 +
120711 + switch (cnt_e) {
120712 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
120713 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_etfc);
120714 + return 0;
120715 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
120716 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dtfc);
120717 + return 0;
120718 + case (e_FM_COUNTERS_DEQ_0):
120719 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc0);
120720 + return 0;
120721 + case (e_FM_COUNTERS_DEQ_1):
120722 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc1);
120723 + return 0;
120724 + case (e_FM_COUNTERS_DEQ_2):
120725 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc2);
120726 + return 0;
120727 + case (e_FM_COUNTERS_DEQ_3):
120728 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc3);
120729 + return 0;
120730 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
120731 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfdc);
120732 + return 0;
120733 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
120734 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfcc);
120735 + return 0;
120736 + case (e_FM_COUNTERS_DEQ_FROM_FD):
120737 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dffc);
120738 + return 0;
120739 + case (e_FM_COUNTERS_DEQ_CONFIRM):
120740 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dcc);
120741 + return 0;
120742 + }
120743 + /* should never get here */
120744 + return -EINVAL; /* counter not available */
120745 +}
120746 --- /dev/null
120747 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
120748 @@ -0,0 +1,136 @@
120749 +/*
120750 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120751 + *
120752 + * Redistribution and use in source and binary forms, with or without
120753 + * modification, are permitted provided that the following conditions are met:
120754 + * * Redistributions of source code must retain the above copyright
120755 + * notice, this list of conditions and the following disclaimer.
120756 + * * Redistributions in binary form must reproduce the above copyright
120757 + * notice, this list of conditions and the following disclaimer in the
120758 + * documentation and/or other materials provided with the distribution.
120759 + * * Neither the name of Freescale Semiconductor nor the
120760 + * names of its contributors may be used to endorse or promote products
120761 + * derived from this software without specific prior written permission.
120762 + *
120763 + *
120764 + * ALTERNATIVELY, this software may be distributed under the terms of the
120765 + * GNU General Public License ("GPL") as published by the Free Software
120766 + * Foundation, either version 2 of that License or (at your option) any
120767 + * later version.
120768 + *
120769 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120770 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120771 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120772 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120773 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120774 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120775 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120776 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120777 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120778 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120779 + */
120780 +
120781 +
120782 +#ifndef LNXWRP_SYSFS_FM_H_
120783 +#define LNXWRP_SYSFS_FM_H_
120784 +
120785 +#include "lnxwrp_sysfs.h"
120786 +
120787 +int fm_sysfs_create(struct device *dev);
120788 +void fm_sysfs_destroy(struct device *dev);
120789 +int fm_dump_regs(void *h_dev, char *buf, int nn);
120790 +int fm_fpm_dump_regs(void *h_dev, char *buf, int nn);
120791 +int fm_kg_dump_regs(void *h_pcd, char *buf, int nn);
120792 +int fm_kg_pe_dump_regs(void *h_pcd, char *buf, int nn);
120793 +int fm_dump_scheme(void *h_pcd, int scnum, char *buf, int nn);
120794 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn);
120795 +int fm_dump_cls_plan(void *h_pcd, int cpn, char *buf, int nn);
120796 +int fm_plcr_dump_regs(void *h_pcd, char *buf, int nn);
120797 +int fm_prs_dump_regs(void *h_pcd, char *buf, int nn);
120798 +int fm_profile_dump_regs(void *h_pcd, int ppnum, char *buf, int nn);
120799 +
120800 +#define FM_DMP_PGSZ_ERR { \
120801 + snprintf(&buf[PAGE_SIZE - 80], 70, \
120802 + "\n Err: current sysfs buffer reached PAGE_SIZE\n");\
120803 + n = PAGE_SIZE - 2; \
120804 + }
120805 +
120806 +#define FM_DMP_LN(buf, n, ...) \
120807 + do { \
120808 + int k, m = n; \
120809 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
120810 + if (k < 0 || m > PAGE_SIZE - 90) \
120811 + FM_DMP_PGSZ_ERR \
120812 + n = m; \
120813 + } while (0)
120814 +
120815 +#define FM_DMP_TITLE(buf, n, addr, ...) \
120816 + do { \
120817 + int k, m = n; \
120818 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
120819 + if (k < 0 || m > PAGE_SIZE - 90) \
120820 + FM_DMP_PGSZ_ERR \
120821 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
120822 + if (k < 0 || m > PAGE_SIZE - 90) \
120823 + FM_DMP_PGSZ_ERR \
120824 + if (addr) { \
120825 + phys_addr_t pa; \
120826 + pa = virt_to_phys(addr); \
120827 + m += k = \
120828 + snprintf(&buf[m], PAGE_SIZE - m, " (0x%lX)", \
120829 + (long unsigned int)(pa)); \
120830 + if (k < 0 || m > PAGE_SIZE - 90) \
120831 + FM_DMP_PGSZ_ERR \
120832 + } \
120833 + m += k = snprintf(&buf[m], PAGE_SIZE - m, \
120834 + "\n----------------------------------------\n\n"); \
120835 + if (k < 0 || m > PAGE_SIZE - 90) \
120836 + FM_DMP_PGSZ_ERR \
120837 + n = m; \
120838 + } while (0)
120839 +
120840 +#define FM_DMP_SUBTITLE(buf, n, ...) \
120841 + do { \
120842 + int k, m = n; \
120843 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "------- "); \
120844 + if (k < 0 || m > PAGE_SIZE - 90) \
120845 + FM_DMP_PGSZ_ERR \
120846 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
120847 + if (k < 0 || m > PAGE_SIZE - 90) \
120848 + FM_DMP_PGSZ_ERR \
120849 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
120850 + if (k < 0 || m > PAGE_SIZE - 90) \
120851 + FM_DMP_PGSZ_ERR \
120852 + n = m; \
120853 + } while (0)
120854 +
120855 +#define FM_DMP_MEM_32(buf, n, addr) \
120856 + { \
120857 + uint32_t val; \
120858 + phys_addr_t pa; \
120859 + int k, m = n; \
120860 + pa = virt_to_phys(addr); \
120861 + val = ioread32be((addr)); \
120862 + do { \
120863 + m += k = snprintf(&buf[m], \
120864 + PAGE_SIZE - m, "0x%010llX: 0x%08x\n", \
120865 + pa, val); \
120866 + if (k < 0 || m > PAGE_SIZE - 90) \
120867 + FM_DMP_PGSZ_ERR \
120868 + n += k; \
120869 + } while (0) ;\
120870 + }
120871 +
120872 +#define FM_DMP_V32(buf, n, st, phrase) \
120873 + do { \
120874 + int k, m = n; \
120875 + phys_addr_t pa = virt_to_phys(&((st)->phrase)); \
120876 + k = snprintf(&buf[m], PAGE_SIZE - m, \
120877 + "0x%010llX: 0x%08x%8s\t%s\n", (unsigned long long) pa, \
120878 + ioread32be((uint32_t *)&((st)->phrase)), "", #phrase); \
120879 + if (k < 0 || m > PAGE_SIZE - 90) \
120880 + FM_DMP_PGSZ_ERR \
120881 + n += k; \
120882 + } while (0)
120883 +
120884 +#endif /* LNXWRP_SYSFS_FM_H_ */
120885 --- /dev/null
120886 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
120887 @@ -0,0 +1,1268 @@
120888 +/*
120889 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120890 + *
120891 + * Redistribution and use in source and binary forms, with or without
120892 + * modification, are permitted provided that the following conditions are met:
120893 + * * Redistributions of source code must retain the above copyright
120894 + * notice, this list of conditions and the following disclaimer.
120895 + * * Redistributions in binary form must reproduce the above copyright
120896 + * notice, this list of conditions and the following disclaimer in the
120897 + * documentation and/or other materials provided with the distribution.
120898 + * * Neither the name of Freescale Semiconductor nor the
120899 + * names of its contributors may be used to endorse or promote products
120900 + * derived from this software without specific prior written permission.
120901 + *
120902 + *
120903 + * ALTERNATIVELY, this software may be distributed under the terms of the
120904 + * GNU General Public License ("GPL") as published by the Free Software
120905 + * Foundation, either version 2 of that License or (at your option) any
120906 + * later version.
120907 + *
120908 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120909 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120910 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120911 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120912 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120913 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120914 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120915 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120916 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120917 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120918 + */
120919 +
120920 +#include "lnxwrp_sysfs.h"
120921 +#include "lnxwrp_fm.h"
120922 +#include "debug_ext.h"
120923 +#include "lnxwrp_sysfs_fm_port.h"
120924 +#include "lnxwrp_sysfs_fm.h"
120925 +
120926 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port.h"
120927 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h"
120928 +
120929 +#if defined(__ERR_MODULE__)
120930 +#undef __ERR_MODULE__
120931 +#endif
120932 +
120933 +#include "../../sdk_fman/Peripherals/FM/fm.h"
120934 +
120935 +static const struct sysfs_stats_t portSysfsStats[] = {
120936 + /* RX/TX/OH common statistics */
120937 + {
120938 + .stat_name = "port_frame",
120939 + .stat_counter = e_FM_PORT_COUNTERS_FRAME,
120940 + },
120941 + {
120942 + .stat_name = "port_discard_frame",
120943 + .stat_counter = e_FM_PORT_COUNTERS_DISCARD_FRAME,
120944 + },
120945 + {
120946 + .stat_name = "port_dealloc_buf",
120947 + .stat_counter = e_FM_PORT_COUNTERS_DEALLOC_BUF,
120948 + },
120949 + {
120950 + .stat_name = "port_enq_total",
120951 + .stat_counter = e_FM_PORT_COUNTERS_ENQ_TOTAL,
120952 + },
120953 + /* TX/OH */
120954 + {
120955 + .stat_name = "port_length_err",
120956 + .stat_counter = e_FM_PORT_COUNTERS_LENGTH_ERR,
120957 + },
120958 + {
120959 + .stat_name = "port_unsupprted_format",
120960 + .stat_counter = e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT,
120961 + },
120962 + {
120963 + .stat_name = "port_deq_total",
120964 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_TOTAL,
120965 + },
120966 + {
120967 + .stat_name = "port_deq_from_default",
120968 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT,
120969 + },
120970 + {
120971 + .stat_name = "port_deq_confirm",
120972 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_CONFIRM,
120973 + },
120974 + /* RX/OH */
120975 + {
120976 + .stat_name = "port_rx_bad_frame",
120977 + .stat_counter = e_FM_PORT_COUNTERS_RX_BAD_FRAME,
120978 + },
120979 + {
120980 + .stat_name = "port_rx_large_frame",
120981 + .stat_counter = e_FM_PORT_COUNTERS_RX_LARGE_FRAME,
120982 + },
120983 + {
120984 + .stat_name = "port_rx_out_of_buffers_discard",
120985 + .stat_counter = e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD,
120986 + },
120987 + {
120988 + .stat_name = "port_rx_filter_frame",
120989 + .stat_counter = e_FM_PORT_COUNTERS_RX_FILTER_FRAME,
120990 + },
120991 + /* TODO: Particular statistics for OH ports */
120992 + {}
120993 +};
120994 +
120995 +static ssize_t show_fm_port_stats(struct device *dev,
120996 + struct device_attribute *attr, char *buf)
120997 +{
120998 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
120999 + t_LnxWrpFmDev *p_LnxWrpFmDev;
121000 + unsigned long flags;
121001 + int n = 0;
121002 + uint8_t counter = 0;
121003 +
121004 + if (attr == NULL || buf == NULL || dev == NULL)
121005 + return -EINVAL;
121006 +
121007 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121008 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121009 + return -EINVAL;
121010 +
121011 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
121012 + if (WARN_ON(p_LnxWrpFmDev == NULL))
121013 + return -EINVAL;
121014 +
121015 + if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev)
121016 + return -EIO;
121017 +
121018 + if (!p_LnxWrpFmPortDev->h_Dev) {
121019 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121020 + return n;
121021 + }
121022 +
121023 + counter = fm_find_statistic_counter_by_name(
121024 + attr->attr.name,
121025 + portSysfsStats, NULL);
121026 +
121027 + if (counter == e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR) {
121028 + uint32_t fmRev = 0;
121029 + fmRev = 0xffff &
121030 + ioread32(UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr +
121031 + 0x000c30c4));
121032 +
121033 + if (fmRev == 0x0100) {
121034 + local_irq_save(flags);
121035 + n = snprintf(buf, PAGE_SIZE,
121036 + "counter not available for revision 1\n");
121037 + local_irq_restore(flags);
121038 + }
121039 + return n;
121040 + }
121041 +
121042 + local_irq_save(flags);
121043 + n = snprintf(buf, PAGE_SIZE, "\t%s counter: %u\n",
121044 + p_LnxWrpFmPortDev->name,
121045 + FM_PORT_GetCounter(p_LnxWrpFmPortDev->h_Dev,
121046 + (e_FmPortCounters) counter));
121047 + local_irq_restore(flags);
121048 +
121049 + return n;
121050 +}
121051 +
121052 +/* FM PORT RX/TX/OH statistics */
121053 +static DEVICE_ATTR(port_frame, S_IRUGO, show_fm_port_stats, NULL);
121054 +static DEVICE_ATTR(port_discard_frame, S_IRUGO, show_fm_port_stats, NULL);
121055 +static DEVICE_ATTR(port_dealloc_buf, S_IRUGO, show_fm_port_stats, NULL);
121056 +static DEVICE_ATTR(port_enq_total, S_IRUGO, show_fm_port_stats, NULL);
121057 +/* FM PORT TX/OH statistics */
121058 +static DEVICE_ATTR(port_length_err, S_IRUGO, show_fm_port_stats, NULL);
121059 +static DEVICE_ATTR(port_unsupprted_format, S_IRUGO, show_fm_port_stats, NULL);
121060 +static DEVICE_ATTR(port_deq_total, S_IRUGO, show_fm_port_stats, NULL);
121061 +static DEVICE_ATTR(port_deq_from_default, S_IRUGO, show_fm_port_stats, NULL);
121062 +static DEVICE_ATTR(port_deq_confirm, S_IRUGO, show_fm_port_stats, NULL);
121063 +/* FM PORT RX/OH statistics */
121064 +static DEVICE_ATTR(port_rx_bad_frame, S_IRUGO, show_fm_port_stats, NULL);
121065 +static DEVICE_ATTR(port_rx_large_frame, S_IRUGO, show_fm_port_stats, NULL);
121066 +static DEVICE_ATTR(port_rx_out_of_buffers_discard, S_IRUGO,
121067 + show_fm_port_stats, NULL);
121068 +static DEVICE_ATTR(port_rx_filter_frame, S_IRUGO, show_fm_port_stats, NULL);
121069 +
121070 +/* FM PORT TX statistics */
121071 +static struct attribute *fm_tx_port_dev_stats_attributes[] = {
121072 + &dev_attr_port_frame.attr,
121073 + &dev_attr_port_discard_frame.attr,
121074 + &dev_attr_port_dealloc_buf.attr,
121075 + &dev_attr_port_enq_total.attr,
121076 + &dev_attr_port_length_err.attr,
121077 + &dev_attr_port_unsupprted_format.attr,
121078 + &dev_attr_port_deq_total.attr,
121079 + &dev_attr_port_deq_from_default.attr,
121080 + &dev_attr_port_deq_confirm.attr,
121081 + NULL
121082 +};
121083 +
121084 +static const struct attribute_group fm_tx_port_dev_stats_attr_grp = {
121085 + .name = "statistics",
121086 + .attrs = fm_tx_port_dev_stats_attributes
121087 +};
121088 +
121089 +/* FM PORT RX statistics */
121090 +static struct attribute *fm_rx_port_dev_stats_attributes[] = {
121091 + &dev_attr_port_frame.attr,
121092 + &dev_attr_port_discard_frame.attr,
121093 + &dev_attr_port_dealloc_buf.attr,
121094 + &dev_attr_port_enq_total.attr,
121095 + &dev_attr_port_rx_bad_frame.attr,
121096 + &dev_attr_port_rx_large_frame.attr,
121097 + &dev_attr_port_rx_out_of_buffers_discard.attr,
121098 + &dev_attr_port_rx_filter_frame.attr,
121099 + NULL
121100 +};
121101 +
121102 +static const struct attribute_group fm_rx_port_dev_stats_attr_grp = {
121103 + .name = "statistics",
121104 + .attrs = fm_rx_port_dev_stats_attributes
121105 +};
121106 +
121107 +/* TODO: add particular OH ports statistics */
121108 +static struct attribute *fm_oh_port_dev_stats_attributes[] = {
121109 + &dev_attr_port_frame.attr,
121110 + &dev_attr_port_discard_frame.attr,
121111 + &dev_attr_port_dealloc_buf.attr,
121112 + &dev_attr_port_enq_total.attr,
121113 + /*TX*/ &dev_attr_port_length_err.attr,
121114 + &dev_attr_port_unsupprted_format.attr,
121115 + &dev_attr_port_deq_total.attr,
121116 + &dev_attr_port_deq_from_default.attr,
121117 + &dev_attr_port_deq_confirm.attr,
121118 + /* &dev_attr_port_rx_bad_frame.attr, */
121119 + /* &dev_attr_port_rx_large_frame.attr, */
121120 + &dev_attr_port_rx_out_of_buffers_discard.attr,
121121 + /*&dev_attr_port_rx_filter_frame.attr, */
121122 + NULL
121123 +};
121124 +
121125 +static const struct attribute_group fm_oh_port_dev_stats_attr_grp = {
121126 + .name = "statistics",
121127 + .attrs = fm_oh_port_dev_stats_attributes
121128 +};
121129 +
121130 +static ssize_t show_fm_port_regs(struct device *dev,
121131 + struct device_attribute *attr, char *buf)
121132 +{
121133 + unsigned long flags;
121134 + unsigned n = 0;
121135 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121136 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121137 +#endif
121138 + if (attr == NULL || buf == NULL || dev == NULL)
121139 + return -EINVAL;
121140 +
121141 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121142 + p_LnxWrpFmPortDev =
121143 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121144 +
121145 +
121146 + local_irq_save(flags);
121147 +
121148 + if (!p_LnxWrpFmPortDev->h_Dev) {
121149 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121150 + return n;
121151 + } else {
121152 + n = snprintf(buf, PAGE_SIZE,
121153 + "FM port driver registers dump.\n");
121154 + n = fm_port_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
121155 + }
121156 +
121157 + local_irq_restore(flags);
121158 +
121159 + return n;
121160 +#else
121161 +
121162 + local_irq_save(flags);
121163 + n = snprintf(buf, PAGE_SIZE,
121164 + "Debug level is too low to dump registers!!!\n");
121165 + local_irq_restore(flags);
121166 +
121167 + return n;
121168 +#endif
121169 +}
121170 +static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn)
121171 +{
121172 + t_FmPort *p_FmPort;
121173 + t_Fm *p_Fm;
121174 + uint8_t hardwarePortId;
121175 + uint32_t *param_page;
121176 + t_ArCommonDesc *ArCommonDescPtr;
121177 + uint32_t *mem;
121178 + int i, n = nn;
121179 +
121180 + p_FmPort = (t_FmPort *)h_dev;
121181 + hardwarePortId = p_FmPort->hardwarePortId;
121182 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121183 +
121184 + if (!FM_PORT_IsInDsar(p_FmPort))
121185 + {
121186 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
121187 + hardwarePortId);
121188 + return n;
121189 + }
121190 + FM_DMP_LN(buf, n, "port %u DSAR mem\n", hardwarePortId);
121191 + FM_DMP_LN(buf, n, "========================\n");
121192 +
121193 + /* do I need request_mem_region here? */
121194 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
121195 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), 300*4)); /* this should be changed*/
121196 + mem = (uint32_t*)ArCommonDescPtr;
121197 + for (i = 0; i < 300; i+=4)
121198 + FM_DMP_LN(buf, n, "%08x: %08x %08x %08x %08x\n", i*4, mem[i], mem[i + 1], mem[i + 2], mem[i + 3]);
121199 + iounmap(ArCommonDescPtr);
121200 + iounmap(param_page);
121201 + return n;
121202 +}
121203 +
121204 +static int fm_port_dsar_dump_regs(void *h_dev, char *buf, int nn)
121205 +{
121206 + t_FmPort *p_FmPort;
121207 + t_Fm *p_Fm;
121208 + uint8_t hardwarePortId;
121209 + uint32_t *param_page;
121210 + t_ArCommonDesc *ArCommonDescPtr;
121211 + int i, n = nn;
121212 +
121213 + p_FmPort = (t_FmPort *)h_dev;
121214 + hardwarePortId = p_FmPort->hardwarePortId;
121215 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121216 +
121217 + if (!FM_PORT_IsInDsar(p_FmPort))
121218 + {
121219 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
121220 + hardwarePortId);
121221 + return n;
121222 + }
121223 + FM_DMP_LN(buf, n, "port %u DSAR information\n", hardwarePortId);
121224 + FM_DMP_LN(buf, n, "========================\n");
121225 +
121226 + /* do I need request_mem_region here? */
121227 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
121228 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/
121229 + FM_DMP_LN(buf, n, "Tx port: 0x%x\n", ArCommonDescPtr->arTxPort);
121230 + FM_DMP_LN(buf, n, "Active HPNIA: 0x%08x\n", ArCommonDescPtr->activeHPNIA);
121231 + FM_DMP_LN(buf, n, "Snmp port: 0x%x\n", ArCommonDescPtr->snmpPort);
121232 + FM_DMP_LN(buf, n, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ArCommonDescPtr->macStationAddr[0],
121233 + ArCommonDescPtr->macStationAddr[1], ArCommonDescPtr->macStationAddr[2],
121234 + ArCommonDescPtr->macStationAddr[3], ArCommonDescPtr->macStationAddr[4],
121235 + ArCommonDescPtr->macStationAddr[5]);
121236 + FM_DMP_LN(buf, n, "filterControl: 0x%02x\n", ArCommonDescPtr->filterControl);
121237 + FM_DMP_LN(buf, n, "tcpControlPass: 0x%04x\n", ArCommonDescPtr->tcpControlPass);
121238 + FM_DMP_LN(buf, n, "ipProtocolTblSize: 0x%x\n", ArCommonDescPtr->ipProtocolTblSize);
121239 + FM_DMP_LN(buf, n, "udpPortTblSize: 0x%x\n", ArCommonDescPtr->udpPortTblSize);
121240 + FM_DMP_LN(buf, n, "tcpPortTblSize: 0x%x\n", ArCommonDescPtr->tcpPortTblSize);
121241 + if (ArCommonDescPtr->p_ArStats)
121242 + {
121243 + t_ArStatistics *arStatistics = (t_ArStatistics*)
121244 + ioremap(ioread32be(&ArCommonDescPtr->p_ArStats) +
121245 + p_FmPort->fmMuramPhysBaseAddr,
121246 + sizeof (t_ArStatistics));
121247 + FM_DMP_LN(buf, n, "\nDSAR statistics\n");
121248 + FM_DMP_LN(buf, n, "DSAR_Discarded: 0x%x\n", arStatistics->dsarDiscarded);
121249 + FM_DMP_LN(buf, n, "DSAR_Err_Discarded: 0x%x\n", arStatistics->dsarErrDiscarded);
121250 + FM_DMP_LN(buf, n, "DSAR_Frag_Discarded: 0x%x\n", arStatistics->dsarFragDiscarded);
121251 + FM_DMP_LN(buf, n, "DSAR_Tunnel_Discarded: 0x%x\n", arStatistics->dsarTunnelDiscarded);
121252 + FM_DMP_LN(buf, n, "DSAR_ARP_Discarded: 0x%x\n", arStatistics->dsarArpDiscarded);
121253 + FM_DMP_LN(buf, n, "DSAR_IP_Discarded: 0x%x\n", arStatistics->dsarIpDiscarded);
121254 + FM_DMP_LN(buf, n, "DSAR_TCP_Discarded: 0x%x\n", arStatistics->dsarTcpDiscarded);
121255 + FM_DMP_LN(buf, n, "DSAR_UDP_Discarded: 0x%x\n", arStatistics->dsarUdpDiscarded);
121256 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Checksum_Err: 0x%x\n", arStatistics->dsarIcmpV6ChecksumErr);
121257 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Other_Type: 0x%x\n", arStatistics->dsarIcmpV6OtherType);
121258 + FM_DMP_LN(buf, n, "DSAR_ICMPv4_Other_Type: 0x%x\n", arStatistics->dsarIcmpV4OtherType);
121259 +
121260 + iounmap(arStatistics);
121261 + }
121262 + if (ArCommonDescPtr->p_ArpDescriptor)
121263 + {
121264 + t_DsarArpDescriptor* ArpDescriptor = (t_DsarArpDescriptor*)
121265 + ioremap(ioread32be(&ArCommonDescPtr->p_ArpDescriptor) +
121266 + p_FmPort->fmMuramPhysBaseAddr,
121267 + sizeof (t_DsarArpDescriptor));
121268 + FM_DMP_LN(buf, n, "\nARP\n");
121269 + FM_DMP_LN(buf, n, "===\n");
121270 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ArpDescriptor->control);
121271 + if (ArpDescriptor->numOfBindings)
121272 + {
121273 + char ip_str[100];
121274 + t_DsarArpBindingEntry* bindings = ioremap(
121275 + ioread32be(&ArpDescriptor->p_Bindings) +
121276 + p_FmPort->fmMuramPhysBaseAddr,
121277 + ArpDescriptor->numOfBindings *
121278 + sizeof(t_DsarArpBindingEntry));
121279 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121280 + FM_DMP_LN(buf, n, " ip vlan id\n");
121281 + for (i = 0; i < ArpDescriptor->numOfBindings; i++)
121282 + {
121283 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121284 + ip_addr[0], ip_addr[1],
121285 + ip_addr[2], ip_addr[3]);
121286 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121287 + ip_str, bindings->vlanId);
121288 + }
121289 + iounmap(bindings);
121290 + }
121291 + if (ArpDescriptor->p_Statistics)
121292 + {
121293 + t_DsarArpStatistics* arpStats = ioremap(
121294 + ioread32be(&ArpDescriptor->p_Statistics) +
121295 + p_FmPort->fmMuramPhysBaseAddr,
121296 + sizeof(t_DsarArpStatistics));
121297 + FM_DMP_LN(buf, n, "statistics\n");
121298 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", arpStats->invalCnt);
121299 + FM_DMP_LN(buf, n, "ECHO_CNT: 0x%x\n", arpStats->echoCnt);
121300 + FM_DMP_LN(buf, n, "CD_CNT: 0x%x\n", arpStats->cdCnt);
121301 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", arpStats->arCnt);
121302 + FM_DMP_LN(buf, n, "RATM_CNT: 0x%x\n", arpStats->ratmCnt);
121303 + FM_DMP_LN(buf, n, "UKOP_CNT: 0x%x\n", arpStats->ukopCnt);
121304 + FM_DMP_LN(buf, n, "NMTP_CNT: 0x%x\n", arpStats->nmtpCnt);
121305 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", arpStats->nmVlanCnt);
121306 + iounmap(arpStats);
121307 + }
121308 +
121309 + iounmap(ArpDescriptor);
121310 + }
121311 + if (ArCommonDescPtr->p_IcmpV4Descriptor)
121312 + {
121313 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor =
121314 + (t_DsarIcmpV4Descriptor*)ioremap(ioread32be(
121315 + &ArCommonDescPtr->p_IcmpV4Descriptor) +
121316 + p_FmPort->fmMuramPhysBaseAddr,
121317 + sizeof (t_DsarIcmpV4Descriptor));
121318 + FM_DMP_LN(buf, n, "\nEcho ICMPv4\n");
121319 + FM_DMP_LN(buf, n, "===========\n");
121320 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV4Descriptor->control);
121321 + if (ICMPV4Descriptor->numOfBindings)
121322 + {
121323 + char ip_str[100];
121324 + t_DsarArpBindingEntry* bindings = ioremap(
121325 + ioread32be(&ICMPV4Descriptor->p_Bindings) +
121326 + p_FmPort->fmMuramPhysBaseAddr,
121327 + ICMPV4Descriptor->numOfBindings *
121328 + sizeof(t_DsarArpBindingEntry));
121329 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121330 + FM_DMP_LN(buf, n, " ip vlan id\n");
121331 + for (i = 0; i < ICMPV4Descriptor->numOfBindings; i++)
121332 + {
121333 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121334 + ip_addr[0], ip_addr[1],
121335 + ip_addr[2], ip_addr[3]);
121336 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121337 + ip_str, bindings->vlanId);
121338 + }
121339 + iounmap(bindings);
121340 + }
121341 + if (ICMPV4Descriptor->p_Statistics)
121342 + {
121343 + t_DsarIcmpV4Statistics* icmpv4Stats = ioremap(
121344 + ioread32be(&ICMPV4Descriptor->p_Statistics) +
121345 + p_FmPort->fmMuramPhysBaseAddr,
121346 + sizeof(t_DsarIcmpV4Statistics));
121347 + FM_DMP_LN(buf, n, "statistics\n");
121348 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv4Stats->invalCnt);
121349 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv4Stats->nmVlanCnt);
121350 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv4Stats->nmIpCnt);
121351 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv4Stats->arCnt);
121352 + FM_DMP_LN(buf, n, "CSERR_CNT: 0x%x\n", icmpv4Stats->cserrCnt);
121353 + iounmap(icmpv4Stats);
121354 + }
121355 + iounmap(ICMPV4Descriptor);
121356 + }
121357 + if (ArCommonDescPtr->p_NdDescriptor)
121358 + {
121359 + t_DsarNdDescriptor *NDDescriptor =
121360 + (t_DsarNdDescriptor*)ioremap(ioread32be(
121361 + &ArCommonDescPtr->p_NdDescriptor) + p_FmPort->
121362 + fmMuramPhysBaseAddr, sizeof (t_DsarNdDescriptor));
121363 + FM_DMP_LN(buf, n, "\nNDP\n");
121364 + FM_DMP_LN(buf, n, "===\n");
121365 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", NDDescriptor->control);
121366 + FM_DMP_LN(buf, n, "solicited address 0x%08x\n", NDDescriptor->solicitedAddr);
121367 + if (NDDescriptor->numOfBindings)
121368 + {
121369 + char ip_str[100];
121370 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
121371 + ioread32be(&NDDescriptor->p_Bindings) +
121372 + p_FmPort->fmMuramPhysBaseAddr,
121373 + NDDescriptor->numOfBindings *
121374 + sizeof(t_DsarIcmpV6BindingEntry));
121375 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
121376 + FM_DMP_LN(buf, n, " ip vlan id\n");
121377 + for (i = 0; i < NDDescriptor->numOfBindings; i++)
121378 + {
121379 + n += snprintf(ip_str, 100,
121380 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
121381 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
121382 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
121383 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
121384 + }
121385 + iounmap(bindings);
121386 + }
121387 + if (NDDescriptor->p_Statistics)
121388 + {
121389 + t_NdStatistics* ndStats = ioremap(
121390 + ioread32be(&NDDescriptor->p_Statistics) +
121391 + p_FmPort->fmMuramPhysBaseAddr,
121392 + sizeof(t_NdStatistics));
121393 + FM_DMP_LN(buf, n, "statistics\n");
121394 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", ndStats->invalCnt);
121395 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", ndStats->nmVlanCnt);
121396 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", ndStats->nmIpCnt);
121397 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", ndStats->arCnt);
121398 + FM_DMP_LN(buf, n, "USADVERT_CNT: 0x%x\n", ndStats->usadvertCnt);
121399 + FM_DMP_LN(buf, n, "NMMCAST_CNT: 0x%x\n", ndStats->nmmcastCnt);
121400 + FM_DMP_LN(buf, n, "NSLLA_CNT: 0x%x\n", ndStats->nsllaCnt);
121401 + iounmap(ndStats);
121402 + }
121403 + iounmap(NDDescriptor);
121404 + }
121405 + if (ArCommonDescPtr->p_IcmpV6Descriptor)
121406 + {
121407 + t_DsarIcmpV6Descriptor *ICMPV6Descriptor =
121408 + (t_DsarIcmpV6Descriptor*)ioremap(ioread32be(
121409 + &ArCommonDescPtr->p_IcmpV6Descriptor) + p_FmPort->
121410 + fmMuramPhysBaseAddr, sizeof (t_DsarIcmpV6Descriptor));
121411 + FM_DMP_LN(buf, n, "\nEcho ICMPv6\n");
121412 + FM_DMP_LN(buf, n, "===========\n");
121413 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV6Descriptor->control);
121414 + if (ICMPV6Descriptor->numOfBindings)
121415 + {
121416 + char ip_str[100];
121417 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
121418 + ioread32be(&ICMPV6Descriptor->p_Bindings) +
121419 + p_FmPort->fmMuramPhysBaseAddr,
121420 + ICMPV6Descriptor->numOfBindings *
121421 + sizeof(t_DsarIcmpV6BindingEntry));
121422 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
121423 + FM_DMP_LN(buf, n, " ip vlan id\n");
121424 + for (i = 0; i < ICMPV6Descriptor->numOfBindings; i++)
121425 + {
121426 + n += snprintf(ip_str, 100,
121427 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
121428 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
121429 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
121430 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
121431 + }
121432 + iounmap(bindings);
121433 + }
121434 + if (ICMPV6Descriptor->p_Statistics)
121435 + {
121436 + t_DsarIcmpV6Statistics* icmpv6Stats = ioremap(
121437 + ioread32be(&ICMPV6Descriptor->p_Statistics) +
121438 + p_FmPort->fmMuramPhysBaseAddr,
121439 + sizeof(t_DsarIcmpV6Statistics));
121440 + FM_DMP_LN(buf, n, "statistics\n");
121441 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv6Stats->invalCnt);
121442 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv6Stats->nmVlanCnt);
121443 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv6Stats->nmIpCnt);
121444 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv6Stats->arCnt);
121445 + iounmap(icmpv6Stats);
121446 + }
121447 + iounmap(ICMPV6Descriptor);
121448 + }
121449 + if (ArCommonDescPtr->p_SnmpDescriptor)
121450 + {
121451 + t_DsarSnmpDescriptor *SnmpDescriptor =
121452 + (t_DsarSnmpDescriptor*)ioremap(ioread32be(
121453 + &ArCommonDescPtr->p_SnmpDescriptor) + p_FmPort->
121454 + fmMuramPhysBaseAddr, sizeof (t_DsarSnmpDescriptor));
121455 + FM_DMP_LN(buf, n, "\nSNMP\n");
121456 + FM_DMP_LN(buf, n, "===========\n");
121457 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", SnmpDescriptor->control);
121458 + FM_DMP_LN(buf, n, "max message length 0x%04x\n", SnmpDescriptor->maxSnmpMsgLength);
121459 + if (SnmpDescriptor->numOfIpv4Addresses)
121460 + {
121461 + char ip_str[100];
121462 + t_DsarSnmpIpv4AddrTblEntry* addrs = ioremap(
121463 + ioread32be(&SnmpDescriptor->p_Ipv4AddrTbl) +
121464 + p_FmPort->fmMuramPhysBaseAddr,
121465 + SnmpDescriptor->numOfIpv4Addresses *
121466 + sizeof(t_DsarSnmpIpv4AddrTblEntry));
121467 + uint8_t* ip_addr = (uint8_t*)&addrs->ipv4Addr;
121468 + FM_DMP_LN(buf, n, " ip vlan id\n");
121469 + for (i = 0; i < SnmpDescriptor->numOfIpv4Addresses; i++)
121470 + {
121471 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121472 + ip_addr[0], ip_addr[1],
121473 + ip_addr[2], ip_addr[3]);
121474 + FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, addrs->vlanId);
121475 + }
121476 + iounmap(addrs);
121477 + }
121478 + if (SnmpDescriptor->p_Statistics)
121479 + {
121480 + t_DsarSnmpStatistics* snmpStats = ioremap(
121481 + ioread32be(&SnmpDescriptor->p_Statistics) +
121482 + p_FmPort->fmMuramPhysBaseAddr,
121483 + sizeof(t_DsarSnmpStatistics));
121484 + FM_DMP_LN(buf, n, "statistics\n");
121485 + FM_DMP_LN(buf, n, "snmpErrCnt: 0x%x\n", snmpStats->snmpErrCnt);
121486 + FM_DMP_LN(buf, n, "snmpCommunityErrCnt: 0x%x\n", snmpStats->snmpCommunityErrCnt);
121487 + FM_DMP_LN(buf, n, "snmpTotalDiscardCnt: 0x%x\n", snmpStats->snmpTotalDiscardCnt);
121488 + FM_DMP_LN(buf, n, "snmpGetReqCnt: 0x%x\n", snmpStats->snmpGetReqCnt);
121489 + FM_DMP_LN(buf, n, "snmpGetNextReqCnt: 0x%x\n", snmpStats->snmpGetNextReqCnt);
121490 + iounmap(snmpStats);
121491 + }
121492 + iounmap(SnmpDescriptor);
121493 + }
121494 + iounmap(ArCommonDescPtr);
121495 + iounmap(param_page);
121496 + return n;
121497 +}
121498 +
121499 +static ssize_t show_fm_port_dsar_mem(struct device *dev,
121500 + struct device_attribute *attr, char *buf)
121501 +{
121502 + unsigned long flags;
121503 + unsigned n = 0;
121504 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121505 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121506 +#endif
121507 + if (attr == NULL || buf == NULL || dev == NULL)
121508 + return -EINVAL;
121509 +
121510 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121511 + p_LnxWrpFmPortDev =
121512 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121513 +
121514 + local_irq_save(flags);
121515 +
121516 + if (!p_LnxWrpFmPortDev->h_Dev) {
121517 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121518 + return n;
121519 + } else {
121520 + n = snprintf(buf, PAGE_SIZE,
121521 + "FM port driver registers dump.\n");
121522 + n = fm_port_dsar_dump_mem(p_LnxWrpFmPortDev->h_Dev, buf, n);
121523 + }
121524 +
121525 + local_irq_restore(flags);
121526 +
121527 + return n;
121528 +#else
121529 +
121530 + local_irq_save(flags);
121531 + n = snprintf(buf, PAGE_SIZE,
121532 + "Debug level is too low to dump registers!!!\n");
121533 + local_irq_restore(flags);
121534 +
121535 + return n;
121536 +#endif
121537 +}
121538 +
121539 +static ssize_t show_fm_port_dsar_regs(struct device *dev,
121540 + struct device_attribute *attr, char *buf)
121541 +{
121542 + unsigned long flags;
121543 + unsigned n = 0;
121544 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121545 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121546 +#endif
121547 + if (attr == NULL || buf == NULL || dev == NULL)
121548 + return -EINVAL;
121549 +
121550 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121551 + p_LnxWrpFmPortDev =
121552 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121553 +
121554 + local_irq_save(flags);
121555 +
121556 + if (!p_LnxWrpFmPortDev->h_Dev) {
121557 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121558 + return n;
121559 + } else {
121560 + n = snprintf(buf, PAGE_SIZE,
121561 + "FM port driver registers dump.\n");
121562 + n = fm_port_dsar_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
121563 + }
121564 +
121565 + local_irq_restore(flags);
121566 +
121567 + return n;
121568 +#else
121569 +
121570 + local_irq_save(flags);
121571 + n = snprintf(buf, PAGE_SIZE,
121572 + "Debug level is too low to dump registers!!!\n");
121573 + local_irq_restore(flags);
121574 +
121575 + return n;
121576 +#endif
121577 +}
121578 +
121579 +#if (DPAA_VERSION >= 11)
121580 +static ssize_t show_fm_port_ipv4_options(struct device *dev,
121581 + struct device_attribute *attr, char *buf)
121582 +{
121583 + unsigned long flags;
121584 + unsigned n = 0;
121585 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121586 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121587 +#endif
121588 +
121589 + if (attr == NULL || buf == NULL || dev == NULL)
121590 + return -EINVAL;
121591 +
121592 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121593 + p_LnxWrpFmPortDev =
121594 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121595 +
121596 + local_irq_save(flags);
121597 +
121598 + if (!p_LnxWrpFmPortDev->h_Dev) {
121599 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121600 + return n;
121601 + } else if (((t_FmPort *)p_LnxWrpFmPortDev->h_Dev)->p_ParamsPage
121602 + == NULL) {
121603 + n = snprintf(buf, PAGE_SIZE,
121604 + "\tPort: FMan-controller params page not set\n");
121605 + return n;
121606 + } else {
121607 + n = snprintf(buf, PAGE_SIZE,
121608 + "Counter for fragmented pkt with IP header options\n");
121609 + n = fm_port_dump_ipv4_opt(p_LnxWrpFmPortDev->h_Dev, buf, n);
121610 + }
121611 +
121612 + local_irq_restore(flags);
121613 +
121614 + return n;
121615 +#else
121616 +
121617 + local_irq_save(flags);
121618 + n = snprintf(buf, PAGE_SIZE,
121619 + "Debug level is too low to dump registers!!!\n");
121620 + local_irq_restore(flags);
121621 +
121622 + return n;
121623 +#endif
121624 +}
121625 +
121626 +#endif
121627 +
121628 +static ssize_t show_fm_port_bmi_regs(struct device *dev,
121629 + struct device_attribute *attr, char *buf)
121630 +{
121631 + unsigned long flags;
121632 + unsigned n = 0;
121633 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121634 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121635 +#endif
121636 +
121637 + if (attr == NULL || buf == NULL || dev == NULL)
121638 + return -EINVAL;
121639 +
121640 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121641 + p_LnxWrpFmPortDev =
121642 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121643 +
121644 + local_irq_save(flags);
121645 +
121646 + if (!p_LnxWrpFmPortDev->h_Dev) {
121647 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121648 + return n;
121649 + } else {
121650 + n = snprintf(buf, PAGE_SIZE,
121651 + "FM port driver registers dump.\n");
121652 + n = fm_port_dump_regs_bmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
121653 + }
121654 +
121655 + local_irq_restore(flags);
121656 +
121657 + return n;
121658 +#else
121659 +
121660 + local_irq_save(flags);
121661 + n = snprintf(buf, PAGE_SIZE,
121662 + "Debug level is too low to dump registers!!!\n");
121663 + local_irq_restore(flags);
121664 +
121665 + return n;
121666 +#endif
121667 +}
121668 +
121669 +static ssize_t show_fm_port_qmi_regs(struct device *dev,
121670 + struct device_attribute *attr, char *buf)
121671 +{
121672 + unsigned long flags;
121673 + unsigned n = 0;
121674 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121675 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121676 +#endif
121677 +
121678 + if (attr == NULL || buf == NULL || dev == NULL)
121679 + return -EINVAL;
121680 +
121681 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121682 + p_LnxWrpFmPortDev =
121683 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121684 +
121685 + local_irq_save(flags);
121686 +
121687 + if (!p_LnxWrpFmPortDev->h_Dev) {
121688 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121689 + return n;
121690 + } else {
121691 + n = snprintf(buf, PAGE_SIZE,
121692 + "FM port driver registers dump.\n");
121693 + n = fm_port_dump_regs_qmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
121694 + }
121695 +
121696 + local_irq_restore(flags);
121697 +
121698 + return n;
121699 +#else
121700 +
121701 + local_irq_save(flags);
121702 + n = snprintf(buf, PAGE_SIZE,
121703 + "Debug level is too low to dump registers!!!\n");
121704 + local_irq_restore(flags);
121705 +
121706 + return n;
121707 +#endif
121708 +}
121709 +
121710 +static DEVICE_ATTR(fm_port_regs, S_IRUGO | S_IRUSR, show_fm_port_regs, NULL);
121711 +static DEVICE_ATTR(fm_port_qmi_regs, S_IRUGO | S_IRUSR, show_fm_port_qmi_regs, NULL);
121712 +static DEVICE_ATTR(fm_port_bmi_regs, S_IRUGO | S_IRUSR, show_fm_port_bmi_regs, NULL);
121713 +#if (DPAA_VERSION >= 11)
121714 +static DEVICE_ATTR(fm_port_ipv4_opt, S_IRUGO | S_IRUSR, show_fm_port_ipv4_options, NULL);
121715 +#endif
121716 +static DEVICE_ATTR(fm_port_dsar_regs, S_IRUGO | S_IRUSR, show_fm_port_dsar_regs, NULL);
121717 +static DEVICE_ATTR(fm_port_dsar_mem, S_IRUGO | S_IRUSR, show_fm_port_dsar_mem, NULL);
121718 +
121719 +int fm_port_sysfs_create(struct device *dev)
121720 +{
121721 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121722 +
121723 + if (dev == NULL)
121724 + return -EINVAL;
121725 +
121726 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121727 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121728 + return -EINVAL;
121729 +
121730 + /* store to remove them when module is disabled */
121731 + p_LnxWrpFmPortDev->dev_attr_regs = &dev_attr_fm_port_regs;
121732 + p_LnxWrpFmPortDev->dev_attr_qmi_regs = &dev_attr_fm_port_qmi_regs;
121733 + p_LnxWrpFmPortDev->dev_attr_bmi_regs = &dev_attr_fm_port_bmi_regs;
121734 +#if (DPAA_VERSION >= 11)
121735 + p_LnxWrpFmPortDev->dev_attr_ipv4_opt = &dev_attr_fm_port_ipv4_opt;
121736 +#endif
121737 + p_LnxWrpFmPortDev->dev_attr_dsar_regs = &dev_attr_fm_port_dsar_regs;
121738 + p_LnxWrpFmPortDev->dev_attr_dsar_mem = &dev_attr_fm_port_dsar_mem;
121739 + /* Registers dump entry - in future will be moved to debugfs */
121740 + if (device_create_file(dev, &dev_attr_fm_port_regs) != 0)
121741 + return -EIO;
121742 + if (device_create_file(dev, &dev_attr_fm_port_qmi_regs) != 0)
121743 + return -EIO;
121744 + if (device_create_file(dev, &dev_attr_fm_port_bmi_regs) != 0)
121745 + return -EIO;
121746 +#if (DPAA_VERSION >= 11)
121747 + if (device_create_file(dev, &dev_attr_fm_port_ipv4_opt) != 0)
121748 + return -EIO;
121749 +#endif
121750 + if (device_create_file(dev, &dev_attr_fm_port_dsar_regs) != 0)
121751 + return -EIO;
121752 + if (device_create_file(dev, &dev_attr_fm_port_dsar_mem) != 0)
121753 + return -EIO;
121754 +
121755 + /* FM Ports statistics */
121756 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
121757 + case e_FM_PORT_TYPE_TX:
121758 + case e_FM_PORT_TYPE_TX_10G:
121759 + if (sysfs_create_group
121760 + (&dev->kobj, &fm_tx_port_dev_stats_attr_grp) != 0)
121761 + return -EIO;
121762 + break;
121763 + case e_FM_PORT_TYPE_RX:
121764 + case e_FM_PORT_TYPE_RX_10G:
121765 + if (sysfs_create_group
121766 + (&dev->kobj, &fm_rx_port_dev_stats_attr_grp) != 0)
121767 + return -EIO;
121768 + break;
121769 + case e_FM_PORT_TYPE_DUMMY:
121770 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
121771 + if (sysfs_create_group
121772 + (&dev->kobj, &fm_oh_port_dev_stats_attr_grp) != 0)
121773 + return -EIO;
121774 + break;
121775 + default:
121776 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
121777 + __func__);
121778 + return -EINVAL;
121779 + break;
121780 + };
121781 +
121782 + return 0;
121783 +}
121784 +
121785 +void fm_port_sysfs_destroy(struct device *dev)
121786 +{
121787 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
121788 +
121789 + /* this function has never been tested !!! */
121790 +
121791 + if (WARN_ON(dev == NULL))
121792 + return;
121793 +
121794 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121795 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121796 + return;
121797 +
121798 + /* The name attribute will be freed also by these 2 functions? */
121799 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
121800 + case e_FM_PORT_TYPE_TX:
121801 + case e_FM_PORT_TYPE_TX_10G:
121802 + sysfs_remove_group(&dev->kobj, &fm_tx_port_dev_stats_attr_grp);
121803 + break;
121804 + case e_FM_PORT_TYPE_RX:
121805 + case e_FM_PORT_TYPE_RX_10G:
121806 + sysfs_remove_group(&dev->kobj, &fm_rx_port_dev_stats_attr_grp);
121807 + break;
121808 + case e_FM_PORT_TYPE_DUMMY:
121809 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
121810 + sysfs_remove_group(&dev->kobj, &fm_oh_port_dev_stats_attr_grp);
121811 + break;
121812 + default:
121813 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
121814 + __func__);
121815 + break;
121816 + };
121817 +
121818 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_regs);
121819 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_qmi_regs);
121820 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_bmi_regs);
121821 +#if (DPAA_VERSION >= 11)
121822 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_ipv4_opt);
121823 +#endif
121824 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_regs);
121825 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_mem);
121826 +}
121827 +
121828 +
121829 +int fm_port_dump_regs(void *h_dev, char *buf, int nn)
121830 +{
121831 + t_FmPort *p_FmPort;
121832 + t_Fm *p_Fm;
121833 + uint8_t hardwarePortId;
121834 + int n = nn;
121835 +
121836 + p_FmPort = (t_FmPort *)h_dev;
121837 + hardwarePortId = p_FmPort->hardwarePortId;
121838 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121839 +
121840 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1],
121841 + "fmbm_pp for port %u", hardwarePortId);
121842 + FM_DMP_MEM_32(buf, n,
121843 + &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1]);
121844 +
121845 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1],
121846 + "fmbm_pfs for port %u", hardwarePortId);
121847 + FM_DMP_MEM_32(buf, n,
121848 + &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1]);
121849 +
121850 + FM_DMP_TITLE(buf, n,
121851 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1],
121852 + "fmbm_spliodn for port %u", hardwarePortId);
121853 + FM_DMP_MEM_32(buf, n,
121854 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1]);
121855 +
121856 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId],
121857 + "fmfp_psfor port %u", hardwarePortId);
121858 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
121859 +
121860 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2],
121861 + "fmdmplrfor port %u", hardwarePortId);
121862 + FM_DMP_MEM_32(buf, n,
121863 + &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2]);
121864 + return n;
121865 +}
121866 +
121867 +#if (DPAA_VERSION >= 11)
121868 +
121869 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int nn)
121870 +{
121871 + t_FmPort *p_FmPort;
121872 + int n = nn;
121873 +
121874 + p_FmPort = (t_FmPort *)h_dev;
121875 +
121876 + FM_DMP_V32(buf, n, p_FmPort->p_ParamsPage, ipfOptionsCounter);
121877 +
121878 + FM_DMP_SUBTITLE(buf, n, "\n");
121879 +
121880 + return n;
121881 +}
121882 +#endif
121883 +
121884 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int nn)
121885 +{
121886 + t_FmPort *p_FmPort;
121887 + u_FmPortBmiRegs *p_bmi;
121888 +
121889 + char arr[20];
121890 + uint8_t flag;
121891 + int i = 0;
121892 + int n = nn;
121893 +
121894 + p_FmPort = (t_FmPort *)h_dev;
121895 + p_bmi = p_FmPort->p_FmPortBmiRegs;
121896 +
121897 + memset(arr, 0, sizeof(arr));
121898 + switch (p_FmPort->portType) {
121899 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
121900 + strcpy(arr, "OFFLINE-PARSING");
121901 + flag = 0;
121902 + break;
121903 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
121904 + strcpy(arr, "HOST-COMMAND");
121905 + flag = 0;
121906 + break;
121907 + case (e_FM_PORT_TYPE_RX):
121908 + strcpy(arr, "RX");
121909 + flag = 1;
121910 + break;
121911 + case (e_FM_PORT_TYPE_RX_10G):
121912 + strcpy(arr, "RX-10G");
121913 + flag = 1;
121914 + break;
121915 + case (e_FM_PORT_TYPE_TX):
121916 + strcpy(arr, "TX");
121917 + flag = 2;
121918 + break;
121919 + case (e_FM_PORT_TYPE_TX_10G):
121920 + strcpy(arr, "TX-10G");
121921 + flag = 2;
121922 + break;
121923 + default:
121924 + return -EINVAL;
121925 + }
121926 +
121927 + FM_DMP_TITLE(buf, n, NULL,
121928 + "FMan-Port (%s #%d) registers:",
121929 + arr, p_FmPort->portId);
121930 +
121931 + FM_DMP_TITLE(buf, n, p_bmi, "Bmi Port Regs");
121932 +
121933 + switch (flag) {
121934 + case (0):
121935 + FM_DMP_SUBTITLE(buf, n, "\n");
121936 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocfg);
121937 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ost);
121938 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oda);
121939 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oicp);
121940 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdne);
121941 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofne);
121942 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofca);
121943 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofpne);
121944 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opso);
121945 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opp);
121946 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occb);
121947 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oim);
121948 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofp);
121949 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofed);
121950 +
121951 + FM_DMP_TITLE(buf, n,
121952 + &(p_bmi->ohPortBmiRegs.fmbm_oprai), "fmbm_oprai");
121953 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
121954 + FM_DMP_MEM_32(buf, n,
121955 + &(p_bmi->ohPortBmiRegs.fmbm_oprai[i]));
121956 + }
121957 + FM_DMP_SUBTITLE(buf, n, "\n");
121958 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofqid);
121959 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oefqid);
121960 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsdm);
121961 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsem);
121962 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofene);
121963 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmts);
121964 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmt);
121965 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocmne);
121966 + {
121967 +#ifndef FM_NO_OP_OBSERVED_POOLS
121968 + if (p_FmPort->fmRevInfo.majorRev == 4) {
121969 + FM_DMP_TITLE(buf, n,
121970 + &p_bmi->ohPortBmiRegs.fmbm_oebmpi,
121971 + "fmbm_oebmpi");
121972 +
121973 + for (i = 0; i < FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS; ++i) {
121974 + FM_DMP_MEM_32(buf, n,
121975 + &(p_bmi->ohPortBmiRegs.fmbm_oebmpi[i]));
121976 + }
121977 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocgm);
121978 + }
121979 +#endif /* !FM_NO_OP_OBSERVED_POOLS */
121980 + }
121981 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ostc);
121982 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofrc);
121983 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdc);
121984 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofledc);
121985 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofufdc);
121986 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_offc);
121987 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofwdc);
121988 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofldec);
121989 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opc);
121990 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opcp);
121991 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occn);
121992 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_otuc);
121993 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oduc);
121994 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofuc);
121995 + FM_DMP_TITLE(buf, n, &(p_bmi->ohPortBmiRegs.fmbm_odcfg),
121996 + "fmbm_odcfg");
121997 + for (i = 0; i < 3; ++i) {
121998 + FM_DMP_MEM_32(buf, n,
121999 + &(p_bmi->ohPortBmiRegs.fmbm_odcfg[i]));
122000 + }
122001 + FM_DMP_SUBTITLE(buf, n, "\n");
122002 +
122003 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ogpr);
122004 + break;
122005 + case (1):
122006 + FM_DMP_SUBTITLE(buf, n, "\n");
122007 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcfg);
122008 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rst);
122009 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rda);
122010 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfp);
122011 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_reth);
122012 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfed);
122013 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_ricp);
122014 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rebm);
122015 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfne);
122016 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfca);
122017 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfpne);
122018 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpso);
122019 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpp);
122020 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rprai),
122021 + "fmbm_rprai");
122022 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
122023 + FM_DMP_MEM_32(buf, n,
122024 + &(p_bmi->rxPortBmiRegs.fmbm_rprai[i]));
122025 + }
122026 + FM_DMP_SUBTITLE(buf, n, "\n");
122027 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfqid);
122028 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_refqid);
122029 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsdm);
122030 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsem);
122031 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfene);
122032 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcmne);
122033 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_ebmpi,
122034 + "fmbm_ebmpi");
122035 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
122036 + FM_DMP_MEM_32(buf, n,
122037 + &(p_bmi->rxPortBmiRegs.fmbm_ebmpi[i]));
122038 + }
122039 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_acnt,
122040 + "fmbm_acnt");
122041 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
122042 + FM_DMP_MEM_32(buf, n,
122043 + &(p_bmi->rxPortBmiRegs.fmbm_acnt[i]));
122044 + }
122045 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_rcgm,
122046 + "fmbm_rcgm");
122047 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS / 32; ++i) {
122048 + FM_DMP_MEM_32(buf, n,
122049 + &(p_bmi->rxPortBmiRegs.fmbm_rcgm[i]));
122050 + }
122051 +
122052 + FM_DMP_SUBTITLE(buf, n, "\n");
122053 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rmpd);
122054 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rstc);
122055 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfrc);
122056 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfbc);
122057 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rlfc);
122058 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rffc);
122059 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfcd);
122060 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfldec);
122061 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rodc);
122062 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpc);
122063 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpcp);
122064 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rccn);
122065 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rtuc);
122066 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rrquc);
122067 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rduc);
122068 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfuc);
122069 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpac);
122070 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rdcfg),
122071 + "fmbm_rdcfg");
122072 + for (i = 0; i < 3; ++i) {
122073 + FM_DMP_MEM_32(buf, n,
122074 + &(p_bmi->rxPortBmiRegs.fmbm_rdcfg[i]));
122075 + }
122076 + FM_DMP_SUBTITLE(buf, n, "\n");
122077 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rgpr);
122078 + break;
122079 + case (2):
122080 + FM_DMP_SUBTITLE(buf, n, "\n");
122081 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfg);
122082 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tst);
122083 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tda);
122084 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfp);
122085 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfed);
122086 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ticp);
122087 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdne);
122088 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfca);
122089 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfqid);
122090 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfeqid);
122091 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfene);
122092 +#if (DPAA_VERSION >= 11)
122093 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfne);
122094 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcmne);
122095 +#endif /* (DPAA_VERSION >= 11) */
122096 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmts);
122097 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmt);
122098 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tstc);
122099 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfrc);
122100 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdc);
122101 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfledc);
122102 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfufdc);
122103 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpc);
122104 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpcp);
122105 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tccn);
122106 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttuc);
122107 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttcquc);
122108 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tduc);
122109 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfuc);
122110 + FM_DMP_TITLE(buf, n, &(p_bmi->txPortBmiRegs.fmbm_tdcfg),
122111 + "fmbm_tdcfg");
122112 + for (i = 0; i < 3 ; ++i) {
122113 + FM_DMP_MEM_32(buf, n,
122114 + &(p_bmi->txPortBmiRegs.fmbm_tdcfg[i]));
122115 + }
122116 + FM_DMP_SUBTITLE(buf, n, "\n");
122117 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tgpr);
122118 + break;
122119 + }
122120 +
122121 + FM_DMP_SUBTITLE(buf, n, "\n");
122122 +
122123 + return n;
122124 +}
122125 +
122126 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int nn)
122127 +{
122128 + t_FmPort *p_FmPort;
122129 + int n = nn;
122130 +
122131 + p_FmPort = (t_FmPort *)h_dev;
122132 +
122133 + FM_DMP_TITLE(buf, n, p_FmPort->p_FmPortQmiRegs, "Qmi Port Regs");
122134 +
122135 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnc);
122136 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pns);
122137 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnts);
122138 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnen);
122139 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnetfc);
122140 + FM_DMP_V32(buf, n,
122141 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndn);
122142 + FM_DMP_V32(buf, n,
122143 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndc);
122144 + FM_DMP_V32(buf, n,
122145 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndtfc);
122146 + FM_DMP_V32(buf, n,
122147 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndfdc);
122148 + FM_DMP_V32(buf, n,
122149 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndcc);
122150 +
122151 + FM_DMP_SUBTITLE(buf, n, "\n");
122152 +
122153 + return n;
122154 +}
122155 +
122156 --- /dev/null
122157 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
122158 @@ -0,0 +1,56 @@
122159 +/*
122160 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122161 + *
122162 + * Redistribution and use in source and binary forms, with or without
122163 + * modification, are permitted provided that the following conditions are met:
122164 + * * Redistributions of source code must retain the above copyright
122165 + * notice, this list of conditions and the following disclaimer.
122166 + * * Redistributions in binary form must reproduce the above copyright
122167 + * notice, this list of conditions and the following disclaimer in the
122168 + * documentation and/or other materials provided with the distribution.
122169 + * * Neither the name of Freescale Semiconductor nor the
122170 + * names of its contributors may be used to endorse or promote products
122171 + * derived from this software without specific prior written permission.
122172 + *
122173 + *
122174 + * ALTERNATIVELY, this software may be distributed under the terms of the
122175 + * GNU General Public License ("GPL") as published by the Free Software
122176 + * Foundation, either version 2 of that License or (at your option) any
122177 + * later version.
122178 + *
122179 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122180 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122181 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122182 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122183 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122184 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122185 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122186 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122187 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122188 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122189 + */
122190 +
122191 +/*
122192 + @File lnxwrp_sysfs_fm_port.h
122193 +
122194 + @Description FM port sysfs functions.
122195 +
122196 +*/
122197 +
122198 +#ifndef LNXWRP_SYSFS_FM_PORT_H_
122199 +#define LNXWRP_SYSFS_FM_PORT_H_
122200 +
122201 +#include "lnxwrp_sysfs.h"
122202 +
122203 +int fm_port_sysfs_create(struct device *dev);
122204 +void fm_port_sysfs_destroy(struct device *dev);
122205 +
122206 +int fm_port_dump_regs(void *h_dev, char *buf, int n);
122207 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int n);
122208 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int n);
122209 +
122210 +#if (DPAA_VERSION >= 11)
122211 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int n);
122212 +#endif
122213 +
122214 +#endif /* LNXWRP_SYSFS_FM_PORT_H_ */
122215 --- /dev/null
122216 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
122217 @@ -0,0 +1,18 @@
122218 +#
122219 +# Makefile for the Freescale Ethernet controllers
122220 +#
122221 +ccflags-y += -DVERSION=\"\"
122222 +#
122223 +#Include netcomm SW specific definitions
122224 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
122225 +
122226 +obj-y += fsl-ncsw-xx.o
122227 +
122228 +ifneq ($(CONFIG_FMAN_ARM),y)
122229 +fsl-ncsw-xx-objs := xx_linux.o \
122230 + module_strings.o
122231 +else
122232 +fsl-ncsw-xx-objs := xx_arm_linux.o \
122233 + module_strings.o
122234 +endif
122235 +
122236 --- /dev/null
122237 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
122238 @@ -0,0 +1,46 @@
122239 +/*
122240 + * Copyright 2012 Freescale Semiconductor Inc.
122241 + *
122242 + * Redistribution and use in source and binary forms, with or without
122243 + * modification, are permitted provided that the following conditions are met:
122244 + * * Redistributions of source code must retain the above copyright
122245 + * notice, this list of conditions and the following disclaimer.
122246 + * * Redistributions in binary form must reproduce the above copyright
122247 + * notice, this list of conditions and the following disclaimer in the
122248 + * documentation and/or other materials provided with the distribution.
122249 + * * Neither the name of Freescale Semiconductor nor the
122250 + * names of its contributors may be used to endorse or promote products
122251 + * derived from this software without specific prior written permission.
122252 + *
122253 + *
122254 + * ALTERNATIVELY, this software may be distributed under the terms of the
122255 + * GNU General Public License ("GPL") as published by the Free Software
122256 + * Foundation, either version 2 of that License or (at your option) any
122257 + * later version.
122258 + *
122259 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122260 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122261 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122262 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122263 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122264 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122265 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122266 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122267 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122268 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122269 + */
122270 +
122271 +/* Module names for debug messages */
122272 +const char *moduleStrings[] =
122273 +{
122274 + "", /* MODULE_UNKNOWN */
122275 + "FM", /* MODULE_FM */
122276 + "FM-MURAM", /* MODULE_FM_MURAM */
122277 + "FM-PCD", /* MODULE_FM_PCD */
122278 + "FM-RTC", /* MODULE_FM_RTC */
122279 + "FM-MAC", /* MODULE_FM_MAC */
122280 + "FM-Port", /* MODULE_FM_PORT */
122281 + "MM", /* MODULE_MM */
122282 + "FM-SP", /* MODULE_FM_SP */
122283 + "FM-MACSEC" /* MODULE_FM_MACSEC */
122284 +};
122285 --- /dev/null
122286 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
122287 @@ -0,0 +1,905 @@
122288 +/*
122289 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122290 + *
122291 + * Redistribution and use in source and binary forms, with or without
122292 + * modification, are permitted provided that the following conditions are met:
122293 + * * Redistributions of source code must retain the above copyright
122294 + * notice, this list of conditions and the following disclaimer.
122295 + * * Redistributions in binary form must reproduce the above copyright
122296 + * notice, this list of conditions and the following disclaimer in the
122297 + * documentation and/or other materials provided with the distribution.
122298 + * * Neither the name of Freescale Semiconductor nor the
122299 + * names of its contributors may be used to endorse or promote products
122300 + * derived from this software without specific prior written permission.
122301 + *
122302 + *
122303 + * ALTERNATIVELY, this software may be distributed under the terms of the
122304 + * GNU General Public License ("GPL") as published by the Free Software
122305 + * Foundation, either version 2 of that License or (at your option) any
122306 + * later version.
122307 + *
122308 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122309 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122310 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122311 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122312 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122313 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122314 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122315 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122316 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122317 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122318 + */
122319 +
122320 +/**************************************************************************//**
122321 + @File xx_arm_linux.c
122322 +
122323 + @Description XX routines implementation for Linux.
122324 +*//***************************************************************************/
122325 +#include <linux/version.h>
122326 +
122327 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
122328 +#define MODVERSIONS
122329 +#endif
122330 +#ifdef MODVERSIONS
122331 +#include <config/modversions.h>
122332 +#endif /* MODVERSIONS */
122333 +
122334 +#include <linux/module.h>
122335 +#include <linux/kernel.h>
122336 +#include <linux/sched.h>
122337 +#include <linux/string.h>
122338 +#include <linux/ptrace.h>
122339 +#include <linux/errno.h>
122340 +#include <linux/ioport.h>
122341 +#include <linux/slab.h>
122342 +#include <linux/interrupt.h>
122343 +#include <linux/fs.h>
122344 +#include <linux/vmalloc.h>
122345 +#include <linux/init.h>
122346 +#include <linux/timer.h>
122347 +#include <linux/spinlock.h>
122348 +#include <linux/delay.h>
122349 +#include <linux/proc_fs.h>
122350 +#include <linux/smp.h>
122351 +#include <linux/of.h>
122352 +#include <linux/irqdomain.h>
122353 +
122354 +#include <linux/workqueue.h>
122355 +
122356 +#ifdef BIGPHYSAREA_ENABLE
122357 +#include <linux/bigphysarea.h>
122358 +#endif /* BIGPHYSAREA_ENABLE */
122359 +
122360 +//#include <sysdev/fsl_soc.h>
122361 +#include <asm/pgtable.h>
122362 +#include <asm/irq.h>
122363 +#include <asm/bitops.h>
122364 +#include <asm/uaccess.h>
122365 +#include <asm/io.h>
122366 +#include <asm/atomic.h>
122367 +#include <asm/string.h>
122368 +#include <asm/byteorder.h>
122369 +#include <asm/page.h>
122370 +
122371 +#include "error_ext.h"
122372 +#include "std_ext.h"
122373 +#include "list_ext.h"
122374 +#include "mm_ext.h"
122375 +#include "sys_io_ext.h"
122376 +#include "xx.h"
122377 +
122378 +
122379 +#define __ERR_MODULE__ MODULE_UNKNOWN
122380 +
122381 +#ifdef BIGPHYSAREA_ENABLE
122382 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
122383 +
122384 +
122385 +/* TODO: large allocations => use big phys area */
122386 +/******************************************************************************
122387 + * routine: get_nr_pages
122388 + *
122389 + * description:
122390 + * calculates the number of memory pages for a given size (in bytes)
122391 + *
122392 + * arguments:
122393 + * size - the number of bytes
122394 + *
122395 + * return code:
122396 + * The number of pages
122397 + *
122398 + *****************************************************************************/
122399 +static __inline__ uint32_t get_nr_pages (uint32_t size)
122400 +{
122401 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
122402 +}
122403 +
122404 +static bool in_big_phys_area (uint32_t addr)
122405 +{
122406 + uint32_t base, size;
122407 +
122408 + bigphysarea_get_details (&base, &size);
122409 + return ((addr >= base) && (addr < base + size));
122410 +}
122411 +#endif /* BIGPHYSAREA_ENABLE */
122412 +
122413 +void * xx_Malloc(uint32_t n)
122414 +{
122415 + void *a;
122416 + uint32_t flags;
122417 +
122418 + flags = XX_DisableAllIntr();
122419 +#ifdef BIGPHYSAREA_ENABLE
122420 + if (n >= MAX_ALLOCATION_SIZE)
122421 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
122422 + else
122423 +#endif /* BIGPHYSAREA_ENABLE */
122424 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
122425 + if (!a)
122426 + XX_Print("No memory for XX_Malloc\n");
122427 + XX_RestoreAllIntr(flags);
122428 +
122429 + return a;
122430 +}
122431 +
122432 +void xx_Free(void *p)
122433 +{
122434 +#ifdef BIGPHYSAREA_ENABLE
122435 + if (in_big_phys_area ((uint32_t)p))
122436 + bigphysarea_free_pages(p);
122437 + else
122438 +#endif /* BIGPHYSAREA_ENABLE */
122439 + kfree(p);
122440 +}
122441 +
122442 +void XX_Exit(int status)
122443 +{
122444 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
122445 +}
122446 +
122447 +#define BUF_SIZE 512
122448 +void XX_Print(char *str, ...)
122449 +{
122450 + va_list args;
122451 +#ifdef CONFIG_SMP
122452 + char buf[BUF_SIZE];
122453 +#endif /* CONFIG_SMP */
122454 +
122455 + va_start(args, str);
122456 +#ifdef CONFIG_SMP
122457 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
122458 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
122459 + printk(KERN_CRIT "cpu %d: %s", raw_smp_processor_id(), buf);
122460 +#else
122461 + vprintk(str, args);
122462 +#endif /* CONFIG_SMP */
122463 + va_end(args);
122464 +}
122465 +
122466 +void XX_Fprint(void *file, char *str, ...)
122467 +{
122468 + va_list args;
122469 +#ifdef CONFIG_SMP
122470 + char buf[BUF_SIZE];
122471 +#endif /* CONFIG_SMP */
122472 +
122473 + va_start(args, str);
122474 +#ifdef CONFIG_SMP
122475 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
122476 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
122477 + printk (KERN_CRIT "cpu %d: %s", smp_processor_id(), buf);
122478 +
122479 +#else
122480 + vprintk(str, args);
122481 +#endif /* CONFIG_SMP */
122482 + va_end(args);
122483 +}
122484 +
122485 +#ifdef DEBUG_XX_MALLOC
122486 +typedef void (*t_ffn)(void *);
122487 +typedef struct {
122488 + t_ffn f_free;
122489 + void *mem;
122490 + char *fname;
122491 + int fline;
122492 + uint32_t size;
122493 + t_List node;
122494 +} t_MemDebug;
122495 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
122496 +
122497 +LIST(memDbgLst);
122498 +
122499 +
122500 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
122501 +{
122502 + void *mem;
122503 + t_MemDebug *p_MemDbg;
122504 +
122505 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
122506 + if (p_MemDbg == NULL)
122507 + return NULL;
122508 +
122509 + mem = xx_Malloc(size);
122510 + if (mem == NULL)
122511 + {
122512 + XX_Free(p_MemDbg);
122513 + return NULL;
122514 + }
122515 +
122516 + INIT_LIST(&p_MemDbg->node);
122517 + p_MemDbg->f_free = xx_Free;
122518 + p_MemDbg->mem = mem;
122519 + p_MemDbg->fname = fname;
122520 + p_MemDbg->fline = line;
122521 + p_MemDbg->size = size+sizeof(t_MemDebug);
122522 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
122523 +
122524 + return mem;
122525 +}
122526 +
122527 +void * XX_MallocSmartDebug(uint32_t size,
122528 + int memPartitionId,
122529 + uint32_t align,
122530 + char *fname,
122531 + int line)
122532 +{
122533 + void *mem;
122534 + t_MemDebug *p_MemDbg;
122535 +
122536 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
122537 + if (p_MemDbg == NULL)
122538 + return NULL;
122539 +
122540 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
122541 + if (mem == NULL)
122542 + {
122543 + XX_Free(p_MemDbg);
122544 + return NULL;
122545 + }
122546 +
122547 + INIT_LIST(&p_MemDbg->node);
122548 + p_MemDbg->f_free = xx_FreeSmart;
122549 + p_MemDbg->mem = mem;
122550 + p_MemDbg->fname = fname;
122551 + p_MemDbg->fline = line;
122552 + p_MemDbg->size = size+sizeof(t_MemDebug);
122553 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
122554 +
122555 + return mem;
122556 +}
122557 +
122558 +static void debug_free(void *mem)
122559 +{
122560 + t_List *p_MemDbgLh = NULL;
122561 + t_MemDebug *p_MemDbg;
122562 + bool found = FALSE;
122563 +
122564 + if (LIST_IsEmpty(&memDbgLst))
122565 + {
122566 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
122567 + return;
122568 + }
122569 +
122570 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
122571 + {
122572 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
122573 + if (p_MemDbg->mem == mem)
122574 + {
122575 + found = TRUE;
122576 + break;
122577 + }
122578 + }
122579 +
122580 + if (!found)
122581 + {
122582 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
122583 + ("Attempt to free unallocated address (0x%08x)",mem));
122584 + dump_stack();
122585 + return;
122586 + }
122587 +
122588 + LIST_Del(p_MemDbgLh);
122589 + p_MemDbg->f_free(mem);
122590 + p_MemDbg->f_free(p_MemDbg);
122591 +}
122592 +
122593 +void XX_FreeSmart(void *p)
122594 +{
122595 + debug_free(p);
122596 +}
122597 +
122598 +
122599 +void XX_Free(void *p)
122600 +{
122601 + debug_free(p);
122602 +}
122603 +
122604 +#else /* not DEBUG_XX_MALLOC */
122605 +void * XX_Malloc(uint32_t size)
122606 +{
122607 + return xx_Malloc(size);
122608 +}
122609 +
122610 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
122611 +{
122612 + return xx_MallocSmart(size,memPartitionId, alignment);
122613 +}
122614 +
122615 +void XX_FreeSmart(void *p)
122616 +{
122617 + xx_FreeSmart(p);
122618 +}
122619 +
122620 +
122621 +void XX_Free(void *p)
122622 +{
122623 + xx_Free(p);
122624 +}
122625 +#endif /* not DEBUG_XX_MALLOC */
122626 +
122627 +
122628 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
122629 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
122630 +{
122631 + e_Event eventCode = (e_Event)event;
122632 +
122633 + UNUSED(eventCode);
122634 + UNUSED(appId);
122635 + UNUSED(flags);
122636 + UNUSED(msg);
122637 +}
122638 +#endif /* (defined(REPORT_EVENTS) && ... */
122639 +
122640 +
122641 +uint32_t XX_DisableAllIntr(void)
122642 +{
122643 + unsigned long flags;
122644 +
122645 +#ifdef local_irq_save_nort
122646 + local_irq_save_nort(flags);
122647 +#else
122648 + local_irq_save(flags);
122649 +#endif
122650 +
122651 + return (uint32_t)flags;
122652 +}
122653 +
122654 +void XX_RestoreAllIntr(uint32_t flags)
122655 +{
122656 +#ifdef local_irq_restore_nort
122657 + local_irq_restore_nort((unsigned long)flags);
122658 +#else
122659 + local_irq_restore((unsigned long)flags);
122660 +#endif
122661 +}
122662 +
122663 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
122664 +{
122665 + UNUSED(qid);
122666 + UNUSED(appId);
122667 + UNUSED(flags);
122668 +
122669 + return f(id);
122670 +}
122671 +
122672 +int XX_IsICacheEnable(void)
122673 +{
122674 + return TRUE;
122675 +}
122676 +
122677 +int XX_IsDCacheEnable(void)
122678 +{
122679 + return TRUE;
122680 +}
122681 +
122682 +
122683 +typedef struct {
122684 + t_Isr *f_Isr;
122685 + t_Handle handle;
122686 +} t_InterruptHandler;
122687 +
122688 +
122689 +t_Handle interruptHandlers[0x00010000];
122690 +
122691 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
122692 +{
122693 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
122694 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
122695 + return IRQ_HANDLED;
122696 +}
122697 +
122698 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
122699 +{
122700 + const char *device;
122701 + t_InterruptHandler *p_IntrHndl;
122702 +
122703 + device = GetDeviceName(irq);
122704 + if (device == NULL)
122705 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
122706 +
122707 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
122708 + if (p_IntrHndl == NULL)
122709 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
122710 + p_IntrHndl->f_Isr = f_Isr;
122711 + p_IntrHndl->handle = handle;
122712 + interruptHandlers[irq] = p_IntrHndl;
122713 +
122714 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
122715 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
122716 + disable_irq(GetDeviceIrqNum(irq));
122717 +
122718 + return E_OK;
122719 +}
122720 +
122721 +t_Error XX_FreeIntr(int irq)
122722 +{
122723 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
122724 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
122725 + XX_Free(p_IntrHndl);
122726 + interruptHandlers[irq] = 0;
122727 + return E_OK;
122728 +}
122729 +
122730 +t_Error XX_EnableIntr(int irq)
122731 +{
122732 + enable_irq(GetDeviceIrqNum(irq));
122733 + return E_OK;
122734 +}
122735 +
122736 +t_Error XX_DisableIntr(int irq)
122737 +{
122738 + disable_irq(GetDeviceIrqNum(irq));
122739 + return E_OK;
122740 +}
122741 +
122742 +
122743 +/*****************************************************************************/
122744 +/* Tasklet Service Routines */
122745 +/*****************************************************************************/
122746 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
122747 +typedef struct
122748 +{
122749 + t_Handle h_Data;
122750 + void (*f_Callback) (void *);
122751 + struct delayed_work dwork;
122752 +} t_Tasklet;
122753 +
122754 +static void GenericTaskletCallback(struct work_struct *p_Work)
122755 +{
122756 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
122757 +
122758 + p_Task->f_Callback(p_Task->h_Data);
122759 +}
122760 +#endif /* LINUX_VERSION_CODE */
122761 +
122762 +
122763 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
122764 +{
122765 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122766 + struct work_struct *p_Task;
122767 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
122768 + INIT_WORK(p_Task, routine, data);
122769 +#else
122770 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
122771 + p_Task->h_Data = data;
122772 + p_Task->f_Callback = routine;
122773 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
122774 +#endif /* LINUX_VERSION_CODE */
122775 +
122776 + return (t_TaskletHandle)p_Task;
122777 +}
122778 +
122779 +
122780 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
122781 +{
122782 + if (h_Tasklet)
122783 + XX_Free(h_Tasklet);
122784 +}
122785 +
122786 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
122787 +{
122788 + int ans;
122789 +
122790 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122791 + if (immediate)
122792 + ans = schedule_work(h_Tasklet);
122793 + else
122794 + ans = schedule_delayed_work(h_Tasklet, 1);
122795 +#else
122796 + if (immediate)
122797 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
122798 + else
122799 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
122800 +#endif /* LINUX_VERSION_CODE */
122801 +
122802 + return ans;
122803 +}
122804 +
122805 +void XX_FlushScheduledTasks(void)
122806 +{
122807 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
122808 + flush_scheduled_tasks();
122809 +#else
122810 + flush_scheduled_work();
122811 +#endif /* LINUX_VERSION_CODE */
122812 +}
122813 +
122814 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
122815 +{
122816 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122817 + return (int)(((struct work_struct *)h_Tasklet)->pending);
122818 +#else
122819 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
122820 +#endif /* LINUX_VERSION_CODE */
122821 +}
122822 +
122823 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
122824 +{
122825 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
122826 + ((struct tq_struct *)h_Tasklet)->data = data;
122827 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122828 + ((struct work_struct *)h_Tasklet)->data = data;
122829 +#else
122830 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
122831 +#endif /* LINUX_VERSION_CODE */
122832 +}
122833 +
122834 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
122835 +{
122836 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122837 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
122838 +#else
122839 + return ((t_Tasklet *)h_Tasklet)->h_Data;
122840 +#endif /* LINUX_VERSION_CODE */
122841 +}
122842 +
122843 +
122844 +/*****************************************************************************/
122845 +/* Spinlock Service Routines */
122846 +/*****************************************************************************/
122847 +
122848 +t_Handle XX_InitSpinlock(void)
122849 +{
122850 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
122851 + if (!p_Spinlock)
122852 + return NULL;
122853 +
122854 + spin_lock_init(p_Spinlock);
122855 +
122856 + return (t_Handle)p_Spinlock;
122857 +}
122858 +
122859 +void XX_FreeSpinlock(t_Handle h_Spinlock)
122860 +{
122861 + if (h_Spinlock)
122862 + XX_Free(h_Spinlock);
122863 +}
122864 +
122865 +void XX_LockSpinlock(t_Handle h_Spinlock)
122866 +{
122867 + spin_lock((spinlock_t *)h_Spinlock);
122868 +}
122869 +
122870 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
122871 +{
122872 + spin_unlock((spinlock_t *)h_Spinlock);
122873 +}
122874 +
122875 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
122876 +{
122877 + unsigned long intrFlags;
122878 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
122879 + return intrFlags;
122880 +}
122881 +
122882 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
122883 +{
122884 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
122885 +}
122886 +
122887 +
122888 +/*****************************************************************************/
122889 +/* Timers Service Routines */
122890 +/*****************************************************************************/
122891 +/* The time now is in mili sec. resolution */
122892 +uint32_t XX_CurrentTime(void)
122893 +{
122894 + return (jiffies*1000)/HZ;
122895 +}
122896 +
122897 +
122898 +t_Handle XX_CreateTimer(void)
122899 +{
122900 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
122901 + if (p_Timer)
122902 + {
122903 + memset(p_Timer, 0, sizeof(struct timer_list));
122904 + init_timer(p_Timer);
122905 + }
122906 + return (t_Handle)p_Timer;
122907 +}
122908 +
122909 +void XX_FreeTimer(t_Handle h_Timer)
122910 +{
122911 + if (h_Timer)
122912 + XX_Free(h_Timer);
122913 +}
122914 +
122915 +void XX_StartTimer(t_Handle h_Timer,
122916 + uint32_t msecs,
122917 + bool periodic,
122918 + void (*f_TimerExpired)(t_Handle),
122919 + t_Handle h_Arg)
122920 +{
122921 + int tmp_jiffies = (msecs*HZ)/1000;
122922 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122923 +
122924 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
122925 +
122926 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
122927 + p_Timer->data = (unsigned long)h_Arg;
122928 + if ((msecs*HZ)%1000)
122929 + tmp_jiffies++;
122930 + p_Timer->expires = (jiffies + tmp_jiffies);
122931 +
122932 + add_timer((struct timer_list *)h_Timer);
122933 +}
122934 +
122935 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
122936 +{
122937 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122938 +
122939 + p_Timer->data = (unsigned long)data;
122940 +}
122941 +
122942 +t_Handle XX_GetTimerData(t_Handle h_Timer)
122943 +{
122944 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122945 +
122946 + return (t_Handle)p_Timer->data;
122947 +}
122948 +
122949 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
122950 +{
122951 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122952 +
122953 + return (uint32_t)p_Timer->expires;
122954 +}
122955 +
122956 +void XX_StopTimer(t_Handle h_Timer)
122957 +{
122958 + del_timer((struct timer_list *)h_Timer);
122959 +}
122960 +
122961 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
122962 +{
122963 + int tmp_jiffies = (msecs*HZ)/1000;
122964 +
122965 + if ((msecs*HZ)%1000)
122966 + tmp_jiffies++;
122967 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
122968 +}
122969 +
122970 +int XX_TimerIsActive(t_Handle h_Timer)
122971 +{
122972 + return timer_pending((struct timer_list *)h_Timer);
122973 +}
122974 +
122975 +uint32_t XX_Sleep(uint32_t msecs)
122976 +{
122977 + int tmp_jiffies = (msecs*HZ)/1000;
122978 +
122979 + if ((msecs*HZ)%1000)
122980 + tmp_jiffies++;
122981 + return schedule_timeout(tmp_jiffies);
122982 +}
122983 +
122984 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
122985 +void XX_UDelay(uint32_t usecs)
122986 +{
122987 + udelay(usecs);
122988 +}
122989 +
122990 +/* TODO: verify that these are correct */
122991 +#define MSG_BODY_SIZE 512
122992 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
122993 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
122994 +t_Error XX_SendMessage(char *p_DestAddr,
122995 + uint32_t msgId,
122996 + uint8_t msgBody[MSG_BODY_SIZE],
122997 + t_MsgCompletionCB *f_CompletionCB,
122998 + t_Handle h_CBArg);
122999 +
123000 +typedef struct {
123001 + char *p_Addr;
123002 + t_MsgHandler *f_MsgHandlerCB;
123003 + t_Handle h_Mod;
123004 + t_List node;
123005 +} t_MsgHndlr;
123006 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
123007 +
123008 +LIST(msgHndlrList);
123009 +
123010 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
123011 +{
123012 + uint32_t intFlags;
123013 +
123014 + intFlags = XX_DisableAllIntr();
123015 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
123016 + XX_RestoreAllIntr(intFlags);
123017 +}
123018 +/* TODO: add this for multi-platform support
123019 +static t_MsgHndlr * DequeueMsgHndlr(void)
123020 +{
123021 + t_MsgHndlr *p_MsgHndlr = NULL;
123022 + uint32_t intFlags;
123023 +
123024 + intFlags = XX_DisableAllIntr();
123025 + if (!LIST_IsEmpty(&msgHndlrList))
123026 + {
123027 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
123028 + LIST_DelAndInit(&p_MsgHndlr->node);
123029 + }
123030 + XX_RestoreAllIntr(intFlags);
123031 +
123032 + return p_MsgHndlr;
123033 +}
123034 +*/
123035 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
123036 +{
123037 + t_MsgHndlr *p_MsgHndlr;
123038 + t_List *p_Pos;
123039 +
123040 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
123041 + {
123042 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
123043 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
123044 + return p_MsgHndlr;
123045 + }
123046 +
123047 + return NULL;
123048 +}
123049 +
123050 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
123051 +{
123052 + t_MsgHndlr *p_MsgHndlr;
123053 + uint32_t len;
123054 +
123055 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
123056 + if (!p_MsgHndlr)
123057 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
123058 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
123059 +
123060 + len = strlen(p_Addr);
123061 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
123062 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
123063 +
123064 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
123065 + p_MsgHndlr->h_Mod = h_Mod;
123066 + INIT_LIST(&p_MsgHndlr->node);
123067 + EnqueueMsgHndlr(p_MsgHndlr);
123068 +
123069 + return E_OK;
123070 +}
123071 +
123072 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
123073 +{
123074 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
123075 + if (!p_MsgHndlr)
123076 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123077 +
123078 + LIST_Del(&p_MsgHndlr->node);
123079 + XX_Free(p_MsgHndlr->p_Addr);
123080 + XX_Free(p_MsgHndlr);
123081 +
123082 + return E_OK;
123083 +}
123084 +
123085 +t_Error XX_SendMessage(char *p_DestAddr,
123086 + uint32_t msgId,
123087 + uint8_t msgBody[MSG_BODY_SIZE],
123088 + t_MsgCompletionCB *f_CompletionCB,
123089 + t_Handle h_CBArg)
123090 +{
123091 + t_Error ans;
123092 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
123093 + if (!p_MsgHndlr)
123094 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123095 +
123096 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
123097 +
123098 + if (f_CompletionCB)
123099 + f_CompletionCB(h_CBArg, msgBody);
123100 +
123101 + return ans;
123102 +}
123103 +
123104 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123105 + t_IpcMsgHandler *f_MsgHandler,
123106 + t_Handle h_Module,
123107 + uint32_t replyLength)
123108 +{
123109 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
123110 + return E_OK;
123111 +}
123112 +
123113 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123114 +{
123115 + UNUSED(addr);
123116 + return E_OK;
123117 +}
123118 +
123119 +
123120 +t_Error XX_IpcSendMessage(t_Handle h_Session,
123121 + uint8_t *p_Msg,
123122 + uint32_t msgLength,
123123 + uint8_t *p_Reply,
123124 + uint32_t *p_ReplyLength,
123125 + t_IpcMsgCompletion *f_Completion,
123126 + t_Handle h_Arg)
123127 +{
123128 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
123129 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
123130 + return E_OK;
123131 +}
123132 +
123133 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123134 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123135 +{
123136 + UNUSED(destAddr); UNUSED(srcAddr);
123137 + return E_OK;
123138 +}
123139 +
123140 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
123141 +int GetDeviceIrqNum(int irq)
123142 +{
123143 + struct device_node *iPar;
123144 + struct irq_domain *irqHost;
123145 + uint32_t hwIrq;
123146 +
123147 + /* Get the interrupt controller */
123148 + iPar = of_find_node_by_name(NULL, "mpic");
123149 + hwIrq = 0;
123150 +
123151 + ASSERT_COND(iPar != NULL);
123152 + /* Get the irq host */
123153 + irqHost = irq_find_host(iPar);
123154 + of_node_put(iPar);
123155 +
123156 + /* Create irq mapping */
123157 + return irq_create_mapping(irqHost, hwIrq);
123158 +}
123159 +#else
123160 +#error "kernel not supported!!!"
123161 +#endif /* LINUX_VERSION_CODE */
123162 +
123163 +void * XX_PhysToVirt(physAddress_t addr)
123164 +{
123165 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
123166 +}
123167 +
123168 +physAddress_t XX_VirtToPhys(void * addr)
123169 +{
123170 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
123171 +}
123172 +
123173 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123174 +{
123175 + uintptr_t *returnCode, tmp;
123176 +
123177 + if (alignment < sizeof(uintptr_t))
123178 + alignment = sizeof(uintptr_t);
123179 + size += alignment + sizeof(returnCode);
123180 + tmp = (uintptr_t)xx_Malloc(size);
123181 + if (tmp == 0)
123182 + return NULL;
123183 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
123184 + *(returnCode - 1) = tmp;
123185 +
123186 + return (void*)returnCode;
123187 +}
123188 +
123189 +void xx_FreeSmart(void *p)
123190 +{
123191 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
123192 +}
123193 --- /dev/null
123194 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
123195 @@ -0,0 +1,918 @@
123196 +/*
123197 + * Copyright 2008-2012 Freescale Semiconductor Inc.
123198 + *
123199 + * Redistribution and use in source and binary forms, with or without
123200 + * modification, are permitted provided that the following conditions are met:
123201 + * * Redistributions of source code must retain the above copyright
123202 + * notice, this list of conditions and the following disclaimer.
123203 + * * Redistributions in binary form must reproduce the above copyright
123204 + * notice, this list of conditions and the following disclaimer in the
123205 + * documentation and/or other materials provided with the distribution.
123206 + * * Neither the name of Freescale Semiconductor nor the
123207 + * names of its contributors may be used to endorse or promote products
123208 + * derived from this software without specific prior written permission.
123209 + *
123210 + *
123211 + * ALTERNATIVELY, this software may be distributed under the terms of the
123212 + * GNU General Public License ("GPL") as published by the Free Software
123213 + * Foundation, either version 2 of that License or (at your option) any
123214 + * later version.
123215 + *
123216 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
123217 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
123218 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
123219 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
123220 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
123221 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
123222 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
123223 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
123224 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
123225 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
123226 + */
123227 +
123228 +/**************************************************************************//**
123229 + @File xx_linux.c
123230 +
123231 + @Description XX routines implementation for Linux.
123232 +*//***************************************************************************/
123233 +#include <linux/version.h>
123234 +
123235 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
123236 +#define MODVERSIONS
123237 +#endif
123238 +#ifdef MODVERSIONS
123239 +#include <config/modversions.h>
123240 +#endif /* MODVERSIONS */
123241 +
123242 +#include <linux/module.h>
123243 +#include <linux/kernel.h>
123244 +#include <linux/sched.h>
123245 +#include <linux/string.h>
123246 +#include <linux/ptrace.h>
123247 +#include <linux/errno.h>
123248 +#include <linux/ioport.h>
123249 +#include <linux/slab.h>
123250 +#include <linux/interrupt.h>
123251 +#include <linux/fs.h>
123252 +#include <linux/vmalloc.h>
123253 +#include <linux/init.h>
123254 +#include <linux/timer.h>
123255 +#include <linux/spinlock.h>
123256 +#include <linux/delay.h>
123257 +#include <linux/proc_fs.h>
123258 +#include <linux/smp.h>
123259 +#include <linux/of.h>
123260 +#ifdef CONFIG_FMAN_ARM
123261 +#include <linux/irqdomain.h>
123262 +#endif
123263 +
123264 +#include <linux/workqueue.h>
123265 +
123266 +#ifdef BIGPHYSAREA_ENABLE
123267 +#include <linux/bigphysarea.h>
123268 +#endif /* BIGPHYSAREA_ENABLE */
123269 +
123270 +#ifndef CONFIG_FMAN_ARM
123271 +#include <sysdev/fsl_soc.h>
123272 +#endif
123273 +#include <asm/pgtable.h>
123274 +#include <asm/irq.h>
123275 +#include <asm/bitops.h>
123276 +#include <asm/uaccess.h>
123277 +#include <asm/io.h>
123278 +#include <asm/atomic.h>
123279 +#include <asm/string.h>
123280 +#include <asm/byteorder.h>
123281 +#include <asm/page.h>
123282 +
123283 +#include "error_ext.h"
123284 +#include "std_ext.h"
123285 +#include "list_ext.h"
123286 +#include "mm_ext.h"
123287 +#include "sys_io_ext.h"
123288 +#include "xx.h"
123289 +
123290 +
123291 +#define __ERR_MODULE__ MODULE_UNKNOWN
123292 +
123293 +#ifdef BIGPHYSAREA_ENABLE
123294 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
123295 +
123296 +
123297 +/* TODO: large allocations => use big phys area */
123298 +/******************************************************************************
123299 + * routine: get_nr_pages
123300 + *
123301 + * description:
123302 + * calculates the number of memory pages for a given size (in bytes)
123303 + *
123304 + * arguments:
123305 + * size - the number of bytes
123306 + *
123307 + * return code:
123308 + * The number of pages
123309 + *
123310 + *****************************************************************************/
123311 +static __inline__ uint32_t get_nr_pages (uint32_t size)
123312 +{
123313 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
123314 +}
123315 +
123316 +static bool in_big_phys_area (uint32_t addr)
123317 +{
123318 + uint32_t base, size;
123319 +
123320 + bigphysarea_get_details (&base, &size);
123321 + return ((addr >= base) && (addr < base + size));
123322 +}
123323 +#endif /* BIGPHYSAREA_ENABLE */
123324 +
123325 +void * xx_Malloc(uint32_t n)
123326 +{
123327 + void *a;
123328 + uint32_t flags;
123329 +
123330 + flags = XX_DisableAllIntr();
123331 +#ifdef BIGPHYSAREA_ENABLE
123332 + if (n >= MAX_ALLOCATION_SIZE)
123333 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
123334 + else
123335 +#endif /* BIGPHYSAREA_ENABLE */
123336 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
123337 + if (!a)
123338 + XX_Print("No memory for XX_Malloc\n");
123339 + XX_RestoreAllIntr(flags);
123340 +
123341 + return a;
123342 +}
123343 +
123344 +void xx_Free(void *p)
123345 +{
123346 +#ifdef BIGPHYSAREA_ENABLE
123347 + if (in_big_phys_area ((uint32_t)p))
123348 + bigphysarea_free_pages(p);
123349 + else
123350 +#endif /* BIGPHYSAREA_ENABLE */
123351 + kfree(p);
123352 +}
123353 +
123354 +void XX_Exit(int status)
123355 +{
123356 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
123357 +}
123358 +
123359 +#define BUF_SIZE 512
123360 +void XX_Print(char *str, ...)
123361 +{
123362 + va_list args;
123363 +#ifdef CONFIG_SMP
123364 + char buf[BUF_SIZE];
123365 +#endif /* CONFIG_SMP */
123366 +
123367 + va_start(args, str);
123368 +#ifdef CONFIG_SMP
123369 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123370 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123371 + printk(KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
123372 +#else
123373 + vprintk(str, args);
123374 +#endif /* CONFIG_SMP */
123375 + va_end(args);
123376 +}
123377 +
123378 +void XX_Fprint(void *file, char *str, ...)
123379 +{
123380 + va_list args;
123381 +#ifdef CONFIG_SMP
123382 + char buf[BUF_SIZE];
123383 +#endif /* CONFIG_SMP */
123384 +
123385 + va_start(args, str);
123386 +#ifdef CONFIG_SMP
123387 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123388 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123389 + printk (KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
123390 +
123391 +#else
123392 + vprintk(str, args);
123393 +#endif /* CONFIG_SMP */
123394 + va_end(args);
123395 +}
123396 +
123397 +#ifdef DEBUG_XX_MALLOC
123398 +typedef void (*t_ffn)(void *);
123399 +typedef struct {
123400 + t_ffn f_free;
123401 + void *mem;
123402 + char *fname;
123403 + int fline;
123404 + uint32_t size;
123405 + t_List node;
123406 +} t_MemDebug;
123407 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
123408 +
123409 +LIST(memDbgLst);
123410 +
123411 +
123412 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
123413 +{
123414 + void *mem;
123415 + t_MemDebug *p_MemDbg;
123416 +
123417 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
123418 + if (p_MemDbg == NULL)
123419 + return NULL;
123420 +
123421 + mem = xx_Malloc(size);
123422 + if (mem == NULL)
123423 + {
123424 + XX_Free(p_MemDbg);
123425 + return NULL;
123426 + }
123427 +
123428 + INIT_LIST(&p_MemDbg->node);
123429 + p_MemDbg->f_free = xx_Free;
123430 + p_MemDbg->mem = mem;
123431 + p_MemDbg->fname = fname;
123432 + p_MemDbg->fline = line;
123433 + p_MemDbg->size = size+sizeof(t_MemDebug);
123434 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123435 +
123436 + return mem;
123437 +}
123438 +
123439 +void * XX_MallocSmartDebug(uint32_t size,
123440 + int memPartitionId,
123441 + uint32_t align,
123442 + char *fname,
123443 + int line)
123444 +{
123445 + void *mem;
123446 + t_MemDebug *p_MemDbg;
123447 +
123448 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
123449 + if (p_MemDbg == NULL)
123450 + return NULL;
123451 +
123452 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
123453 + if (mem == NULL)
123454 + {
123455 + XX_Free(p_MemDbg);
123456 + return NULL;
123457 + }
123458 +
123459 + INIT_LIST(&p_MemDbg->node);
123460 + p_MemDbg->f_free = xx_FreeSmart;
123461 + p_MemDbg->mem = mem;
123462 + p_MemDbg->fname = fname;
123463 + p_MemDbg->fline = line;
123464 + p_MemDbg->size = size+sizeof(t_MemDebug);
123465 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123466 +
123467 + return mem;
123468 +}
123469 +
123470 +static void debug_free(void *mem)
123471 +{
123472 + t_List *p_MemDbgLh = NULL;
123473 + t_MemDebug *p_MemDbg;
123474 + bool found = FALSE;
123475 +
123476 + if (LIST_IsEmpty(&memDbgLst))
123477 + {
123478 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
123479 + return;
123480 + }
123481 +
123482 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
123483 + {
123484 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
123485 + if (p_MemDbg->mem == mem)
123486 + {
123487 + found = TRUE;
123488 + break;
123489 + }
123490 + }
123491 +
123492 + if (!found)
123493 + {
123494 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
123495 + ("Attempt to free unallocated address (0x%08x)",mem));
123496 + dump_stack();
123497 + return;
123498 + }
123499 +
123500 + LIST_Del(p_MemDbgLh);
123501 + p_MemDbg->f_free(mem);
123502 + p_MemDbg->f_free(p_MemDbg);
123503 +}
123504 +
123505 +void XX_FreeSmart(void *p)
123506 +{
123507 + debug_free(p);
123508 +}
123509 +
123510 +
123511 +void XX_Free(void *p)
123512 +{
123513 + debug_free(p);
123514 +}
123515 +
123516 +#else /* not DEBUG_XX_MALLOC */
123517 +void * XX_Malloc(uint32_t size)
123518 +{
123519 + return xx_Malloc(size);
123520 +}
123521 +
123522 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123523 +{
123524 + return xx_MallocSmart(size,memPartitionId, alignment);
123525 +}
123526 +
123527 +void XX_FreeSmart(void *p)
123528 +{
123529 + xx_FreeSmart(p);
123530 +}
123531 +
123532 +
123533 +void XX_Free(void *p)
123534 +{
123535 + xx_Free(p);
123536 +}
123537 +#endif /* not DEBUG_XX_MALLOC */
123538 +
123539 +
123540 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
123541 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
123542 +{
123543 + e_Event eventCode = (e_Event)event;
123544 +
123545 + UNUSED(eventCode);
123546 + UNUSED(appId);
123547 + UNUSED(flags);
123548 + UNUSED(msg);
123549 +}
123550 +#endif /* (defined(REPORT_EVENTS) && ... */
123551 +
123552 +
123553 +uint32_t XX_DisableAllIntr(void)
123554 +{
123555 + unsigned long flags;
123556 +
123557 +#ifdef local_irq_save_nort
123558 + local_irq_save_nort(flags);
123559 +#else
123560 + local_irq_save(flags);
123561 +#endif
123562 +
123563 + return (uint32_t)flags;
123564 +}
123565 +
123566 +void XX_RestoreAllIntr(uint32_t flags)
123567 +{
123568 +#ifdef local_irq_restore_nort
123569 + local_irq_restore_nort((unsigned long)flags);
123570 +#else
123571 + local_irq_restore((unsigned long)flags);
123572 +#endif
123573 +}
123574 +
123575 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
123576 +{
123577 + UNUSED(qid);
123578 + UNUSED(appId);
123579 + UNUSED(flags);
123580 +
123581 + return f(id);
123582 +}
123583 +
123584 +int XX_IsICacheEnable(void)
123585 +{
123586 + return TRUE;
123587 +}
123588 +
123589 +int XX_IsDCacheEnable(void)
123590 +{
123591 + return TRUE;
123592 +}
123593 +
123594 +
123595 +typedef struct {
123596 + t_Isr *f_Isr;
123597 + t_Handle handle;
123598 +} t_InterruptHandler;
123599 +
123600 +
123601 +t_Handle interruptHandlers[0x00010000];
123602 +
123603 +#ifdef CONFIG_FMAN_ARM
123604 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
123605 +{
123606 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
123607 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
123608 + return IRQ_HANDLED;
123609 +}
123610 +#endif
123611 +
123612 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
123613 +{
123614 +#ifdef CONFIG_FMAN_ARM
123615 + const char *device;
123616 + t_InterruptHandler *p_IntrHndl;
123617 +
123618 + device = GetDeviceName(irq);
123619 + if (device == NULL)
123620 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
123621 +
123622 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
123623 + if (p_IntrHndl == NULL)
123624 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
123625 + p_IntrHndl->f_Isr = f_Isr;
123626 + p_IntrHndl->handle = handle;
123627 + interruptHandlers[irq] = p_IntrHndl;
123628 +
123629 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
123630 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
123631 + disable_irq(GetDeviceIrqNum(irq));
123632 +#endif
123633 + return E_OK;
123634 +}
123635 +
123636 +t_Error XX_FreeIntr(int irq)
123637 +{
123638 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
123639 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
123640 + XX_Free(p_IntrHndl);
123641 + interruptHandlers[irq] = 0;
123642 + return E_OK;
123643 +}
123644 +
123645 +t_Error XX_EnableIntr(int irq)
123646 +{
123647 + enable_irq(GetDeviceIrqNum(irq));
123648 + return E_OK;
123649 +}
123650 +
123651 +t_Error XX_DisableIntr(int irq)
123652 +{
123653 + disable_irq(GetDeviceIrqNum(irq));
123654 + return E_OK;
123655 +}
123656 +
123657 +
123658 +/*****************************************************************************/
123659 +/* Tasklet Service Routines */
123660 +/*****************************************************************************/
123661 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
123662 +typedef struct
123663 +{
123664 + t_Handle h_Data;
123665 + void (*f_Callback) (void *);
123666 + struct delayed_work dwork;
123667 +} t_Tasklet;
123668 +
123669 +static void GenericTaskletCallback(struct work_struct *p_Work)
123670 +{
123671 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
123672 +
123673 + p_Task->f_Callback(p_Task->h_Data);
123674 +}
123675 +#endif /* LINUX_VERSION_CODE */
123676 +
123677 +
123678 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
123679 +{
123680 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123681 + struct work_struct *p_Task;
123682 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
123683 + INIT_WORK(p_Task, routine, data);
123684 +#else
123685 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
123686 + p_Task->h_Data = data;
123687 + p_Task->f_Callback = routine;
123688 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
123689 +#endif /* LINUX_VERSION_CODE */
123690 +
123691 + return (t_TaskletHandle)p_Task;
123692 +}
123693 +
123694 +
123695 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
123696 +{
123697 + if (h_Tasklet)
123698 + XX_Free(h_Tasklet);
123699 +}
123700 +
123701 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
123702 +{
123703 + int ans;
123704 +
123705 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123706 + if (immediate)
123707 + ans = schedule_work(h_Tasklet);
123708 + else
123709 + ans = schedule_delayed_work(h_Tasklet, 1);
123710 +#else
123711 + if (immediate)
123712 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
123713 + else
123714 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
123715 +#endif /* LINUX_VERSION_CODE */
123716 +
123717 + return ans;
123718 +}
123719 +
123720 +void XX_FlushScheduledTasks(void)
123721 +{
123722 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123723 + flush_scheduled_tasks();
123724 +#else
123725 + flush_scheduled_work();
123726 +#endif /* LINUX_VERSION_CODE */
123727 +}
123728 +
123729 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
123730 +{
123731 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123732 + return (int)(((struct work_struct *)h_Tasklet)->pending);
123733 +#else
123734 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
123735 +#endif /* LINUX_VERSION_CODE */
123736 +}
123737 +
123738 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
123739 +{
123740 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123741 + ((struct tq_struct *)h_Tasklet)->data = data;
123742 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123743 + ((struct work_struct *)h_Tasklet)->data = data;
123744 +#else
123745 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
123746 +#endif /* LINUX_VERSION_CODE */
123747 +}
123748 +
123749 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
123750 +{
123751 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123752 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
123753 +#else
123754 + return ((t_Tasklet *)h_Tasklet)->h_Data;
123755 +#endif /* LINUX_VERSION_CODE */
123756 +}
123757 +
123758 +
123759 +/*****************************************************************************/
123760 +/* Spinlock Service Routines */
123761 +/*****************************************************************************/
123762 +
123763 +t_Handle XX_InitSpinlock(void)
123764 +{
123765 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
123766 + if (!p_Spinlock)
123767 + return NULL;
123768 +
123769 + spin_lock_init(p_Spinlock);
123770 +
123771 + return (t_Handle)p_Spinlock;
123772 +}
123773 +
123774 +void XX_FreeSpinlock(t_Handle h_Spinlock)
123775 +{
123776 + if (h_Spinlock)
123777 + XX_Free(h_Spinlock);
123778 +}
123779 +
123780 +void XX_LockSpinlock(t_Handle h_Spinlock)
123781 +{
123782 + spin_lock((spinlock_t *)h_Spinlock);
123783 +}
123784 +
123785 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
123786 +{
123787 + spin_unlock((spinlock_t *)h_Spinlock);
123788 +}
123789 +
123790 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
123791 +{
123792 + unsigned long intrFlags;
123793 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
123794 + return intrFlags;
123795 +}
123796 +
123797 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
123798 +{
123799 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
123800 +}
123801 +
123802 +
123803 +/*****************************************************************************/
123804 +/* Timers Service Routines */
123805 +/*****************************************************************************/
123806 +/* The time now is in mili sec. resolution */
123807 +uint32_t XX_CurrentTime(void)
123808 +{
123809 + return (jiffies*1000)/HZ;
123810 +}
123811 +
123812 +
123813 +t_Handle XX_CreateTimer(void)
123814 +{
123815 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
123816 + if (p_Timer)
123817 + {
123818 + memset(p_Timer, 0, sizeof(struct timer_list));
123819 + init_timer(p_Timer);
123820 + }
123821 + return (t_Handle)p_Timer;
123822 +}
123823 +
123824 +void XX_FreeTimer(t_Handle h_Timer)
123825 +{
123826 + if (h_Timer)
123827 + XX_Free(h_Timer);
123828 +}
123829 +
123830 +void XX_StartTimer(t_Handle h_Timer,
123831 + uint32_t msecs,
123832 + bool periodic,
123833 + void (*f_TimerExpired)(t_Handle),
123834 + t_Handle h_Arg)
123835 +{
123836 + int tmp_jiffies = (msecs*HZ)/1000;
123837 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123838 +
123839 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
123840 +
123841 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
123842 + p_Timer->data = (unsigned long)h_Arg;
123843 + if ((msecs*HZ)%1000)
123844 + tmp_jiffies++;
123845 + p_Timer->expires = (jiffies + tmp_jiffies);
123846 +
123847 + add_timer((struct timer_list *)h_Timer);
123848 +}
123849 +
123850 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
123851 +{
123852 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123853 +
123854 + p_Timer->data = (unsigned long)data;
123855 +}
123856 +
123857 +t_Handle XX_GetTimerData(t_Handle h_Timer)
123858 +{
123859 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123860 +
123861 + return (t_Handle)p_Timer->data;
123862 +}
123863 +
123864 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
123865 +{
123866 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123867 +
123868 + return (uint32_t)p_Timer->expires;
123869 +}
123870 +
123871 +void XX_StopTimer(t_Handle h_Timer)
123872 +{
123873 + del_timer((struct timer_list *)h_Timer);
123874 +}
123875 +
123876 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
123877 +{
123878 + int tmp_jiffies = (msecs*HZ)/1000;
123879 +
123880 + if ((msecs*HZ)%1000)
123881 + tmp_jiffies++;
123882 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
123883 +}
123884 +
123885 +int XX_TimerIsActive(t_Handle h_Timer)
123886 +{
123887 + return timer_pending((struct timer_list *)h_Timer);
123888 +}
123889 +
123890 +uint32_t XX_Sleep(uint32_t msecs)
123891 +{
123892 + int tmp_jiffies = (msecs*HZ)/1000;
123893 +
123894 + if ((msecs*HZ)%1000)
123895 + tmp_jiffies++;
123896 + return schedule_timeout(tmp_jiffies);
123897 +}
123898 +
123899 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
123900 +void XX_UDelay(uint32_t usecs)
123901 +{
123902 + udelay(usecs);
123903 +}
123904 +
123905 +/* TODO: verify that these are correct */
123906 +#define MSG_BODY_SIZE 512
123907 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
123908 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
123909 +t_Error XX_SendMessage(char *p_DestAddr,
123910 + uint32_t msgId,
123911 + uint8_t msgBody[MSG_BODY_SIZE],
123912 + t_MsgCompletionCB *f_CompletionCB,
123913 + t_Handle h_CBArg);
123914 +
123915 +typedef struct {
123916 + char *p_Addr;
123917 + t_MsgHandler *f_MsgHandlerCB;
123918 + t_Handle h_Mod;
123919 + t_List node;
123920 +} t_MsgHndlr;
123921 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
123922 +
123923 +LIST(msgHndlrList);
123924 +
123925 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
123926 +{
123927 + uint32_t intFlags;
123928 +
123929 + intFlags = XX_DisableAllIntr();
123930 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
123931 + XX_RestoreAllIntr(intFlags);
123932 +}
123933 +/* TODO: add this for multi-platform support
123934 +static t_MsgHndlr * DequeueMsgHndlr(void)
123935 +{
123936 + t_MsgHndlr *p_MsgHndlr = NULL;
123937 + uint32_t intFlags;
123938 +
123939 + intFlags = XX_DisableAllIntr();
123940 + if (!LIST_IsEmpty(&msgHndlrList))
123941 + {
123942 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
123943 + LIST_DelAndInit(&p_MsgHndlr->node);
123944 + }
123945 + XX_RestoreAllIntr(intFlags);
123946 +
123947 + return p_MsgHndlr;
123948 +}
123949 +*/
123950 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
123951 +{
123952 + t_MsgHndlr *p_MsgHndlr;
123953 + t_List *p_Pos;
123954 +
123955 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
123956 + {
123957 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
123958 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
123959 + return p_MsgHndlr;
123960 + }
123961 +
123962 + return NULL;
123963 +}
123964 +
123965 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
123966 +{
123967 + t_MsgHndlr *p_MsgHndlr;
123968 + uint32_t len;
123969 +
123970 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
123971 + if (!p_MsgHndlr)
123972 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
123973 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
123974 +
123975 + len = strlen(p_Addr);
123976 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
123977 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
123978 +
123979 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
123980 + p_MsgHndlr->h_Mod = h_Mod;
123981 + INIT_LIST(&p_MsgHndlr->node);
123982 + EnqueueMsgHndlr(p_MsgHndlr);
123983 +
123984 + return E_OK;
123985 +}
123986 +
123987 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
123988 +{
123989 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
123990 + if (!p_MsgHndlr)
123991 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123992 +
123993 + LIST_Del(&p_MsgHndlr->node);
123994 + XX_Free(p_MsgHndlr->p_Addr);
123995 + XX_Free(p_MsgHndlr);
123996 +
123997 + return E_OK;
123998 +}
123999 +
124000 +t_Error XX_SendMessage(char *p_DestAddr,
124001 + uint32_t msgId,
124002 + uint8_t msgBody[MSG_BODY_SIZE],
124003 + t_MsgCompletionCB *f_CompletionCB,
124004 + t_Handle h_CBArg)
124005 +{
124006 + t_Error ans;
124007 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
124008 + if (!p_MsgHndlr)
124009 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
124010 +
124011 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
124012 +
124013 + if (f_CompletionCB)
124014 + f_CompletionCB(h_CBArg, msgBody);
124015 +
124016 + return ans;
124017 +}
124018 +
124019 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124020 + t_IpcMsgHandler *f_MsgHandler,
124021 + t_Handle h_Module,
124022 + uint32_t replyLength)
124023 +{
124024 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
124025 + return E_OK;
124026 +}
124027 +
124028 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124029 +{
124030 + UNUSED(addr);
124031 + return E_OK;
124032 +}
124033 +
124034 +
124035 +t_Error XX_IpcSendMessage(t_Handle h_Session,
124036 + uint8_t *p_Msg,
124037 + uint32_t msgLength,
124038 + uint8_t *p_Reply,
124039 + uint32_t *p_ReplyLength,
124040 + t_IpcMsgCompletion *f_Completion,
124041 + t_Handle h_Arg)
124042 +{
124043 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
124044 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
124045 + return E_OK;
124046 +}
124047 +
124048 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124049 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124050 +{
124051 + UNUSED(destAddr); UNUSED(srcAddr);
124052 + return E_OK;
124053 +}
124054 +
124055 +/*Forced to introduce due to PRINT_FMT_PARAMS define*/
124056 +uint32_t E500_GetId(void)
124057 +{
124058 + return raw_smp_processor_id();
124059 +}
124060 +
124061 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
124062 +int GetDeviceIrqNum(int irq)
124063 +{
124064 + struct device_node *iPar;
124065 + struct irq_domain *irqHost;
124066 + uint32_t hwIrq;
124067 +
124068 + /* Get the interrupt controller */
124069 + iPar = of_find_node_by_name(NULL, "mpic");
124070 + hwIrq = 0;
124071 +
124072 + ASSERT_COND(iPar != NULL);
124073 + /* Get the irq host */
124074 + irqHost = irq_find_host(iPar);
124075 + of_node_put(iPar);
124076 +
124077 + /* Create irq mapping */
124078 + return irq_create_mapping(irqHost, hwIrq);
124079 +}
124080 +#else
124081 +#error "kernel not supported!!!"
124082 +#endif /* LINUX_VERSION_CODE */
124083 +
124084 +void * XX_PhysToVirt(physAddress_t addr)
124085 +{
124086 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
124087 +}
124088 +
124089 +physAddress_t XX_VirtToPhys(void * addr)
124090 +{
124091 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
124092 +}
124093 +
124094 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
124095 +{
124096 + uintptr_t *returnCode, tmp;
124097 +
124098 + if (alignment < sizeof(uintptr_t))
124099 + alignment = sizeof(uintptr_t);
124100 + size += alignment + sizeof(returnCode);
124101 + tmp = (uintptr_t)xx_Malloc(size);
124102 + if (tmp == 0)
124103 + return NULL;
124104 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
124105 + *(returnCode - 1) = tmp;
124106 +
124107 + return (void*)returnCode;
124108 +}
124109 +
124110 +void xx_FreeSmart(void *p)
124111 +{
124112 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
124113 +}
124114 --- /dev/null
124115 +++ b/drivers/staging/fsl_qbman/Kconfig
124116 @@ -0,0 +1,228 @@
124117 +config FSL_SDK_DPA
124118 + bool "Freescale Datapath Queue and Buffer management"
124119 + depends on !FSL_DPAA
124120 + select FSL_QMAN_FQ_LOOKUP if PPC64
124121 + select FSL_QMAN_FQ_LOOKUP if ARM64
124122 +
124123 +
124124 +menu "Freescale Datapath QMan/BMan options"
124125 + depends on FSL_SDK_DPA
124126 +
124127 +config FSL_DPA_CHECKING
124128 + bool "additional driver checking"
124129 + default n
124130 + ---help---
124131 + Compiles in additional checks to sanity-check the drivers and any
124132 + use of it by other code. Not recommended for performance.
124133 +
124134 +config FSL_DPA_CAN_WAIT
124135 + bool
124136 + default y
124137 +
124138 +config FSL_DPA_CAN_WAIT_SYNC
124139 + bool
124140 + default y
124141 +
124142 +config FSL_DPA_PIRQ_FAST
124143 + bool
124144 + default y
124145 +
124146 +config FSL_DPA_PIRQ_SLOW
124147 + bool
124148 + default y
124149 +
124150 +config FSL_DPA_PORTAL_SHARE
124151 + bool
124152 + default y
124153 +
124154 +config FSL_SDK_BMAN
124155 + bool "Freescale Buffer Manager (BMan) support"
124156 + default y
124157 +
124158 +if FSL_SDK_BMAN
124159 +
124160 +config FSL_BMAN_CONFIG
124161 + bool "BMan device management"
124162 + default y
124163 + ---help---
124164 + If this linux image is running natively, you need this option. If this
124165 + linux image is running as a guest OS under the hypervisor, only one
124166 + guest OS ("the control plane") needs this option.
124167 +
124168 +config FSL_BMAN_TEST
124169 + tristate "BMan self-tests"
124170 + default n
124171 + ---help---
124172 + This option compiles self-test code for BMan.
124173 +
124174 +config FSL_BMAN_TEST_HIGH
124175 + bool "BMan high-level self-test"
124176 + depends on FSL_BMAN_TEST
124177 + default y
124178 + ---help---
124179 + This requires the presence of cpu-affine portals, and performs
124180 + high-level API testing with them (whichever portal(s) are affine to
124181 + the cpu(s) the test executes on).
124182 +
124183 +config FSL_BMAN_TEST_THRESH
124184 + bool "BMan threshold test"
124185 + depends on FSL_BMAN_TEST
124186 + default y
124187 + ---help---
124188 + Multi-threaded (SMP) test of BMan pool depletion. A pool is seeded
124189 + before multiple threads (one per cpu) create pool objects to track
124190 + depletion state changes. The pool is then drained to empty by a
124191 + "drainer" thread, and the other threads that they observe exactly
124192 + the depletion state changes that are expected.
124193 +
124194 +config FSL_BMAN_DEBUGFS
124195 + tristate "BMan debugfs interface"
124196 + depends on DEBUG_FS
124197 + default y
124198 + ---help---
124199 + This option compiles debugfs code for BMan.
124200 +
124201 +endif # FSL_SDK_BMAN
124202 +
124203 +config FSL_SDK_QMAN
124204 + bool "Freescale Queue Manager (QMan) support"
124205 + default y
124206 +
124207 +if FSL_SDK_QMAN
124208 +
124209 +config FSL_QMAN_POLL_LIMIT
124210 + int
124211 + default 32
124212 +
124213 +config FSL_QMAN_CONFIG
124214 + bool "QMan device management"
124215 + default y
124216 + ---help---
124217 + If this linux image is running natively, you need this option. If this
124218 + linux image is running as a guest OS under the hypervisor, only one
124219 + guest OS ("the control plane") needs this option.
124220 +
124221 +config FSL_QMAN_TEST
124222 + tristate "QMan self-tests"
124223 + default n
124224 + ---help---
124225 + This option compiles self-test code for QMan.
124226 +
124227 +config FSL_QMAN_TEST_STASH_POTATO
124228 + bool "QMan 'hot potato' data-stashing self-test"
124229 + depends on FSL_QMAN_TEST
124230 + default y
124231 + ---help---
124232 + This performs a "hot potato" style test enqueuing/dequeuing a frame
124233 + across a series of FQs scheduled to different portals (and cpus), with
124234 + DQRR, data and context stashing always on.
124235 +
124236 +config FSL_QMAN_TEST_HIGH
124237 + bool "QMan high-level self-test"
124238 + depends on FSL_QMAN_TEST
124239 + default y
124240 + ---help---
124241 + This requires the presence of cpu-affine portals, and performs
124242 + high-level API testing with them (whichever portal(s) are affine to
124243 + the cpu(s) the test executes on).
124244 +
124245 +config FSL_QMAN_DEBUGFS
124246 + tristate "QMan debugfs interface"
124247 + depends on DEBUG_FS
124248 + default y
124249 + ---help---
124250 + This option compiles debugfs code for QMan.
124251 +
124252 +# H/w settings that can be hard-coded for now.
124253 +config FSL_QMAN_FQD_SZ
124254 + int "size of Frame Queue Descriptor region"
124255 + default 10
124256 + ---help---
124257 + This is the size of the FQD region defined as: PAGE_SIZE * (2^value)
124258 + ex: 10 => PAGE_SIZE * (2^10)
124259 + Note: Default device-trees now require minimum Kconfig setting of 10.
124260 +
124261 +config FSL_QMAN_PFDR_SZ
124262 + int "size of the PFDR pool"
124263 + default 13
124264 + ---help---
124265 + This is the size of the PFDR pool defined as: PAGE_SIZE * (2^value)
124266 + ex: 13 => PAGE_SIZE * (2^13)
124267 +
124268 +# Corenet initiator settings. Stash request queues are 4-deep to match cores'
124269 +# ability to snart. Stash priority is 3, other priorities are 2.
124270 +config FSL_QMAN_CI_SCHED_CFG_SRCCIV
124271 + int
124272 + depends on FSL_QMAN_CONFIG
124273 + default 4
124274 +config FSL_QMAN_CI_SCHED_CFG_SRQ_W
124275 + int
124276 + depends on FSL_QMAN_CONFIG
124277 + default 3
124278 +config FSL_QMAN_CI_SCHED_CFG_RW_W
124279 + int
124280 + depends on FSL_QMAN_CONFIG
124281 + default 2
124282 +config FSL_QMAN_CI_SCHED_CFG_BMAN_W
124283 + int
124284 + depends on FSL_QMAN_CONFIG
124285 + default 2
124286 +
124287 +# portal interrupt settings
124288 +config FSL_QMAN_PIRQ_DQRR_ITHRESH
124289 + int
124290 + default 12
124291 +config FSL_QMAN_PIRQ_MR_ITHRESH
124292 + int
124293 + default 4
124294 +config FSL_QMAN_PIRQ_IPERIOD
124295 + int
124296 + default 100
124297 +
124298 +# 64 bit kernel support
124299 +config FSL_QMAN_FQ_LOOKUP
124300 + bool
124301 + default n
124302 +
124303 +config QMAN_CEETM_UPDATE_PERIOD
124304 + int "Token update period for shaping, in nanoseconds"
124305 + default 1000
124306 + ---help---
124307 + Traffic shaping works by performing token calculations (using
124308 + credits) on shaper instances periodically. This update period
124309 + sets the granularity for how often those token rate credit
124310 + updates are performed, and thus determines the accuracy and
124311 + range of traffic rates that can be configured by users. The
124312 + reference manual recommends a 1 microsecond period as providing
124313 + a good balance between granularity and range.
124314 +
124315 + Unless you know what you are doing, leave this value at its default.
124316 +
124317 +config FSL_QMAN_INIT_TIMEOUT
124318 + int "timeout for qman init stage, in seconds"
124319 + default 10
124320 + ---help---
124321 + The timeout setting to quit the initialization loop for non-control
124322 + partition in case the control partition fails to boot-up.
124323 +
124324 +endif # FSL_SDK_QMAN
124325 +
124326 +config FSL_USDPAA
124327 + bool "Freescale USDPAA process driver"
124328 + depends on FSL_SDK_DPA
124329 + default y
124330 + ---help---
124331 + This driver provides user-space access to kernel-managed
124332 + resource interfaces for USDPAA applications, on the assumption
124333 + that each process will open this device once. Specifically, this
124334 + device exposes functionality that would be awkward if exposed
124335 + via the portal devices - ie. this device exposes functionality
124336 + that is inherently process-wide rather than portal-specific.
124337 + This device is necessary for obtaining access to DMA memory and
124338 + for allocation of Qman and Bman resources. In short, if you wish
124339 + to use USDPAA applications, you need this.
124340 +
124341 + If unsure, say Y.
124342 +
124343 +
124344 +endmenu
124345 --- /dev/null
124346 +++ b/drivers/staging/fsl_qbman/Makefile
124347 @@ -0,0 +1,28 @@
124348 +subdir-ccflags-y := -Werror
124349 +
124350 +# Common
124351 +obj-$(CONFIG_FSL_SDK_DPA) += dpa_alloc.o
124352 +obj-$(CONFIG_FSL_SDK_DPA) += qbman_driver.o
124353 +
124354 +# Bman
124355 +obj-$(CONFIG_FSL_SDK_BMAN) += bman_high.o
124356 +obj-$(CONFIG_FSL_BMAN_CONFIG) += bman_config.o bman_driver.o
124357 +obj-$(CONFIG_FSL_BMAN_TEST) += bman_tester.o
124358 +obj-$(CONFIG_FSL_BMAN_DEBUGFS) += bman_debugfs_interface.o
124359 +bman_tester-y = bman_test.o
124360 +bman_tester-$(CONFIG_FSL_BMAN_TEST_HIGH) += bman_test_high.o
124361 +bman_tester-$(CONFIG_FSL_BMAN_TEST_THRESH) += bman_test_thresh.o
124362 +bman_debugfs_interface-y = bman_debugfs.o
124363 +
124364 +# Qman
124365 +obj-$(CONFIG_FSL_SDK_QMAN) += qman_high.o qman_utility.o
124366 +obj-$(CONFIG_FSL_QMAN_CONFIG) += qman_config.o qman_driver.o
124367 +obj-$(CONFIG_FSL_QMAN_TEST) += qman_tester.o
124368 +qman_tester-y = qman_test.o
124369 +qman_tester-$(CONFIG_FSL_QMAN_TEST_STASH_POTATO) += qman_test_hotpotato.o
124370 +qman_tester-$(CONFIG_FSL_QMAN_TEST_HIGH) += qman_test_high.o
124371 +obj-$(CONFIG_FSL_QMAN_DEBUGFS) += qman_debugfs_interface.o
124372 +qman_debugfs_interface-y = qman_debugfs.o
124373 +
124374 +# USDPAA
124375 +obj-$(CONFIG_FSL_USDPAA) += fsl_usdpaa.o fsl_usdpaa_irq.o
124376 --- /dev/null
124377 +++ b/drivers/staging/fsl_qbman/bman_config.c
124378 @@ -0,0 +1,720 @@
124379 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc.
124380 + *
124381 + * Redistribution and use in source and binary forms, with or without
124382 + * modification, are permitted provided that the following conditions are met:
124383 + * * Redistributions of source code must retain the above copyright
124384 + * notice, this list of conditions and the following disclaimer.
124385 + * * Redistributions in binary form must reproduce the above copyright
124386 + * notice, this list of conditions and the following disclaimer in the
124387 + * documentation and/or other materials provided with the distribution.
124388 + * * Neither the name of Freescale Semiconductor nor the
124389 + * names of its contributors may be used to endorse or promote products
124390 + * derived from this software without specific prior written permission.
124391 + *
124392 + *
124393 + * ALTERNATIVELY, this software may be distributed under the terms of the
124394 + * GNU General Public License ("GPL") as published by the Free Software
124395 + * Foundation, either version 2 of that License or (at your option) any
124396 + * later version.
124397 + *
124398 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
124399 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
124400 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
124401 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
124402 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
124403 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
124404 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
124405 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124406 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
124407 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124408 + */
124409 +
124410 +#include <asm/cacheflush.h>
124411 +#include "bman_private.h"
124412 +#include <linux/of_reserved_mem.h>
124413 +
124414 +/* Last updated for v00.79 of the BG */
124415 +
124416 +struct bman;
124417 +
124418 +/* Register offsets */
124419 +#define REG_POOL_SWDET(n) (0x0000 + ((n) * 0x04))
124420 +#define REG_POOL_HWDET(n) (0x0100 + ((n) * 0x04))
124421 +#define REG_POOL_SWDXT(n) (0x0200 + ((n) * 0x04))
124422 +#define REG_POOL_HWDXT(n) (0x0300 + ((n) * 0x04))
124423 +#define REG_POOL_CONTENT(n) (0x0600 + ((n) * 0x04))
124424 +#define REG_FBPR_FPC 0x0800
124425 +#define REG_STATE_IDLE 0x960
124426 +#define REG_STATE_STOP 0x964
124427 +#define REG_ECSR 0x0a00
124428 +#define REG_ECIR 0x0a04
124429 +#define REG_EADR 0x0a08
124430 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
124431 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
124432 +#define REG_IP_REV_1 0x0bf8
124433 +#define REG_IP_REV_2 0x0bfc
124434 +#define REG_FBPR_BARE 0x0c00
124435 +#define REG_FBPR_BAR 0x0c04
124436 +#define REG_FBPR_AR 0x0c10
124437 +#define REG_SRCIDR 0x0d04
124438 +#define REG_LIODNR 0x0d08
124439 +#define REG_ERR_ISR 0x0e00 /* + "enum bm_isr_reg" */
124440 +
124441 +/* Used by all error interrupt registers except 'inhibit' */
124442 +#define BM_EIRQ_IVCI 0x00000010 /* Invalid Command Verb */
124443 +#define BM_EIRQ_FLWI 0x00000008 /* FBPR Low Watermark */
124444 +#define BM_EIRQ_MBEI 0x00000004 /* Multi-bit ECC Error */
124445 +#define BM_EIRQ_SBEI 0x00000002 /* Single-bit ECC Error */
124446 +#define BM_EIRQ_BSCN 0x00000001 /* pool State Change Notification */
124447 +
124448 +/* BMAN_ECIR valid error bit */
124449 +#define PORTAL_ECSR_ERR (BM_EIRQ_IVCI)
124450 +
124451 +union bman_ecir {
124452 + u32 ecir_raw;
124453 + struct {
124454 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
124455 + u32 __reserved1:4;
124456 + u32 portal_num:4;
124457 + u32 __reserved2:12;
124458 + u32 numb:4;
124459 + u32 __reserved3:2;
124460 + u32 pid:6;
124461 +#else
124462 + u32 pid:6;
124463 + u32 __reserved3:2;
124464 + u32 numb:4;
124465 + u32 __reserved2:12;
124466 + u32 portal_num:4;
124467 + u32 __reserved1:4;
124468 +#endif
124469 + } __packed info;
124470 +};
124471 +
124472 +union bman_eadr {
124473 + u32 eadr_raw;
124474 + struct {
124475 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
124476 + u32 __reserved1:5;
124477 + u32 memid:3;
124478 + u32 __reserved2:14;
124479 + u32 eadr:10;
124480 +#else
124481 + u32 eadr:10;
124482 + u32 __reserved2:14;
124483 + u32 memid:3;
124484 + u32 __reserved1:5;
124485 +#endif
124486 + } __packed info;
124487 +};
124488 +
124489 +struct bman_hwerr_txt {
124490 + u32 mask;
124491 + const char *txt;
124492 +};
124493 +
124494 +#define BMAN_HWE_TXT(a, b) { .mask = BM_EIRQ_##a, .txt = b }
124495 +
124496 +static const struct bman_hwerr_txt bman_hwerr_txts[] = {
124497 + BMAN_HWE_TXT(IVCI, "Invalid Command Verb"),
124498 + BMAN_HWE_TXT(FLWI, "FBPR Low Watermark"),
124499 + BMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
124500 + BMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
124501 + BMAN_HWE_TXT(BSCN, "Pool State Change Notification"),
124502 +};
124503 +#define BMAN_HWE_COUNT (sizeof(bman_hwerr_txts)/sizeof(struct bman_hwerr_txt))
124504 +
124505 +struct bman_error_info_mdata {
124506 + u16 addr_mask;
124507 + u16 bits;
124508 + const char *txt;
124509 +};
124510 +
124511 +#define BMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
124512 +static const struct bman_error_info_mdata error_mdata[] = {
124513 + BMAN_ERR_MDATA(0x03FF, 192, "Stockpile memory"),
124514 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 1"),
124515 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 2"),
124516 +};
124517 +#define BMAN_ERR_MDATA_COUNT \
124518 + (sizeof(error_mdata)/sizeof(struct bman_error_info_mdata))
124519 +
124520 +/* Add this in Kconfig */
124521 +#define BMAN_ERRS_TO_UNENABLE (BM_EIRQ_FLWI)
124522 +
124523 +/**
124524 + * bm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
124525 + * @v: for accessors that write values, this is the 32-bit value
124526 + *
124527 + * Manipulates BMAN_ERR_ISR, BMAN_ERR_IER, BMAN_ERR_ISDR, BMAN_ERR_IIR. All
124528 + * manipulations except bm_err_isr_[un]inhibit() use 32-bit masks composed of
124529 + * the BM_EIRQ_*** definitions. Note that "bm_err_isr_enable_write" means
124530 + * "write the enable register" rather than "enable the write register"!
124531 + */
124532 +#define bm_err_isr_status_read(bm) \
124533 + __bm_err_isr_read(bm, bm_isr_status)
124534 +#define bm_err_isr_status_clear(bm, m) \
124535 + __bm_err_isr_write(bm, bm_isr_status, m)
124536 +#define bm_err_isr_enable_read(bm) \
124537 + __bm_err_isr_read(bm, bm_isr_enable)
124538 +#define bm_err_isr_enable_write(bm, v) \
124539 + __bm_err_isr_write(bm, bm_isr_enable, v)
124540 +#define bm_err_isr_disable_read(bm) \
124541 + __bm_err_isr_read(bm, bm_isr_disable)
124542 +#define bm_err_isr_disable_write(bm, v) \
124543 + __bm_err_isr_write(bm, bm_isr_disable, v)
124544 +#define bm_err_isr_inhibit(bm) \
124545 + __bm_err_isr_write(bm, bm_isr_inhibit, 1)
124546 +#define bm_err_isr_uninhibit(bm) \
124547 + __bm_err_isr_write(bm, bm_isr_inhibit, 0)
124548 +
124549 +/*
124550 + * TODO: unimplemented registers
124551 + *
124552 + * BMAN_POOLk_SDCNT, BMAN_POOLk_HDCNT, BMAN_FULT,
124553 + * BMAN_VLDPL, BMAN_EECC, BMAN_SBET, BMAN_EINJ
124554 + */
124555 +
124556 +/* Encapsulate "struct bman *" as a cast of the register space address. */
124557 +
124558 +static struct bman *bm_create(void *regs)
124559 +{
124560 + return (struct bman *)regs;
124561 +}
124562 +
124563 +static inline u32 __bm_in(struct bman *bm, u32 offset)
124564 +{
124565 + return in_be32((void *)bm + offset);
124566 +}
124567 +static inline void __bm_out(struct bman *bm, u32 offset, u32 val)
124568 +{
124569 + out_be32((void *)bm + offset, val);
124570 +}
124571 +#define bm_in(reg) __bm_in(bm, REG_##reg)
124572 +#define bm_out(reg, val) __bm_out(bm, REG_##reg, val)
124573 +
124574 +static u32 __bm_err_isr_read(struct bman *bm, enum bm_isr_reg n)
124575 +{
124576 + return __bm_in(bm, REG_ERR_ISR + (n << 2));
124577 +}
124578 +
124579 +static void __bm_err_isr_write(struct bman *bm, enum bm_isr_reg n, u32 val)
124580 +{
124581 + __bm_out(bm, REG_ERR_ISR + (n << 2), val);
124582 +}
124583 +
124584 +static void bm_get_version(struct bman *bm, u16 *id, u8 *major, u8 *minor)
124585 +{
124586 + u32 v = bm_in(IP_REV_1);
124587 + *id = (v >> 16);
124588 + *major = (v >> 8) & 0xff;
124589 + *minor = v & 0xff;
124590 +}
124591 +
124592 +static u32 __generate_thresh(u32 val, int roundup)
124593 +{
124594 + u32 e = 0; /* co-efficient, exponent */
124595 + int oddbit = 0;
124596 + while (val > 0xff) {
124597 + oddbit = val & 1;
124598 + val >>= 1;
124599 + e++;
124600 + if (roundup && oddbit)
124601 + val++;
124602 + }
124603 + DPA_ASSERT(e < 0x10);
124604 + return val | (e << 8);
124605 +}
124606 +
124607 +static void bm_set_pool(struct bman *bm, u8 pool, u32 swdet, u32 swdxt,
124608 + u32 hwdet, u32 hwdxt)
124609 +{
124610 + DPA_ASSERT(pool < bman_pool_max);
124611 + bm_out(POOL_SWDET(pool), __generate_thresh(swdet, 0));
124612 + bm_out(POOL_SWDXT(pool), __generate_thresh(swdxt, 1));
124613 + bm_out(POOL_HWDET(pool), __generate_thresh(hwdet, 0));
124614 + bm_out(POOL_HWDXT(pool), __generate_thresh(hwdxt, 1));
124615 +}
124616 +
124617 +static void bm_set_memory(struct bman *bm, u64 ba, int prio, u32 size)
124618 +{
124619 + u32 exp = ilog2(size);
124620 + /* choke if size isn't within range */
124621 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
124622 + is_power_of_2(size));
124623 + /* choke if '[e]ba' has lower-alignment than 'size' */
124624 + DPA_ASSERT(!(ba & (size - 1)));
124625 + bm_out(FBPR_BARE, upper_32_bits(ba));
124626 + bm_out(FBPR_BAR, lower_32_bits(ba));
124627 + bm_out(FBPR_AR, (prio ? 0x40000000 : 0) | (exp - 1));
124628 +}
124629 +
124630 +/*****************/
124631 +/* Config driver */
124632 +/*****************/
124633 +
124634 +/* TODO: Kconfig these? */
124635 +#define DEFAULT_FBPR_SZ (PAGE_SIZE << 12)
124636 +
124637 +/* We support only one of these. */
124638 +static struct bman *bm;
124639 +static struct device_node *bm_node;
124640 +
124641 +/* And this state belongs to 'bm'. It is set during fsl_bman_init(), but used
124642 + * during bman_init_ccsr(). */
124643 +static dma_addr_t fbpr_a;
124644 +static size_t fbpr_sz = DEFAULT_FBPR_SZ;
124645 +
124646 +static int bman_fbpr(struct reserved_mem *rmem)
124647 +{
124648 + fbpr_a = rmem->base;
124649 + fbpr_sz = rmem->size;
124650 +
124651 + WARN_ON(!(fbpr_a && fbpr_sz));
124652 +
124653 + return 0;
124654 +}
124655 +RESERVEDMEM_OF_DECLARE(bman_fbpr, "fsl,bman-fbpr", bman_fbpr);
124656 +
124657 +static int __init fsl_bman_init(struct device_node *node)
124658 +{
124659 + struct resource res;
124660 + u32 __iomem *regs;
124661 + const char *s;
124662 + int ret, standby = 0;
124663 + u16 id;
124664 + u8 major, minor;
124665 +
124666 + ret = of_address_to_resource(node, 0, &res);
124667 + if (ret) {
124668 + pr_err("Can't get %s property 'reg'\n",
124669 + node->full_name);
124670 + return ret;
124671 + }
124672 + s = of_get_property(node, "fsl,hv-claimable", &ret);
124673 + if (s && !strcmp(s, "standby"))
124674 + standby = 1;
124675 + /* Global configuration */
124676 + regs = ioremap(res.start, res.end - res.start + 1);
124677 + bm = bm_create(regs);
124678 + BUG_ON(!bm);
124679 + bm_node = node;
124680 + bm_get_version(bm, &id, &major, &minor);
124681 + pr_info("Bman ver:%04x,%02x,%02x\n", id, major, minor);
124682 + if ((major == 1) && (minor == 0)) {
124683 + bman_ip_rev = BMAN_REV10;
124684 + bman_pool_max = 64;
124685 + } else if ((major == 2) && (minor == 0)) {
124686 + bman_ip_rev = BMAN_REV20;
124687 + bman_pool_max = 8;
124688 + } else if ((major == 2) && (minor == 1)) {
124689 + bman_ip_rev = BMAN_REV21;
124690 + bman_pool_max = 64;
124691 + } else {
124692 + pr_warn("unknown Bman version, default to rev1.0\n");
124693 + }
124694 +
124695 + if (standby) {
124696 + pr_info(" -> in standby mode\n");
124697 + return 0;
124698 + }
124699 + return 0;
124700 +}
124701 +
124702 +int bman_have_ccsr(void)
124703 +{
124704 + return bm ? 1 : 0;
124705 +}
124706 +
124707 +int bm_pool_set(u32 bpid, const u32 *thresholds)
124708 +{
124709 + if (!bm)
124710 + return -ENODEV;
124711 + bm_set_pool(bm, bpid, thresholds[0],
124712 + thresholds[1], thresholds[2],
124713 + thresholds[3]);
124714 + return 0;
124715 +}
124716 +EXPORT_SYMBOL(bm_pool_set);
124717 +
124718 +__init int bman_init_early(void)
124719 +{
124720 + struct device_node *dn;
124721 + int ret;
124722 +
124723 + for_each_compatible_node(dn, NULL, "fsl,bman") {
124724 + if (bm)
124725 + pr_err("%s: only one 'fsl,bman' allowed\n",
124726 + dn->full_name);
124727 + else {
124728 + if (!of_device_is_available(dn))
124729 + continue;
124730 +
124731 + ret = fsl_bman_init(dn);
124732 + BUG_ON(ret);
124733 + }
124734 + }
124735 + return 0;
124736 +}
124737 +postcore_initcall_sync(bman_init_early);
124738 +
124739 +
124740 +static void log_edata_bits(u32 bit_count)
124741 +{
124742 + u32 i, j, mask = 0xffffffff;
124743 +
124744 + pr_warn("Bman ErrInt, EDATA:\n");
124745 + i = bit_count/32;
124746 + if (bit_count%32) {
124747 + i++;
124748 + mask = ~(mask << bit_count%32);
124749 + }
124750 + j = 16-i;
124751 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)) & mask);
124752 + j++;
124753 + for (; j < 16; j++)
124754 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)));
124755 +}
124756 +
124757 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
124758 +{
124759 + union bman_ecir ecir_val;
124760 + union bman_eadr eadr_val;
124761 +
124762 + ecir_val.ecir_raw = bm_in(ECIR);
124763 + /* Is portal info valid */
124764 + if (ecsr_val & PORTAL_ECSR_ERR) {
124765 + pr_warn("Bman ErrInt: SWP id %d, numb %d, pid %d\n",
124766 + ecir_val.info.portal_num, ecir_val.info.numb,
124767 + ecir_val.info.pid);
124768 + }
124769 + if (ecsr_val & (BM_EIRQ_SBEI|BM_EIRQ_MBEI)) {
124770 + eadr_val.eadr_raw = bm_in(EADR);
124771 + pr_warn("Bman ErrInt: EADR Memory: %s, 0x%x\n",
124772 + error_mdata[eadr_val.info.memid].txt,
124773 + error_mdata[eadr_val.info.memid].addr_mask
124774 + & eadr_val.info.eadr);
124775 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
124776 + }
124777 +}
124778 +
124779 +/* Bman interrupt handler */
124780 +static irqreturn_t bman_isr(int irq, void *ptr)
124781 +{
124782 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
124783 +
124784 + ier_val = bm_err_isr_enable_read(bm);
124785 + isr_val = bm_err_isr_status_read(bm);
124786 + ecsr_val = bm_in(ECSR);
124787 + isr_mask = isr_val & ier_val;
124788 +
124789 + if (!isr_mask)
124790 + return IRQ_NONE;
124791 + for (i = 0; i < BMAN_HWE_COUNT; i++) {
124792 + if (bman_hwerr_txts[i].mask & isr_mask) {
124793 + pr_warn("Bman ErrInt: %s\n", bman_hwerr_txts[i].txt);
124794 + if (bman_hwerr_txts[i].mask & ecsr_val) {
124795 + log_additional_error_info(isr_mask, ecsr_val);
124796 + /* Re-arm error capture registers */
124797 + bm_out(ECSR, ecsr_val);
124798 + }
124799 + if (bman_hwerr_txts[i].mask & BMAN_ERRS_TO_UNENABLE) {
124800 + pr_devel("Bman un-enabling error 0x%x\n",
124801 + bman_hwerr_txts[i].mask);
124802 + ier_val &= ~bman_hwerr_txts[i].mask;
124803 + bm_err_isr_enable_write(bm, ier_val);
124804 + }
124805 + }
124806 + }
124807 + bm_err_isr_status_clear(bm, isr_val);
124808 + return IRQ_HANDLED;
124809 +}
124810 +
124811 +static int __bind_irq(void)
124812 +{
124813 + int ret, err_irq;
124814 +
124815 + err_irq = of_irq_to_resource(bm_node, 0, NULL);
124816 + if (err_irq == 0) {
124817 + pr_info("Can't get %s property '%s'\n", bm_node->full_name,
124818 + "interrupts");
124819 + return -ENODEV;
124820 + }
124821 + ret = request_irq(err_irq, bman_isr, IRQF_SHARED, "bman-err", bm_node);
124822 + if (ret) {
124823 + pr_err("request_irq() failed %d for '%s'\n", ret,
124824 + bm_node->full_name);
124825 + return -ENODEV;
124826 + }
124827 + /* Disable Buffer Pool State Change */
124828 + bm_err_isr_disable_write(bm, BM_EIRQ_BSCN);
124829 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
124830 + * to resource allocation during driver init). */
124831 + bm_err_isr_status_clear(bm, 0xffffffff);
124832 + /* Enable Error Interrupts */
124833 + bm_err_isr_enable_write(bm, 0xffffffff);
124834 + return 0;
124835 +}
124836 +
124837 +int bman_init_ccsr(struct device_node *node)
124838 +{
124839 + int ret;
124840 + if (!bman_have_ccsr())
124841 + return 0;
124842 + if (node != bm_node)
124843 + return -EINVAL;
124844 + /* FBPR memory */
124845 + bm_set_memory(bm, fbpr_a, 0, fbpr_sz);
124846 + pr_info("bman-fbpr addr %pad size 0x%zx\n", &fbpr_a, fbpr_sz);
124847 +
124848 + ret = __bind_irq();
124849 + if (ret)
124850 + return ret;
124851 + return 0;
124852 +}
124853 +
124854 +u32 bm_pool_free_buffers(u32 bpid)
124855 +{
124856 + return bm_in(POOL_CONTENT(bpid));
124857 +}
124858 +
124859 +#ifdef CONFIG_SYSFS
124860 +
124861 +#define DRV_NAME "fsl-bman"
124862 +#define SBEC_MAX_ID 1
124863 +#define SBEC_MIN_ID 0
124864 +
124865 +static ssize_t show_fbpr_fpc(struct device *dev,
124866 + struct device_attribute *dev_attr, char *buf)
124867 +{
124868 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(FBPR_FPC));
124869 +};
124870 +
124871 +static ssize_t show_pool_count(struct device *dev,
124872 + struct device_attribute *dev_attr, char *buf)
124873 +{
124874 + u32 data;
124875 + int i;
124876 +
124877 + if (!sscanf(dev_attr->attr.name, "%d", &i) || (i >= bman_pool_max))
124878 + return -EINVAL;
124879 + data = bm_in(POOL_CONTENT(i));
124880 + return snprintf(buf, PAGE_SIZE, "%d\n", data);
124881 +};
124882 +
124883 +static ssize_t show_err_isr(struct device *dev,
124884 + struct device_attribute *dev_attr, char *buf)
124885 +{
124886 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", bm_in(ERR_ISR));
124887 +};
124888 +
124889 +static ssize_t show_sbec(struct device *dev,
124890 + struct device_attribute *dev_attr, char *buf)
124891 +{
124892 + int i;
124893 +
124894 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
124895 + return -EINVAL;
124896 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
124897 + return -EINVAL;
124898 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(SBEC(i)));
124899 +};
124900 +
124901 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
124902 +static DEVICE_ATTR(fbpr_fpc, S_IRUSR, show_fbpr_fpc, NULL);
124903 +
124904 +/* Didn't use DEVICE_ATTR as 64 of this would be required.
124905 + * Initialize them when needed. */
124906 +static char *name_attrs_pool_count; /* "xx" + null-terminator */
124907 +static struct device_attribute *dev_attr_buffer_pool_count;
124908 +
124909 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
124910 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
124911 +
124912 +static struct attribute *bman_dev_attributes[] = {
124913 + &dev_attr_fbpr_fpc.attr,
124914 + &dev_attr_err_isr.attr,
124915 + NULL
124916 +};
124917 +
124918 +static struct attribute *bman_dev_ecr_attributes[] = {
124919 + &dev_attr_sbec_0.attr,
124920 + &dev_attr_sbec_1.attr,
124921 + NULL
124922 +};
124923 +
124924 +static struct attribute **bman_dev_pool_count_attributes;
124925 +
124926 +
124927 +/* root level */
124928 +static const struct attribute_group bman_dev_attr_grp = {
124929 + .name = NULL,
124930 + .attrs = bman_dev_attributes
124931 +};
124932 +static const struct attribute_group bman_dev_ecr_grp = {
124933 + .name = "error_capture",
124934 + .attrs = bman_dev_ecr_attributes
124935 +};
124936 +static struct attribute_group bman_dev_pool_countent_grp = {
124937 + .name = "pool_count",
124938 +};
124939 +
124940 +static int of_fsl_bman_remove(struct platform_device *ofdev)
124941 +{
124942 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
124943 + return 0;
124944 +};
124945 +
124946 +static int of_fsl_bman_probe(struct platform_device *ofdev)
124947 +{
124948 + int ret, i;
124949 +
124950 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
124951 + if (ret)
124952 + goto done;
124953 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
124954 + if (ret)
124955 + goto del_group_0;
124956 +
124957 + name_attrs_pool_count = kmalloc(sizeof(char) * bman_pool_max * 3,
124958 + GFP_KERNEL);
124959 + if (!name_attrs_pool_count) {
124960 + pr_err("Can't alloc name_attrs_pool_count\n");
124961 + goto del_group_1;
124962 + }
124963 +
124964 + dev_attr_buffer_pool_count = kmalloc(sizeof(struct device_attribute) *
124965 + bman_pool_max, GFP_KERNEL);
124966 + if (!dev_attr_buffer_pool_count) {
124967 + pr_err("Can't alloc dev_attr-buffer_pool_count\n");
124968 + goto del_group_2;
124969 + }
124970 +
124971 + bman_dev_pool_count_attributes = kmalloc(sizeof(struct attribute *) *
124972 + (bman_pool_max + 1), GFP_KERNEL);
124973 + if (!bman_dev_pool_count_attributes) {
124974 + pr_err("can't alloc bman_dev_pool_count_attributes\n");
124975 + goto del_group_3;
124976 + }
124977 +
124978 + for (i = 0; i < bman_pool_max; i++) {
124979 + ret = scnprintf((name_attrs_pool_count + i * 3), 3, "%d", i);
124980 + if (!ret)
124981 + goto del_group_4;
124982 + dev_attr_buffer_pool_count[i].attr.name =
124983 + (name_attrs_pool_count + i * 3);
124984 + dev_attr_buffer_pool_count[i].attr.mode = S_IRUSR;
124985 + dev_attr_buffer_pool_count[i].show = show_pool_count;
124986 + bman_dev_pool_count_attributes[i] =
124987 + &dev_attr_buffer_pool_count[i].attr;
124988 + sysfs_attr_init(bman_dev_pool_count_attributes[i]);
124989 + }
124990 + bman_dev_pool_count_attributes[bman_pool_max] = NULL;
124991 +
124992 + bman_dev_pool_countent_grp.attrs = bman_dev_pool_count_attributes;
124993 +
124994 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_pool_countent_grp);
124995 + if (ret)
124996 + goto del_group_4;
124997 +
124998 + goto done;
124999 +
125000 +del_group_4:
125001 + kfree(bman_dev_pool_count_attributes);
125002 +del_group_3:
125003 + kfree(dev_attr_buffer_pool_count);
125004 +del_group_2:
125005 + kfree(name_attrs_pool_count);
125006 +del_group_1:
125007 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
125008 +del_group_0:
125009 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
125010 +done:
125011 + if (ret)
125012 + dev_err(&ofdev->dev,
125013 + "Cannot create dev attributes ret=%d\n", ret);
125014 + return ret;
125015 +};
125016 +
125017 +static struct of_device_id of_fsl_bman_ids[] = {
125018 + {
125019 + .compatible = "fsl,bman",
125020 + },
125021 + {}
125022 +};
125023 +MODULE_DEVICE_TABLE(of, of_fsl_bman_ids);
125024 +
125025 +#ifdef CONFIG_SUSPEND
125026 +static u32 saved_isdr;
125027 +
125028 +static int bman_pm_suspend_noirq(struct device *dev)
125029 +{
125030 + uint32_t idle_state;
125031 +
125032 + suspend_unused_bportal();
125033 + /* save isdr, disable all, clear isr */
125034 + saved_isdr = bm_err_isr_disable_read(bm);
125035 + bm_err_isr_disable_write(bm, 0xffffffff);
125036 + bm_err_isr_status_clear(bm, 0xffffffff);
125037 +
125038 + if (bman_ip_rev < BMAN_REV21) {
125039 +#ifdef CONFIG_PM_DEBUG
125040 + pr_info("Bman version doesn't have STATE_IDLE\n");
125041 +#endif
125042 + return 0;
125043 + }
125044 + idle_state = bm_in(STATE_IDLE);
125045 + if (!(idle_state & 0x1)) {
125046 + pr_err("Bman not idle 0x%x aborting\n", idle_state);
125047 + bm_err_isr_disable_write(bm, saved_isdr);
125048 + resume_unused_bportal();
125049 + return -EBUSY;
125050 + }
125051 +#ifdef CONFIG_PM_DEBUG
125052 + pr_info("Bman suspend code, IDLE_STAT = 0x%x\n", idle_state);
125053 +#endif
125054 + return 0;
125055 +}
125056 +
125057 +static int bman_pm_resume_noirq(struct device *dev)
125058 +{
125059 + /* restore isdr */
125060 + bm_err_isr_disable_write(bm, saved_isdr);
125061 + resume_unused_bportal();
125062 + return 0;
125063 +}
125064 +#else
125065 +#define bman_pm_suspend_noirq NULL
125066 +#define bman_pm_resume_noirq NULL
125067 +#endif
125068 +
125069 +static const struct dev_pm_ops bman_pm_ops = {
125070 + .suspend_noirq = bman_pm_suspend_noirq,
125071 + .resume_noirq = bman_pm_resume_noirq,
125072 +};
125073 +
125074 +static struct platform_driver of_fsl_bman_driver = {
125075 + .driver = {
125076 + .owner = THIS_MODULE,
125077 + .name = DRV_NAME,
125078 + .of_match_table = of_fsl_bman_ids,
125079 + .pm = &bman_pm_ops,
125080 + },
125081 + .probe = of_fsl_bman_probe,
125082 + .remove = of_fsl_bman_remove,
125083 +};
125084 +
125085 +static int bman_ctrl_init(void)
125086 +{
125087 + return platform_driver_register(&of_fsl_bman_driver);
125088 +}
125089 +
125090 +static void bman_ctrl_exit(void)
125091 +{
125092 + platform_driver_unregister(&of_fsl_bman_driver);
125093 +}
125094 +
125095 +module_init(bman_ctrl_init);
125096 +module_exit(bman_ctrl_exit);
125097 +
125098 +#endif /* CONFIG_SYSFS */
125099 --- /dev/null
125100 +++ b/drivers/staging/fsl_qbman/bman_debugfs.c
125101 @@ -0,0 +1,119 @@
125102 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
125103 + *
125104 + * Redistribution and use in source and binary forms, with or without
125105 + * modification, are permitted provided that the following conditions are met:
125106 + * * Redistributions of source code must retain the above copyright
125107 + * notice, this list of conditions and the following disclaimer.
125108 + * * Redistributions in binary form must reproduce the above copyright
125109 + * notice, this list of conditions and the following disclaimer in the
125110 + * documentation and/or other materials provided with the distribution.
125111 + * * Neither the name of Freescale Semiconductor nor the
125112 + * names of its contributors may be used to endorse or promote products
125113 + * derived from this software without specific prior written permission.
125114 + *
125115 + *
125116 + * ALTERNATIVELY, this software may be distributed under the terms of the
125117 + * GNU General Public License ("GPL") as published by the Free Software
125118 + * Foundation, either version 2 of that License or (at your option) any
125119 + * later version.
125120 + *
125121 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125122 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125123 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125124 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125125 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125126 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125127 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125128 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125129 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125130 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125131 + */
125132 +#include <linux/module.h>
125133 +#include <linux/fsl_bman.h>
125134 +#include <linux/debugfs.h>
125135 +#include <linux/seq_file.h>
125136 +#include <linux/uaccess.h>
125137 +
125138 +static struct dentry *dfs_root; /* debugfs root directory */
125139 +
125140 +/*******************************************************************************
125141 + * Query Buffer Pool State
125142 + ******************************************************************************/
125143 +static int query_bp_state_show(struct seq_file *file, void *offset)
125144 +{
125145 + int ret;
125146 + struct bm_pool_state state;
125147 + int i, j;
125148 + u32 mask;
125149 +
125150 + memset(&state, 0, sizeof(struct bm_pool_state));
125151 + ret = bman_query_pools(&state);
125152 + if (ret) {
125153 + seq_printf(file, "Error %d\n", ret);
125154 + return 0;
125155 + }
125156 + seq_puts(file, "bp_id free_buffers_avail bp_depleted\n");
125157 + for (i = 0; i < 2; i++) {
125158 + mask = 0x80000000;
125159 + for (j = 0; j < 32; j++) {
125160 + seq_printf(file,
125161 + " %-2u %-3s %-3s\n",
125162 + (i*32)+j,
125163 + (state.as.state.__state[i] & mask) ? "no" : "yes",
125164 + (state.ds.state.__state[i] & mask) ? "yes" : "no");
125165 + mask >>= 1;
125166 + }
125167 + }
125168 + return 0;
125169 +}
125170 +
125171 +static int query_bp_state_open(struct inode *inode, struct file *file)
125172 +{
125173 + return single_open(file, query_bp_state_show, NULL);
125174 +}
125175 +
125176 +static const struct file_operations query_bp_state_fops = {
125177 + .owner = THIS_MODULE,
125178 + .open = query_bp_state_open,
125179 + .read = seq_read,
125180 + .release = single_release,
125181 +};
125182 +
125183 +static int __init bman_debugfs_module_init(void)
125184 +{
125185 + int ret = 0;
125186 + struct dentry *d;
125187 +
125188 + dfs_root = debugfs_create_dir("bman", NULL);
125189 +
125190 + if (dfs_root == NULL) {
125191 + ret = -ENOMEM;
125192 + pr_err("Cannot create bman debugfs dir\n");
125193 + goto _return;
125194 + }
125195 + d = debugfs_create_file("query_bp_state",
125196 + S_IRUGO,
125197 + dfs_root,
125198 + NULL,
125199 + &query_bp_state_fops);
125200 + if (d == NULL) {
125201 + ret = -ENOMEM;
125202 + pr_err("Cannot create query_bp_state\n");
125203 + goto _return;
125204 + }
125205 + return 0;
125206 +
125207 +_return:
125208 + debugfs_remove_recursive(dfs_root);
125209 + return ret;
125210 +}
125211 +
125212 +static void __exit bman_debugfs_module_exit(void)
125213 +{
125214 + debugfs_remove_recursive(dfs_root);
125215 +}
125216 +
125217 +
125218 +module_init(bman_debugfs_module_init);
125219 +module_exit(bman_debugfs_module_exit);
125220 +MODULE_LICENSE("Dual BSD/GPL");
125221 --- /dev/null
125222 +++ b/drivers/staging/fsl_qbman/bman_driver.c
125223 @@ -0,0 +1,575 @@
125224 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
125225 + *
125226 + * Redistribution and use in source and binary forms, with or without
125227 + * modification, are permitted provided that the following conditions are met:
125228 + * * Redistributions of source code must retain the above copyright
125229 + * notice, this list of conditions and the following disclaimer.
125230 + * * Redistributions in binary form must reproduce the above copyright
125231 + * notice, this list of conditions and the following disclaimer in the
125232 + * documentation and/or other materials provided with the distribution.
125233 + * * Neither the name of Freescale Semiconductor nor the
125234 + * names of its contributors may be used to endorse or promote products
125235 + * derived from this software without specific prior written permission.
125236 + *
125237 + *
125238 + * ALTERNATIVELY, this software may be distributed under the terms of the
125239 + * GNU General Public License ("GPL") as published by the Free Software
125240 + * Foundation, either version 2 of that License or (at your option) any
125241 + * later version.
125242 + *
125243 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125244 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125245 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125246 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125247 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125248 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125249 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125250 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125251 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125252 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125253 + */
125254 +#include "bman_low.h"
125255 +#ifdef CONFIG_HOTPLUG_CPU
125256 +#include <linux/cpu.h>
125257 +#endif
125258 +/*
125259 + * Global variables of the max portal/pool number this bman version supported
125260 + */
125261 +u16 bman_ip_rev;
125262 +EXPORT_SYMBOL(bman_ip_rev);
125263 +u16 bman_pool_max;
125264 +EXPORT_SYMBOL(bman_pool_max);
125265 +static u16 bman_portal_max;
125266 +
125267 +/* After initialising cpus that own shared portal configs, we cache the
125268 + * resulting portals (ie. not just the configs) in this array. Then we
125269 + * initialise slave cpus that don't have their own portals, redirecting them to
125270 + * portals from this cache in a round-robin assignment. */
125271 +static struct bman_portal *shared_portals[NR_CPUS];
125272 +static int num_shared_portals;
125273 +static int shared_portals_idx;
125274 +static LIST_HEAD(unused_pcfgs);
125275 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
125276 +static void *affine_bportals[NR_CPUS];
125277 +
125278 +static int __init fsl_bpool_init(struct device_node *node)
125279 +{
125280 + int ret;
125281 + u32 *thresh, *bpid = (u32 *)of_get_property(node, "fsl,bpid", &ret);
125282 + if (!bpid || (ret != 4)) {
125283 + pr_err("Can't get %s property 'fsl,bpid'\n", node->full_name);
125284 + return -ENODEV;
125285 + }
125286 + thresh = (u32 *)of_get_property(node, "fsl,bpool-thresholds", &ret);
125287 + if (thresh) {
125288 + if (ret != 16) {
125289 + pr_err("Invalid %s property '%s'\n",
125290 + node->full_name, "fsl,bpool-thresholds");
125291 + return -ENODEV;
125292 + }
125293 + }
125294 + if (thresh) {
125295 +#ifdef CONFIG_FSL_BMAN_CONFIG
125296 + ret = bm_pool_set(be32_to_cpu(*bpid), thresh);
125297 + if (ret)
125298 + pr_err("No CCSR node for %s property '%s'\n",
125299 + node->full_name, "fsl,bpool-thresholds");
125300 + return ret;
125301 +#else
125302 + pr_err("Ignoring %s property '%s', no CCSR support\n",
125303 + node->full_name, "fsl,bpool-thresholds");
125304 +#endif
125305 + }
125306 + return 0;
125307 +}
125308 +
125309 +static int __init fsl_bpid_range_init(struct device_node *node)
125310 +{
125311 + int ret;
125312 + u32 *range = (u32 *)of_get_property(node, "fsl,bpid-range", &ret);
125313 + if (!range) {
125314 + pr_err("No 'fsl,bpid-range' property in node %s\n",
125315 + node->full_name);
125316 + return -EINVAL;
125317 + }
125318 + if (ret != 8) {
125319 + pr_err("'fsl,bpid-range' is not a 2-cell range in node %s\n",
125320 + node->full_name);
125321 + return -EINVAL;
125322 + }
125323 + bman_seed_bpid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125324 + pr_info("Bman: BPID allocator includes range %d:%d\n",
125325 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125326 + return 0;
125327 +}
125328 +
125329 +static struct bm_portal_config * __init parse_pcfg(struct device_node *node)
125330 +{
125331 + struct bm_portal_config *pcfg;
125332 + const u32 *index;
125333 + int irq, ret;
125334 + resource_size_t len;
125335 +
125336 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
125337 + if (!pcfg) {
125338 + pr_err("can't allocate portal config");
125339 + return NULL;
125340 + }
125341 +
125342 + if (of_device_is_compatible(node, "fsl,bman-portal-1.0") ||
125343 + of_device_is_compatible(node, "fsl,bman-portal-1.0.0")) {
125344 + bman_ip_rev = BMAN_REV10;
125345 + bman_pool_max = 64;
125346 + bman_portal_max = 10;
125347 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.0") ||
125348 + of_device_is_compatible(node, "fsl,bman-portal-2.0.8")) {
125349 + bman_ip_rev = BMAN_REV20;
125350 + bman_pool_max = 8;
125351 + bman_portal_max = 3;
125352 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.0")) {
125353 + bman_ip_rev = BMAN_REV21;
125354 + bman_pool_max = 64;
125355 + bman_portal_max = 50;
125356 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.1")) {
125357 + bman_ip_rev = BMAN_REV21;
125358 + bman_pool_max = 64;
125359 + bman_portal_max = 25;
125360 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.2")) {
125361 + bman_ip_rev = BMAN_REV21;
125362 + bman_pool_max = 64;
125363 + bman_portal_max = 18;
125364 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.3")) {
125365 + bman_ip_rev = BMAN_REV21;
125366 + bman_pool_max = 64;
125367 + bman_portal_max = 10;
125368 + } else {
125369 + pr_warn("unknown BMan version in portal node,"
125370 + "default to rev1.0\n");
125371 + bman_ip_rev = BMAN_REV10;
125372 + bman_pool_max = 64;
125373 + bman_portal_max = 10;
125374 + }
125375 +
125376 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
125377 + &pcfg->addr_phys[DPA_PORTAL_CE]);
125378 + if (ret) {
125379 + pr_err("Can't get %s property 'reg::CE'\n", node->full_name);
125380 + goto err;
125381 + }
125382 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
125383 + &pcfg->addr_phys[DPA_PORTAL_CI]);
125384 + if (ret) {
125385 + pr_err("Can't get %s property 'reg::CI'\n", node->full_name);
125386 + goto err;
125387 + }
125388 +
125389 + index = of_get_property(node, "cell-index", &ret);
125390 + if (!index || (ret != 4)) {
125391 + pr_err("Can't get %s property '%s'\n", node->full_name,
125392 + "cell-index");
125393 + goto err;
125394 + }
125395 + if (be32_to_cpu(*index) >= bman_portal_max) {
125396 + pr_err("BMan portal cell index %d out of range, max %d\n",
125397 + be32_to_cpu(*index), bman_portal_max);
125398 + goto err;
125399 + }
125400 +
125401 + pcfg->public_cfg.cpu = -1;
125402 +
125403 + irq = irq_of_parse_and_map(node, 0);
125404 + if (irq == 0) {
125405 + pr_err("Can't get %s property 'interrupts'\n", node->full_name);
125406 + goto err;
125407 + }
125408 + pcfg->public_cfg.irq = irq;
125409 + pcfg->public_cfg.index = be32_to_cpu(*index);
125410 + bman_depletion_fill(&pcfg->public_cfg.mask);
125411 +
125412 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
125413 + if (len != (unsigned long)len)
125414 + goto err;
125415 +
125416 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
125417 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
125418 + pcfg->addr_phys[DPA_PORTAL_CE].start,
125419 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
125420 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
125421 + pcfg->addr_phys[DPA_PORTAL_CI].start,
125422 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
125423 +
125424 +#else
125425 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
125426 + pcfg->addr_phys[DPA_PORTAL_CE].start,
125427 + (unsigned long)len,
125428 + 0);
125429 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
125430 + pcfg->addr_phys[DPA_PORTAL_CI].start,
125431 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
125432 + _PAGE_GUARDED | _PAGE_NO_CACHE);
125433 +#endif
125434 + /* disable bp depletion */
125435 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(0));
125436 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(1));
125437 + return pcfg;
125438 +err:
125439 + kfree(pcfg);
125440 + return NULL;
125441 +}
125442 +
125443 +static struct bm_portal_config *get_pcfg(struct list_head *list)
125444 +{
125445 + struct bm_portal_config *pcfg;
125446 + if (list_empty(list))
125447 + return NULL;
125448 + pcfg = list_entry(list->prev, struct bm_portal_config, list);
125449 + list_del(&pcfg->list);
125450 + return pcfg;
125451 +}
125452 +
125453 +static struct bm_portal_config *get_pcfg_idx(struct list_head *list,
125454 + uint32_t idx)
125455 +{
125456 + struct bm_portal_config *pcfg;
125457 + if (list_empty(list))
125458 + return NULL;
125459 + list_for_each_entry(pcfg, list, list) {
125460 + if (pcfg->public_cfg.index == idx) {
125461 + list_del(&pcfg->list);
125462 + return pcfg;
125463 + }
125464 + }
125465 + return NULL;
125466 +}
125467 +
125468 +struct bm_portal_config *bm_get_unused_portal(void)
125469 +{
125470 + return bm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
125471 +}
125472 +
125473 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx)
125474 +{
125475 + struct bm_portal_config *ret;
125476 + spin_lock(&unused_pcfgs_lock);
125477 + if (idx == QBMAN_ANY_PORTAL_IDX)
125478 + ret = get_pcfg(&unused_pcfgs);
125479 + else
125480 + ret = get_pcfg_idx(&unused_pcfgs, idx);
125481 + spin_unlock(&unused_pcfgs_lock);
125482 + return ret;
125483 +}
125484 +
125485 +void bm_put_unused_portal(struct bm_portal_config *pcfg)
125486 +{
125487 + spin_lock(&unused_pcfgs_lock);
125488 + list_add(&pcfg->list, &unused_pcfgs);
125489 + spin_unlock(&unused_pcfgs_lock);
125490 +}
125491 +
125492 +static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg)
125493 +{
125494 + struct bman_portal *p;
125495 + p = bman_create_affine_portal(pcfg);
125496 + if (p) {
125497 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
125498 + bman_p_irqsource_add(p, BM_PIRQ_RCRI | BM_PIRQ_BSCN);
125499 +#endif
125500 + pr_info("Bman portal %sinitialised, cpu %d\n",
125501 + pcfg->public_cfg.is_shared ? "(shared) " : "",
125502 + pcfg->public_cfg.cpu);
125503 + affine_bportals[pcfg->public_cfg.cpu] = p;
125504 + } else
125505 + pr_crit("Bman portal failure on cpu %d\n",
125506 + pcfg->public_cfg.cpu);
125507 + return p;
125508 +}
125509 +
125510 +static void init_slave(int cpu)
125511 +{
125512 + struct bman_portal *p;
125513 + p = bman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
125514 + if (!p)
125515 + pr_err("Bman slave portal failure on cpu %d\n", cpu);
125516 + else
125517 + pr_info("Bman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
125518 + if (shared_portals_idx >= num_shared_portals)
125519 + shared_portals_idx = 0;
125520 + affine_bportals[cpu] = p;
125521 +}
125522 +
125523 +/* Bootarg "bportals=[...]" has the same syntax as "qportals=", and so the
125524 + * parsing is in dpa_sys.h. The syntax is a comma-separated list of indexes
125525 + * and/or ranges of indexes, with each being optionally prefixed by "s" to
125526 + * explicitly mark it or them for sharing.
125527 + * Eg;
125528 + * bportals=s0,1-3,s4
125529 + * means that cpus 1,2,3 get "unshared" portals, cpus 0 and 4 get "shared"
125530 + * portals, and any remaining cpus share the portals that are assigned to cpus 0
125531 + * or 4, selected in a round-robin fashion. (In this example, cpu 5 would share
125532 + * cpu 0's portal, cpu 6 would share cpu4's portal, and cpu 7 would share cpu
125533 + * 0's portal.) */
125534 +static struct cpumask want_unshared __initdata; /* cpus requested without "s" */
125535 +static struct cpumask want_shared __initdata; /* cpus requested with "s" */
125536 +
125537 +static int __init parse_bportals(char *str)
125538 +{
125539 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
125540 + "bportals");
125541 +}
125542 +__setup("bportals=", parse_bportals);
125543 +
125544 +static int bman_offline_cpu(unsigned int cpu)
125545 +{
125546 + struct bman_portal *p;
125547 + const struct bm_portal_config *pcfg;
125548 + p = (struct bman_portal *)affine_bportals[cpu];
125549 + if (p) {
125550 + pcfg = bman_get_bm_portal_config(p);
125551 + if (pcfg)
125552 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
125553 + }
125554 + return 0;
125555 +}
125556 +
125557 +#ifdef CONFIG_HOTPLUG_CPU
125558 +static int bman_online_cpu(unsigned int cpu)
125559 +{
125560 + struct bman_portal *p;
125561 + const struct bm_portal_config *pcfg;
125562 + p = (struct bman_portal *)affine_bportals[cpu];
125563 + if (p) {
125564 + pcfg = bman_get_bm_portal_config(p);
125565 + if (pcfg)
125566 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
125567 + }
125568 + return 0;
125569 +}
125570 +static int bman_hotplug_cpu_callback(struct notifier_block *nfb,
125571 + unsigned long action, void *hcpu)
125572 +{
125573 + unsigned int cpu = (unsigned long)hcpu;
125574 +
125575 + switch (action) {
125576 + case CPU_ONLINE:
125577 + case CPU_ONLINE_FROZEN:
125578 + bman_online_cpu(cpu);
125579 + break;
125580 + case CPU_DOWN_PREPARE:
125581 + case CPU_DOWN_PREPARE_FROZEN:
125582 + bman_offline_cpu(cpu);
125583 + default:
125584 + break;
125585 + }
125586 + return NOTIFY_OK;
125587 +}
125588 +
125589 +static struct notifier_block bman_hotplug_cpu_notifier = {
125590 + .notifier_call = bman_hotplug_cpu_callback,
125591 +};
125592 +#endif /* CONFIG_HOTPLUG_CPU */
125593 +
125594 +/* Initialise the Bman driver. The meat of this function deals with portals. The
125595 + * following describes the flow of portal-handling, the code "steps" refer to
125596 + * this description;
125597 + * 1. Portal configs are parsed from the device-tree into 'unused_pcfgs', with
125598 + * ::cpu==-1. Regions and interrupts are mapped (but interrupts are not
125599 + * bound).
125600 + * 2. The "want_shared" and "want_unshared" lists (as filled by the
125601 + * "bportals=[...]" bootarg) are processed, allocating portals and assigning
125602 + * them to cpus, placing them in the relevant list and setting ::cpu as
125603 + * appropriate. If no "bportals" bootarg was present, the defaut is to try to
125604 + * assign portals to all online cpus at the time of driver initialisation.
125605 + * Any failure to allocate portals (when parsing the "want" lists or when
125606 + * using default behaviour) will be silently tolerated (the "fixup" logic in
125607 + * step 3 will determine what happens in this case).
125608 + * 3. Do fixups relative to cpu_online_mask(). If no portals are marked for
125609 + * sharing and sharing is required (because not all cpus have been assigned
125610 + * portals), then one portal will marked for sharing. Conversely if no
125611 + * sharing is required, any portals marked for sharing will not be shared. It
125612 + * may be that sharing occurs when it wasn't expected, if portal allocation
125613 + * failed to honour all the requested assignments (including the default
125614 + * assignments if no bootarg is present).
125615 + * 4. Unshared portals are initialised on their respective cpus.
125616 + * 5. Shared portals are initialised on their respective cpus.
125617 + * 6. Each remaining cpu is initialised to slave to one of the shared portals,
125618 + * which are selected in a round-robin fashion.
125619 + * Any portal configs left unused are available for USDPAA allocation.
125620 + */
125621 +__init int bman_init(void)
125622 +{
125623 + struct cpumask slave_cpus;
125624 + struct cpumask unshared_cpus = *cpu_none_mask;
125625 + struct cpumask shared_cpus = *cpu_none_mask;
125626 + LIST_HEAD(unshared_pcfgs);
125627 + LIST_HEAD(shared_pcfgs);
125628 + struct device_node *dn;
125629 + struct bm_portal_config *pcfg;
125630 + struct bman_portal *p;
125631 + int cpu, ret;
125632 + struct cpumask offline_cpus;
125633 +
125634 + /* Initialise the Bman (CCSR) device */
125635 + for_each_compatible_node(dn, NULL, "fsl,bman") {
125636 + if (!bman_init_ccsr(dn))
125637 + pr_info("Bman err interrupt handler present\n");
125638 + else
125639 + pr_err("Bman CCSR setup failed\n");
125640 + }
125641 + /* Initialise any declared buffer pools */
125642 + for_each_compatible_node(dn, NULL, "fsl,bpool") {
125643 + ret = fsl_bpool_init(dn);
125644 + if (ret)
125645 + return ret;
125646 + }
125647 + /* Step 1. See comments at the beginning of the file. */
125648 + for_each_compatible_node(dn, NULL, "fsl,bman-portal") {
125649 + if (!of_device_is_available(dn))
125650 + continue;
125651 + pcfg = parse_pcfg(dn);
125652 + if (pcfg)
125653 + list_add_tail(&pcfg->list, &unused_pcfgs);
125654 + }
125655 + /* Step 2. */
125656 + for_each_possible_cpu(cpu) {
125657 + if (cpumask_test_cpu(cpu, &want_shared)) {
125658 + pcfg = get_pcfg(&unused_pcfgs);
125659 + if (!pcfg)
125660 + break;
125661 + pcfg->public_cfg.cpu = cpu;
125662 + list_add_tail(&pcfg->list, &shared_pcfgs);
125663 + cpumask_set_cpu(cpu, &shared_cpus);
125664 + }
125665 + if (cpumask_test_cpu(cpu, &want_unshared)) {
125666 + if (cpumask_test_cpu(cpu, &shared_cpus))
125667 + continue;
125668 + pcfg = get_pcfg(&unused_pcfgs);
125669 + if (!pcfg)
125670 + break;
125671 + pcfg->public_cfg.cpu = cpu;
125672 + list_add_tail(&pcfg->list, &unshared_pcfgs);
125673 + cpumask_set_cpu(cpu, &unshared_cpus);
125674 + }
125675 + }
125676 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
125677 + /* Default, give an unshared portal to each online cpu */
125678 + for_each_online_cpu(cpu) {
125679 + pcfg = get_pcfg(&unused_pcfgs);
125680 + if (!pcfg)
125681 + break;
125682 + pcfg->public_cfg.cpu = cpu;
125683 + list_add_tail(&pcfg->list, &unshared_pcfgs);
125684 + cpumask_set_cpu(cpu, &unshared_cpus);
125685 + }
125686 + }
125687 + /* Step 3. */
125688 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
125689 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
125690 + if (cpumask_empty(&slave_cpus)) {
125691 + /* No sharing required */
125692 + if (!list_empty(&shared_pcfgs)) {
125693 + /* Migrate "shared" to "unshared" */
125694 + cpumask_or(&unshared_cpus, &unshared_cpus,
125695 + &shared_cpus);
125696 + cpumask_clear(&shared_cpus);
125697 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
125698 + INIT_LIST_HEAD(&shared_pcfgs);
125699 + }
125700 + } else {
125701 + /* Sharing required */
125702 + if (list_empty(&shared_pcfgs)) {
125703 + /* Migrate one "unshared" to "shared" */
125704 + pcfg = get_pcfg(&unshared_pcfgs);
125705 + if (!pcfg) {
125706 + pr_crit("No BMan portals available!\n");
125707 + return 0;
125708 + }
125709 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
125710 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
125711 + list_add_tail(&pcfg->list, &shared_pcfgs);
125712 + }
125713 + }
125714 + /* Step 4. */
125715 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
125716 + pcfg->public_cfg.is_shared = 0;
125717 + p = init_pcfg(pcfg);
125718 + if (!p) {
125719 + pr_crit("Unable to initialize bman portal\n");
125720 + return 0;
125721 + }
125722 + }
125723 + /* Step 5. */
125724 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
125725 + pcfg->public_cfg.is_shared = 1;
125726 + p = init_pcfg(pcfg);
125727 + if (p)
125728 + shared_portals[num_shared_portals++] = p;
125729 + }
125730 + /* Step 6. */
125731 + if (!cpumask_empty(&slave_cpus))
125732 + for_each_cpu(cpu, &slave_cpus)
125733 + init_slave(cpu);
125734 + pr_info("Bman portals initialised\n");
125735 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
125736 + for_each_cpu(cpu, &offline_cpus)
125737 + bman_offline_cpu(cpu);
125738 +#ifdef CONFIG_HOTPLUG_CPU
125739 + register_hotcpu_notifier(&bman_hotplug_cpu_notifier);
125740 +#endif
125741 + return 0;
125742 +}
125743 +
125744 +__init int bman_resource_init(void)
125745 +{
125746 + struct device_node *dn;
125747 + int ret;
125748 +
125749 + /* Initialise BPID allocation ranges */
125750 + for_each_compatible_node(dn, NULL, "fsl,bpid-range") {
125751 + ret = fsl_bpid_range_init(dn);
125752 + if (ret)
125753 + return ret;
125754 + }
125755 + return 0;
125756 +}
125757 +
125758 +#ifdef CONFIG_SUSPEND
125759 +void suspend_unused_bportal(void)
125760 +{
125761 + struct bm_portal_config *pcfg;
125762 +
125763 + if (list_empty(&unused_pcfgs))
125764 + return;
125765 +
125766 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
125767 +#ifdef CONFIG_PM_DEBUG
125768 + pr_info("Need to save bportal %d\n", pcfg->public_cfg.index);
125769 +#endif
125770 + /* save isdr, disable all via isdr, clear isr */
125771 + pcfg->saved_isdr =
125772 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
125773 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
125774 + 0xe08);
125775 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
125776 + 0xe00);
125777 + }
125778 + return;
125779 +}
125780 +
125781 +void resume_unused_bportal(void)
125782 +{
125783 + struct bm_portal_config *pcfg;
125784 +
125785 + if (list_empty(&unused_pcfgs))
125786 + return;
125787 +
125788 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
125789 +#ifdef CONFIG_PM_DEBUG
125790 + pr_info("Need to resume bportal %d\n", pcfg->public_cfg.index);
125791 +#endif
125792 + /* restore isdr */
125793 + __raw_writel(pcfg->saved_isdr,
125794 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
125795 + }
125796 + return;
125797 +}
125798 +#endif
125799 --- /dev/null
125800 +++ b/drivers/staging/fsl_qbman/bman_high.c
125801 @@ -0,0 +1,1145 @@
125802 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
125803 + *
125804 + * Redistribution and use in source and binary forms, with or without
125805 + * modification, are permitted provided that the following conditions are met:
125806 + * * Redistributions of source code must retain the above copyright
125807 + * notice, this list of conditions and the following disclaimer.
125808 + * * Redistributions in binary form must reproduce the above copyright
125809 + * notice, this list of conditions and the following disclaimer in the
125810 + * documentation and/or other materials provided with the distribution.
125811 + * * Neither the name of Freescale Semiconductor nor the
125812 + * names of its contributors may be used to endorse or promote products
125813 + * derived from this software without specific prior written permission.
125814 + *
125815 + *
125816 + * ALTERNATIVELY, this software may be distributed under the terms of the
125817 + * GNU General Public License ("GPL") as published by the Free Software
125818 + * Foundation, either version 2 of that License or (at your option) any
125819 + * later version.
125820 + *
125821 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125822 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125823 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125824 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125825 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125826 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125827 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125828 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125829 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125830 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125831 + */
125832 +
125833 +#include "bman_low.h"
125834 +
125835 +/* Compilation constants */
125836 +#define RCR_THRESH 2 /* reread h/w CI when running out of space */
125837 +#define IRQNAME "BMan portal %d"
125838 +#define MAX_IRQNAME 16 /* big enough for "BMan portal %d" */
125839 +
125840 +struct bman_portal {
125841 + struct bm_portal p;
125842 + /* 2-element array. pools[0] is mask, pools[1] is snapshot. */
125843 + struct bman_depletion *pools;
125844 + int thresh_set;
125845 + unsigned long irq_sources;
125846 + u32 slowpoll; /* only used when interrupts are off */
125847 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
125848 + struct bman_pool *rcri_owned; /* only 1 release WAIT_SYNC at a time */
125849 +#endif
125850 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
125851 + raw_spinlock_t sharing_lock; /* only used if is_shared */
125852 + int is_shared;
125853 + struct bman_portal *sharing_redirect;
125854 +#endif
125855 + /* When the cpu-affine portal is activated, this is non-NULL */
125856 + const struct bm_portal_config *config;
125857 + /* This is needed for power management */
125858 + struct platform_device *pdev;
125859 + /* 64-entry hash-table of pool objects that are tracking depletion
125860 + * entry/exit (ie. BMAN_POOL_FLAG_DEPLETION). This isn't fast-path, so
125861 + * we're not fussy about cache-misses and so forth - whereas the above
125862 + * members should all fit in one cacheline.
125863 + * BTW, with 64 entries in the hash table and 64 buffer pools to track,
125864 + * you'll never guess the hash-function ... */
125865 + struct bman_pool *cb[64];
125866 + char irqname[MAX_IRQNAME];
125867 + /* Track if the portal was alloced by the driver */
125868 + u8 alloced;
125869 + /* power management data */
125870 + u32 save_isdr;
125871 +};
125872 +
125873 +/* For an explanation of the locking, redirection, or affine-portal logic,
125874 + * please consult the Qman driver for details. This is the same, only simpler
125875 + * (no fiddly Qman-specific bits.) */
125876 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
125877 +#define PORTAL_IRQ_LOCK(p, irqflags) \
125878 + do { \
125879 + if ((p)->is_shared) \
125880 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
125881 + else \
125882 + local_irq_save(irqflags); \
125883 + } while (0)
125884 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
125885 + do { \
125886 + if ((p)->is_shared) \
125887 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
125888 + irqflags); \
125889 + else \
125890 + local_irq_restore(irqflags); \
125891 + } while (0)
125892 +#else
125893 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
125894 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
125895 +#endif
125896 +
125897 +static cpumask_t affine_mask;
125898 +static DEFINE_SPINLOCK(affine_mask_lock);
125899 +static DEFINE_PER_CPU(struct bman_portal, bman_affine_portal);
125900 +static inline struct bman_portal *get_raw_affine_portal(void)
125901 +{
125902 + return &get_cpu_var(bman_affine_portal);
125903 +}
125904 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
125905 +static inline struct bman_portal *get_affine_portal(void)
125906 +{
125907 + struct bman_portal *p = get_raw_affine_portal();
125908 + if (p->sharing_redirect)
125909 + return p->sharing_redirect;
125910 + return p;
125911 +}
125912 +#else
125913 +#define get_affine_portal() get_raw_affine_portal()
125914 +#endif
125915 +static inline void put_affine_portal(void)
125916 +{
125917 + put_cpu_var(bman_affine_portal);
125918 +}
125919 +static inline struct bman_portal *get_poll_portal(void)
125920 +{
125921 + return &get_cpu_var(bman_affine_portal);
125922 +}
125923 +#define put_poll_portal()
125924 +
125925 +/* GOTCHA: this object type refers to a pool, it isn't *the* pool. There may be
125926 + * more than one such object per Bman buffer pool, eg. if different users of the
125927 + * pool are operating via different portals. */
125928 +struct bman_pool {
125929 + struct bman_pool_params params;
125930 + /* Used for hash-table admin when using depletion notifications. */
125931 + struct bman_portal *portal;
125932 + struct bman_pool *next;
125933 + /* stockpile state - NULL unless BMAN_POOL_FLAG_STOCKPILE is set */
125934 + struct bm_buffer *sp;
125935 + unsigned int sp_fill;
125936 +#ifdef CONFIG_FSL_DPA_CHECKING
125937 + atomic_t in_use;
125938 +#endif
125939 +};
125940 +
125941 +/* (De)Registration of depletion notification callbacks */
125942 +static void depletion_link(struct bman_portal *portal, struct bman_pool *pool)
125943 +{
125944 + __maybe_unused unsigned long irqflags;
125945 + pool->portal = portal;
125946 + PORTAL_IRQ_LOCK(portal, irqflags);
125947 + pool->next = portal->cb[pool->params.bpid];
125948 + portal->cb[pool->params.bpid] = pool;
125949 + if (!pool->next)
125950 + /* First object for that bpid on this portal, enable the BSCN
125951 + * mask bit. */
125952 + bm_isr_bscn_mask(&portal->p, pool->params.bpid, 1);
125953 + PORTAL_IRQ_UNLOCK(portal, irqflags);
125954 +}
125955 +static void depletion_unlink(struct bman_pool *pool)
125956 +{
125957 + struct bman_pool *it, *last = NULL;
125958 + struct bman_pool **base = &pool->portal->cb[pool->params.bpid];
125959 + __maybe_unused unsigned long irqflags;
125960 + PORTAL_IRQ_LOCK(pool->portal, irqflags);
125961 + it = *base; /* <-- gotcha, don't do this prior to the irq_save */
125962 + while (it != pool) {
125963 + last = it;
125964 + it = it->next;
125965 + }
125966 + if (!last)
125967 + *base = pool->next;
125968 + else
125969 + last->next = pool->next;
125970 + if (!last && !pool->next) {
125971 + /* Last object for that bpid on this portal, disable the BSCN
125972 + * mask bit. */
125973 + bm_isr_bscn_mask(&pool->portal->p, pool->params.bpid, 0);
125974 + /* And "forget" that we last saw this pool as depleted */
125975 + bman_depletion_unset(&pool->portal->pools[1],
125976 + pool->params.bpid);
125977 + }
125978 + PORTAL_IRQ_UNLOCK(pool->portal, irqflags);
125979 +}
125980 +
125981 +/* In the case that the application's core loop calls qman_poll() and
125982 + * bman_poll(), we ought to balance how often we incur the overheads of the
125983 + * slow-path poll. We'll use two decrementer sources. The idle decrementer
125984 + * constant is used when the last slow-poll detected no work to do, and the busy
125985 + * decrementer constant when the last slow-poll had work to do. */
125986 +#define SLOW_POLL_IDLE 1000
125987 +#define SLOW_POLL_BUSY 10
125988 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is);
125989 +
125990 +/* Portal interrupt handler */
125991 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
125992 +{
125993 + struct bman_portal *p = ptr;
125994 + u32 clear = p->irq_sources;
125995 + u32 is = bm_isr_status_read(&p->p) & p->irq_sources;
125996 + clear |= __poll_portal_slow(p, is);
125997 + bm_isr_status_clear(&p->p, clear);
125998 + return IRQ_HANDLED;
125999 +}
126000 +
126001 +#ifdef CONFIG_SUSPEND
126002 +static int _bman_portal_suspend_noirq(struct device *dev)
126003 +{
126004 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
126005 +#ifdef CONFIG_PM_DEBUG
126006 + struct platform_device *pdev = to_platform_device(dev);
126007 +#endif
126008 + p->save_isdr = bm_isr_disable_read(&p->p);
126009 + bm_isr_disable_write(&p->p, 0xffffffff);
126010 + bm_isr_status_clear(&p->p, 0xffffffff);
126011 +#ifdef CONFIG_PM_DEBUG
126012 + pr_info("Suspend for %s\n", pdev->name);
126013 +#endif
126014 + return 0;
126015 +}
126016 +
126017 +static int _bman_portal_resume_noirq(struct device *dev)
126018 +{
126019 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
126020 +
126021 + /* restore isdr */
126022 + bm_isr_disable_write(&p->p, p->save_isdr);
126023 + return 0;
126024 +}
126025 +#else
126026 +#define _bman_portal_suspend_noirq NULL
126027 +#define _bman_portal_resume_noirq NULL
126028 +#endif
126029 +
126030 +struct dev_pm_domain bman_portal_device_pm_domain = {
126031 + .ops = {
126032 + USE_PLATFORM_PM_SLEEP_OPS
126033 + .suspend_noirq = _bman_portal_suspend_noirq,
126034 + .resume_noirq = _bman_portal_resume_noirq,
126035 + }
126036 +};
126037 +
126038 +struct bman_portal *bman_create_portal(
126039 + struct bman_portal *portal,
126040 + const struct bm_portal_config *config)
126041 +{
126042 + struct bm_portal *__p;
126043 + const struct bman_depletion *pools = &config->public_cfg.mask;
126044 + int ret;
126045 + u8 bpid = 0;
126046 + char buf[16];
126047 +
126048 + if (!portal) {
126049 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
126050 + if (!portal)
126051 + return portal;
126052 + portal->alloced = 1;
126053 + } else
126054 + portal->alloced = 0;
126055 +
126056 + __p = &portal->p;
126057 +
126058 + /* prep the low-level portal struct with the mapped addresses from the
126059 + * config, everything that follows depends on it and "config" is more
126060 + * for (de)reference... */
126061 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
126062 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
126063 + if (bm_rcr_init(__p, bm_rcr_pvb, bm_rcr_cce)) {
126064 + pr_err("Bman RCR initialisation failed\n");
126065 + goto fail_rcr;
126066 + }
126067 + if (bm_mc_init(__p)) {
126068 + pr_err("Bman MC initialisation failed\n");
126069 + goto fail_mc;
126070 + }
126071 + if (bm_isr_init(__p)) {
126072 + pr_err("Bman ISR initialisation failed\n");
126073 + goto fail_isr;
126074 + }
126075 + portal->pools = kmalloc(2 * sizeof(*pools), GFP_KERNEL);
126076 + if (!portal->pools)
126077 + goto fail_pools;
126078 + portal->pools[0] = *pools;
126079 + bman_depletion_init(portal->pools + 1);
126080 + while (bpid < bman_pool_max) {
126081 + /* Default to all BPIDs disabled, we enable as required at
126082 + * run-time. */
126083 + bm_isr_bscn_mask(__p, bpid, 0);
126084 + bpid++;
126085 + }
126086 + portal->slowpoll = 0;
126087 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126088 + portal->rcri_owned = NULL;
126089 +#endif
126090 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126091 + raw_spin_lock_init(&portal->sharing_lock);
126092 + portal->is_shared = config->public_cfg.is_shared;
126093 + portal->sharing_redirect = NULL;
126094 +#endif
126095 + sprintf(buf, "bportal-%u", config->public_cfg.index);
126096 + portal->pdev = platform_device_alloc(buf, -1);
126097 + if (!portal->pdev)
126098 + goto fail_devalloc;
126099 + portal->pdev->dev.pm_domain = &bman_portal_device_pm_domain;
126100 + portal->pdev->dev.platform_data = portal;
126101 + ret = platform_device_add(portal->pdev);
126102 + if (ret)
126103 + goto fail_devadd;
126104 + memset(&portal->cb, 0, sizeof(portal->cb));
126105 + /* Write-to-clear any stale interrupt status bits */
126106 + bm_isr_disable_write(__p, 0xffffffff);
126107 + portal->irq_sources = 0;
126108 + bm_isr_enable_write(__p, portal->irq_sources);
126109 + bm_isr_status_clear(__p, 0xffffffff);
126110 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
126111 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
126112 + portal)) {
126113 + pr_err("request_irq() failed\n");
126114 + goto fail_irq;
126115 + }
126116 + if ((config->public_cfg.cpu != -1) &&
126117 + irq_can_set_affinity(config->public_cfg.irq) &&
126118 + irq_set_affinity(config->public_cfg.irq,
126119 + cpumask_of(config->public_cfg.cpu))) {
126120 + pr_err("irq_set_affinity() failed %s\n", portal->irqname);
126121 + goto fail_affinity;
126122 + }
126123 +
126124 + /* Need RCR to be empty before continuing */
126125 + ret = bm_rcr_get_fill(__p);
126126 + if (ret) {
126127 + pr_err("Bman RCR unclean\n");
126128 + goto fail_rcr_empty;
126129 + }
126130 + /* Success */
126131 + portal->config = config;
126132 +
126133 + bm_isr_disable_write(__p, 0);
126134 + bm_isr_uninhibit(__p);
126135 + return portal;
126136 +fail_rcr_empty:
126137 +fail_affinity:
126138 + free_irq(config->public_cfg.irq, portal);
126139 +fail_irq:
126140 + platform_device_del(portal->pdev);
126141 +fail_devadd:
126142 + platform_device_put(portal->pdev);
126143 +fail_devalloc:
126144 + kfree(portal->pools);
126145 +fail_pools:
126146 + bm_isr_finish(__p);
126147 +fail_isr:
126148 + bm_mc_finish(__p);
126149 +fail_mc:
126150 + bm_rcr_finish(__p);
126151 +fail_rcr:
126152 + if (portal->alloced)
126153 + kfree(portal);
126154 + return NULL;
126155 +}
126156 +
126157 +struct bman_portal *bman_create_affine_portal(
126158 + const struct bm_portal_config *config)
126159 +{
126160 + struct bman_portal *portal;
126161 +
126162 + portal = &per_cpu(bman_affine_portal, config->public_cfg.cpu);
126163 + portal = bman_create_portal(portal, config);
126164 + if (portal) {
126165 + spin_lock(&affine_mask_lock);
126166 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
126167 + spin_unlock(&affine_mask_lock);
126168 + }
126169 + return portal;
126170 +}
126171 +
126172 +
126173 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
126174 + int cpu)
126175 +{
126176 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126177 + struct bman_portal *p;
126178 + p = &per_cpu(bman_affine_portal, cpu);
126179 + BUG_ON(p->config);
126180 + BUG_ON(p->is_shared);
126181 + BUG_ON(!redirect->config->public_cfg.is_shared);
126182 + p->irq_sources = 0;
126183 + p->sharing_redirect = redirect;
126184 + return p;
126185 +#else
126186 + BUG();
126187 + return NULL;
126188 +#endif
126189 +}
126190 +
126191 +void bman_destroy_portal(struct bman_portal *bm)
126192 +{
126193 + const struct bm_portal_config *pcfg;
126194 + pcfg = bm->config;
126195 + bm_rcr_cce_update(&bm->p);
126196 + bm_rcr_cce_update(&bm->p);
126197 +
126198 + free_irq(pcfg->public_cfg.irq, bm);
126199 +
126200 + kfree(bm->pools);
126201 + bm_isr_finish(&bm->p);
126202 + bm_mc_finish(&bm->p);
126203 + bm_rcr_finish(&bm->p);
126204 + bm->config = NULL;
126205 + if (bm->alloced)
126206 + kfree(bm);
126207 +}
126208 +
126209 +const struct bm_portal_config *bman_destroy_affine_portal(void)
126210 +{
126211 + struct bman_portal *bm = get_raw_affine_portal();
126212 + const struct bm_portal_config *pcfg;
126213 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126214 + if (bm->sharing_redirect) {
126215 + bm->sharing_redirect = NULL;
126216 + put_affine_portal();
126217 + return NULL;
126218 + }
126219 + bm->is_shared = 0;
126220 +#endif
126221 + pcfg = bm->config;
126222 + bman_destroy_portal(bm);
126223 + spin_lock(&affine_mask_lock);
126224 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &affine_mask);
126225 + spin_unlock(&affine_mask_lock);
126226 + put_affine_portal();
126227 + return pcfg;
126228 +}
126229 +
126230 +/* When release logic waits on available RCR space, we need a global waitqueue
126231 + * in the case of "affine" use (as the waits wake on different cpus which means
126232 + * different portals - so we can't wait on any per-portal waitqueue). */
126233 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
126234 +
126235 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is)
126236 +{
126237 + struct bman_depletion tmp;
126238 + u32 ret = is;
126239 +
126240 + /* There is a gotcha to be aware of. If we do the query before clearing
126241 + * the status register, we may miss state changes that occur between the
126242 + * two. If we write to clear the status register before the query, the
126243 + * cache-enabled query command may overtake the status register write
126244 + * unless we use a heavyweight sync (which we don't want). Instead, we
126245 + * write-to-clear the status register then *read it back* before doing
126246 + * the query, hence the odd while loop with the 'is' accumulation. */
126247 + if (is & BM_PIRQ_BSCN) {
126248 + struct bm_mc_result *mcr;
126249 + __maybe_unused unsigned long irqflags;
126250 + unsigned int i, j;
126251 + u32 __is;
126252 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126253 + while ((__is = bm_isr_status_read(&p->p)) & BM_PIRQ_BSCN) {
126254 + is |= __is;
126255 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126256 + }
126257 + is &= ~BM_PIRQ_BSCN;
126258 + PORTAL_IRQ_LOCK(p, irqflags);
126259 + bm_mc_start(&p->p);
126260 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
126261 + while (!(mcr = bm_mc_result(&p->p)))
126262 + cpu_relax();
126263 + tmp = mcr->query.ds.state;
126264 + tmp.__state[0] = be32_to_cpu(tmp.__state[0]);
126265 + tmp.__state[1] = be32_to_cpu(tmp.__state[1]);
126266 + PORTAL_IRQ_UNLOCK(p, irqflags);
126267 + for (i = 0; i < 2; i++) {
126268 + int idx = i * 32;
126269 + /* tmp is a mask of currently-depleted pools.
126270 + * pools[0] is mask of those we care about.
126271 + * pools[1] is our previous view (we only want to
126272 + * be told about changes). */
126273 + tmp.__state[i] &= p->pools[0].__state[i];
126274 + if (tmp.__state[i] == p->pools[1].__state[i])
126275 + /* fast-path, nothing to see, move along */
126276 + continue;
126277 + for (j = 0; j <= 31; j++, idx++) {
126278 + struct bman_pool *pool = p->cb[idx];
126279 + int b4 = bman_depletion_get(&p->pools[1], idx);
126280 + int af = bman_depletion_get(&tmp, idx);
126281 + if (b4 == af)
126282 + continue;
126283 + while (pool) {
126284 + pool->params.cb(p, pool,
126285 + pool->params.cb_ctx, af);
126286 + pool = pool->next;
126287 + }
126288 + }
126289 + }
126290 + p->pools[1] = tmp;
126291 + }
126292 +
126293 + if (is & BM_PIRQ_RCRI) {
126294 + __maybe_unused unsigned long irqflags;
126295 + PORTAL_IRQ_LOCK(p, irqflags);
126296 + bm_rcr_cce_update(&p->p);
126297 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126298 + /* If waiting for sync, we only cancel the interrupt threshold
126299 + * when the ring utilisation hits zero. */
126300 + if (p->rcri_owned) {
126301 + if (!bm_rcr_get_fill(&p->p)) {
126302 + p->rcri_owned = NULL;
126303 + bm_rcr_set_ithresh(&p->p, 0);
126304 + }
126305 + } else
126306 +#endif
126307 + bm_rcr_set_ithresh(&p->p, 0);
126308 + PORTAL_IRQ_UNLOCK(p, irqflags);
126309 + wake_up(&affine_queue);
126310 + bm_isr_status_clear(&p->p, BM_PIRQ_RCRI);
126311 + is &= ~BM_PIRQ_RCRI;
126312 + }
126313 +
126314 + /* There should be no status register bits left undefined */
126315 + DPA_ASSERT(!is);
126316 + return ret;
126317 +}
126318 +
126319 +const struct bman_portal_config *bman_get_portal_config(void)
126320 +{
126321 + struct bman_portal *p = get_affine_portal();
126322 + const struct bman_portal_config *ret = &p->config->public_cfg;
126323 + put_affine_portal();
126324 + return ret;
126325 +}
126326 +EXPORT_SYMBOL(bman_get_portal_config);
126327 +
126328 +u32 bman_irqsource_get(void)
126329 +{
126330 + struct bman_portal *p = get_raw_affine_portal();
126331 + u32 ret = p->irq_sources & BM_PIRQ_VISIBLE;
126332 + put_affine_portal();
126333 + return ret;
126334 +}
126335 +EXPORT_SYMBOL(bman_irqsource_get);
126336 +
126337 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits)
126338 +{
126339 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126340 + if (p->sharing_redirect)
126341 + return -EINVAL;
126342 + else
126343 +#endif
126344 + {
126345 + __maybe_unused unsigned long irqflags;
126346 + PORTAL_IRQ_LOCK(p, irqflags);
126347 + set_bits(bits & BM_PIRQ_VISIBLE, &p->irq_sources);
126348 + bm_isr_enable_write(&p->p, p->irq_sources);
126349 + PORTAL_IRQ_UNLOCK(p, irqflags);
126350 + }
126351 + return 0;
126352 +}
126353 +EXPORT_SYMBOL(bman_p_irqsource_add);
126354 +
126355 +int bman_irqsource_add(__maybe_unused u32 bits)
126356 +{
126357 + struct bman_portal *p = get_raw_affine_portal();
126358 + int ret = 0;
126359 + ret = bman_p_irqsource_add(p, bits);
126360 + put_affine_portal();
126361 + return ret;
126362 +}
126363 +EXPORT_SYMBOL(bman_irqsource_add);
126364 +
126365 +int bman_irqsource_remove(u32 bits)
126366 +{
126367 + struct bman_portal *p = get_raw_affine_portal();
126368 + __maybe_unused unsigned long irqflags;
126369 + u32 ier;
126370 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126371 + if (p->sharing_redirect) {
126372 + put_affine_portal();
126373 + return -EINVAL;
126374 + }
126375 +#endif
126376 + /* Our interrupt handler only processes+clears status register bits that
126377 + * are in p->irq_sources. As we're trimming that mask, if one of them
126378 + * were to assert in the status register just before we remove it from
126379 + * the enable register, there would be an interrupt-storm when we
126380 + * release the IRQ lock. So we wait for the enable register update to
126381 + * take effect in h/w (by reading it back) and then clear all other bits
126382 + * in the status register. Ie. we clear them from ISR once it's certain
126383 + * IER won't allow them to reassert. */
126384 + PORTAL_IRQ_LOCK(p, irqflags);
126385 + bits &= BM_PIRQ_VISIBLE;
126386 + clear_bits(bits, &p->irq_sources);
126387 + bm_isr_enable_write(&p->p, p->irq_sources);
126388 + ier = bm_isr_enable_read(&p->p);
126389 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
126390 + * data-dependency, ie. to protect against re-ordering. */
126391 + bm_isr_status_clear(&p->p, ~ier);
126392 + PORTAL_IRQ_UNLOCK(p, irqflags);
126393 + put_affine_portal();
126394 + return 0;
126395 +}
126396 +EXPORT_SYMBOL(bman_irqsource_remove);
126397 +
126398 +const cpumask_t *bman_affine_cpus(void)
126399 +{
126400 + return &affine_mask;
126401 +}
126402 +EXPORT_SYMBOL(bman_affine_cpus);
126403 +
126404 +u32 bman_poll_slow(void)
126405 +{
126406 + struct bman_portal *p = get_poll_portal();
126407 + u32 ret;
126408 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126409 + if (unlikely(p->sharing_redirect))
126410 + ret = (u32)-1;
126411 + else
126412 +#endif
126413 + {
126414 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
126415 + ret = __poll_portal_slow(p, is);
126416 + bm_isr_status_clear(&p->p, ret);
126417 + }
126418 + put_poll_portal();
126419 + return ret;
126420 +}
126421 +EXPORT_SYMBOL(bman_poll_slow);
126422 +
126423 +/* Legacy wrapper */
126424 +void bman_poll(void)
126425 +{
126426 + struct bman_portal *p = get_poll_portal();
126427 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126428 + if (unlikely(p->sharing_redirect))
126429 + goto done;
126430 +#endif
126431 + if (!(p->slowpoll--)) {
126432 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
126433 + u32 active = __poll_portal_slow(p, is);
126434 + if (active)
126435 + p->slowpoll = SLOW_POLL_BUSY;
126436 + else
126437 + p->slowpoll = SLOW_POLL_IDLE;
126438 + }
126439 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126440 +done:
126441 +#endif
126442 + put_poll_portal();
126443 +}
126444 +EXPORT_SYMBOL(bman_poll);
126445 +
126446 +static const u32 zero_thresholds[4] = {0, 0, 0, 0};
126447 +
126448 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params)
126449 +{
126450 + struct bman_pool *pool = NULL;
126451 + u32 bpid;
126452 +
126453 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID) {
126454 + int ret = bman_alloc_bpid(&bpid);
126455 + if (ret)
126456 + return NULL;
126457 + } else {
126458 + if (params->bpid >= bman_pool_max)
126459 + return NULL;
126460 + bpid = params->bpid;
126461 + }
126462 +#ifdef CONFIG_FSL_BMAN_CONFIG
126463 + if (params->flags & BMAN_POOL_FLAG_THRESH) {
126464 + int ret = bm_pool_set(bpid, params->thresholds);
126465 + if (ret)
126466 + goto err;
126467 + }
126468 +#else
126469 + if (params->flags & BMAN_POOL_FLAG_THRESH)
126470 + goto err;
126471 +#endif
126472 + pool = kmalloc(sizeof(*pool), GFP_KERNEL);
126473 + if (!pool)
126474 + goto err;
126475 + pool->sp = NULL;
126476 + pool->sp_fill = 0;
126477 + pool->params = *params;
126478 +#ifdef CONFIG_FSL_DPA_CHECKING
126479 + atomic_set(&pool->in_use, 1);
126480 +#endif
126481 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126482 + pool->params.bpid = bpid;
126483 + if (params->flags & BMAN_POOL_FLAG_STOCKPILE) {
126484 + pool->sp = kmalloc(sizeof(struct bm_buffer) * BMAN_STOCKPILE_SZ,
126485 + GFP_KERNEL);
126486 + if (!pool->sp)
126487 + goto err;
126488 + }
126489 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION) {
126490 + struct bman_portal *p = get_affine_portal();
126491 + if (!p->pools || !bman_depletion_get(&p->pools[0], bpid)) {
126492 + pr_err("Depletion events disabled for bpid %d\n", bpid);
126493 + goto err;
126494 + }
126495 + depletion_link(p, pool);
126496 + put_affine_portal();
126497 + }
126498 + return pool;
126499 +err:
126500 +#ifdef CONFIG_FSL_BMAN_CONFIG
126501 + if (params->flags & BMAN_POOL_FLAG_THRESH)
126502 + bm_pool_set(bpid, zero_thresholds);
126503 +#endif
126504 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126505 + bman_release_bpid(bpid);
126506 + if (pool) {
126507 + kfree(pool->sp);
126508 + kfree(pool);
126509 + }
126510 + return NULL;
126511 +}
126512 +EXPORT_SYMBOL(bman_new_pool);
126513 +
126514 +void bman_free_pool(struct bman_pool *pool)
126515 +{
126516 +#ifdef CONFIG_FSL_BMAN_CONFIG
126517 + if (pool->params.flags & BMAN_POOL_FLAG_THRESH)
126518 + bm_pool_set(pool->params.bpid, zero_thresholds);
126519 +#endif
126520 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION)
126521 + depletion_unlink(pool);
126522 + if (pool->params.flags & BMAN_POOL_FLAG_STOCKPILE) {
126523 + if (pool->sp_fill)
126524 + pr_err("Stockpile not flushed, has %u in bpid %u.\n",
126525 + pool->sp_fill, pool->params.bpid);
126526 + kfree(pool->sp);
126527 + pool->sp = NULL;
126528 + pool->params.flags ^= BMAN_POOL_FLAG_STOCKPILE;
126529 + }
126530 + if (pool->params.flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126531 + bman_release_bpid(pool->params.bpid);
126532 + kfree(pool);
126533 +}
126534 +EXPORT_SYMBOL(bman_free_pool);
126535 +
126536 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool)
126537 +{
126538 + return &pool->params;
126539 +}
126540 +EXPORT_SYMBOL(bman_get_params);
126541 +
126542 +static noinline void update_rcr_ci(struct bman_portal *p, u8 avail)
126543 +{
126544 + if (avail)
126545 + bm_rcr_cce_prefetch(&p->p);
126546 + else
126547 + bm_rcr_cce_update(&p->p);
126548 +}
126549 +
126550 +int bman_rcr_is_empty(void)
126551 +{
126552 + __maybe_unused unsigned long irqflags;
126553 + struct bman_portal *p = get_affine_portal();
126554 + u8 avail;
126555 +
126556 + PORTAL_IRQ_LOCK(p, irqflags);
126557 + update_rcr_ci(p, 0);
126558 + avail = bm_rcr_get_fill(&p->p);
126559 + PORTAL_IRQ_UNLOCK(p, irqflags);
126560 + put_affine_portal();
126561 + return avail == 0;
126562 +}
126563 +EXPORT_SYMBOL(bman_rcr_is_empty);
126564 +
126565 +static inline struct bm_rcr_entry *try_rel_start(struct bman_portal **p,
126566 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126567 + __maybe_unused struct bman_pool *pool,
126568 +#endif
126569 + __maybe_unused unsigned long *irqflags,
126570 + __maybe_unused u32 flags)
126571 +{
126572 + struct bm_rcr_entry *r;
126573 + u8 avail;
126574 +
126575 + *p = get_affine_portal();
126576 + PORTAL_IRQ_LOCK(*p, (*irqflags));
126577 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126578 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126579 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126580 + if ((*p)->rcri_owned) {
126581 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
126582 + put_affine_portal();
126583 + return NULL;
126584 + }
126585 + (*p)->rcri_owned = pool;
126586 + }
126587 +#endif
126588 + avail = bm_rcr_get_avail(&(*p)->p);
126589 + if (avail < 2)
126590 + update_rcr_ci(*p, avail);
126591 + r = bm_rcr_start(&(*p)->p);
126592 + if (unlikely(!r)) {
126593 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126594 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126595 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC)))
126596 + (*p)->rcri_owned = NULL;
126597 +#endif
126598 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
126599 + put_affine_portal();
126600 + }
126601 + return r;
126602 +}
126603 +
126604 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126605 +static noinline struct bm_rcr_entry *__wait_rel_start(struct bman_portal **p,
126606 + struct bman_pool *pool,
126607 + __maybe_unused unsigned long *irqflags,
126608 + u32 flags)
126609 +{
126610 + struct bm_rcr_entry *rcr = try_rel_start(p, pool, irqflags, flags);
126611 + if (!rcr)
126612 + bm_rcr_set_ithresh(&(*p)->p, 1);
126613 + return rcr;
126614 +}
126615 +
126616 +static noinline struct bm_rcr_entry *wait_rel_start(struct bman_portal **p,
126617 + struct bman_pool *pool,
126618 + __maybe_unused unsigned long *irqflags,
126619 + u32 flags)
126620 +{
126621 + struct bm_rcr_entry *rcr;
126622 +#ifndef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126623 + pool = NULL;
126624 +#endif
126625 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
126626 + /* NB: return NULL if signal occurs before completion. Signal
126627 + * can occur during return. Caller must check for signal */
126628 + wait_event_interruptible(affine_queue,
126629 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
126630 + else
126631 + wait_event(affine_queue,
126632 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
126633 + return rcr;
126634 +}
126635 +#endif
126636 +
126637 +static inline int __bman_release(struct bman_pool *pool,
126638 + const struct bm_buffer *bufs, u8 num, u32 flags)
126639 +{
126640 + struct bman_portal *p;
126641 + struct bm_rcr_entry *r;
126642 + __maybe_unused unsigned long irqflags;
126643 + u32 i = num - 1;
126644 +
126645 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126646 + if (flags & BMAN_RELEASE_FLAG_WAIT)
126647 + r = wait_rel_start(&p, pool, &irqflags, flags);
126648 + else
126649 + r = try_rel_start(&p, pool, &irqflags, flags);
126650 +#else
126651 + r = try_rel_start(&p, &irqflags, flags);
126652 +#endif
126653 + if (!r)
126654 + return -EBUSY;
126655 + /* We can copy all but the first entry, as this can trigger badness
126656 + * with the valid-bit. Use the overlay to mask the verb byte. */
126657 + r->bufs[0].opaque =
126658 + ((cpu_to_be64((bufs[0].opaque |
126659 + ((u64)pool->params.bpid<<48))
126660 + & 0x00ffffffffffffff)));
126661 + if (i) {
126662 + for (i = 1; i < num; i++)
126663 + r->bufs[i].opaque =
126664 + cpu_to_be64(bufs[i].opaque);
126665 + }
126666 +
126667 + bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
126668 + (num & BM_RCR_VERB_BUFCOUNT_MASK));
126669 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126670 + /* if we wish to sync we need to set the threshold after h/w sees the
126671 + * new ring entry. As we're mixing cache-enabled and cache-inhibited
126672 + * accesses, this requires a heavy-weight sync. */
126673 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126674 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126675 + hwsync();
126676 + bm_rcr_set_ithresh(&p->p, 1);
126677 + }
126678 +#endif
126679 + PORTAL_IRQ_UNLOCK(p, irqflags);
126680 + put_affine_portal();
126681 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126682 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126683 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126684 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
126685 + /* NB: return success even if signal occurs before
126686 + * condition is true. pvb_commit guarantees success */
126687 + wait_event_interruptible(affine_queue,
126688 + (p->rcri_owned != pool));
126689 + else
126690 + wait_event(affine_queue, (p->rcri_owned != pool));
126691 + }
126692 +#endif
126693 + return 0;
126694 +}
126695 +
126696 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
126697 + u32 flags)
126698 +{
126699 + int ret;
126700 +#ifdef CONFIG_FSL_DPA_CHECKING
126701 + if (!num || (num > 8))
126702 + return -EINVAL;
126703 + if (pool->params.flags & BMAN_POOL_FLAG_NO_RELEASE)
126704 + return -EINVAL;
126705 +#endif
126706 + /* Without stockpile, this API is a pass-through to the h/w operation */
126707 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
126708 + return __bman_release(pool, bufs, num, flags);
126709 +#ifdef CONFIG_FSL_DPA_CHECKING
126710 + if (!atomic_dec_and_test(&pool->in_use)) {
126711 + pr_crit("Parallel attempts to enter bman_released() detected.");
126712 + panic("only one instance of bman_released/acquired allowed");
126713 + }
126714 +#endif
126715 + /* Two movements of buffers are possible, and can occur in either order.
126716 + * A: moving buffers from the caller to the stockpile.
126717 + * B: moving buffers from the stockpile to hardware.
126718 + * Order 1: if there is already enough space in the stockpile for A
126719 + * then we want to do A first, and only do B if we trigger the
126720 + * stockpile-high threshold.
126721 + * Order 2: if there is not enough space in the stockpile for A, then
126722 + * we want to do B first, then do A if B had succeeded. However in this
126723 + * case B is dependent on how many buffers the user needs to release,
126724 + * not the stockpile-high threshold.
126725 + * Due to the different handling of B between the two cases, putting A
126726 + * and B in a while() loop would require quite obscure logic, so handle
126727 + * the different sequences explicitly. */
126728 + if ((pool->sp_fill + num) <= BMAN_STOCKPILE_SZ) {
126729 + /* Order 1: do A */
126730 + copy_words(pool->sp + pool->sp_fill, bufs,
126731 + sizeof(struct bm_buffer) * num);
126732 + pool->sp_fill += num;
126733 + /* do B relative to STOCKPILE_HIGH */
126734 + while (pool->sp_fill >= BMAN_STOCKPILE_HIGH) {
126735 + ret = __bman_release(pool,
126736 + pool->sp + (pool->sp_fill - 8), 8,
126737 + flags);
126738 + if (ret >= 0)
126739 + pool->sp_fill -= 8;
126740 + }
126741 + } else {
126742 + /* Order 2: do B relative to 'num' */
126743 + do {
126744 + ret = __bman_release(pool,
126745 + pool->sp + (pool->sp_fill - 8), 8,
126746 + flags);
126747 + if (ret < 0)
126748 + /* failure */
126749 + goto release_done;
126750 + pool->sp_fill -= 8;
126751 + } while ((pool->sp_fill + num) > BMAN_STOCKPILE_SZ);
126752 + /* do A */
126753 + copy_words(pool->sp + pool->sp_fill, bufs,
126754 + sizeof(struct bm_buffer) * num);
126755 + pool->sp_fill += num;
126756 + }
126757 + /* success */
126758 + ret = 0;
126759 +release_done:
126760 +#ifdef CONFIG_FSL_DPA_CHECKING
126761 + atomic_inc(&pool->in_use);
126762 +#endif
126763 + return ret;
126764 +}
126765 +EXPORT_SYMBOL(bman_release);
126766 +
126767 +static inline int __bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs,
126768 + u8 num)
126769 +{
126770 + struct bman_portal *p = get_affine_portal();
126771 + struct bm_mc_command *mcc;
126772 + struct bm_mc_result *mcr;
126773 + __maybe_unused unsigned long irqflags;
126774 + int ret, i;
126775 +
126776 + PORTAL_IRQ_LOCK(p, irqflags);
126777 + mcc = bm_mc_start(&p->p);
126778 + mcc->acquire.bpid = pool->params.bpid;
126779 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE |
126780 + (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT));
126781 + while (!(mcr = bm_mc_result(&p->p)))
126782 + cpu_relax();
126783 + ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT;
126784 + if (bufs) {
126785 + for (i = 0; i < num; i++)
126786 + bufs[i].opaque =
126787 + be64_to_cpu(mcr->acquire.bufs[i].opaque);
126788 + }
126789 + PORTAL_IRQ_UNLOCK(p, irqflags);
126790 + put_affine_portal();
126791 + if (ret != num)
126792 + ret = -ENOMEM;
126793 + return ret;
126794 +}
126795 +
126796 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
126797 + u32 flags)
126798 +{
126799 + int ret;
126800 +#ifdef CONFIG_FSL_DPA_CHECKING
126801 + if (!num || (num > 8))
126802 + return -EINVAL;
126803 + if (pool->params.flags & BMAN_POOL_FLAG_ONLY_RELEASE)
126804 + return -EINVAL;
126805 +#endif
126806 + /* Without stockpile, this API is a pass-through to the h/w operation */
126807 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
126808 + return __bman_acquire(pool, bufs, num);
126809 +#ifdef CONFIG_FSL_DPA_CHECKING
126810 + if (!atomic_dec_and_test(&pool->in_use)) {
126811 + pr_crit("Parallel attempts to enter bman_acquire() detected.");
126812 + panic("only one instance of bman_released/acquired allowed");
126813 + }
126814 +#endif
126815 + /* Two movements of buffers are possible, and can occur in either order.
126816 + * A: moving buffers from stockpile to the caller.
126817 + * B: moving buffers from hardware to the stockpile.
126818 + * Order 1: if there are already enough buffers in the stockpile for A
126819 + * then we want to do A first, and only do B if we trigger the
126820 + * stockpile-low threshold.
126821 + * Order 2: if there are not enough buffers in the stockpile for A,
126822 + * then we want to do B first, then do A if B had succeeded. However in
126823 + * this case B is dependent on how many buffers the user needs, not the
126824 + * stockpile-low threshold.
126825 + * Due to the different handling of B between the two cases, putting A
126826 + * and B in a while() loop would require quite obscure logic, so handle
126827 + * the different sequences explicitly. */
126828 + if (num <= pool->sp_fill) {
126829 + /* Order 1: do A */
126830 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
126831 + sizeof(struct bm_buffer) * num);
126832 + pool->sp_fill -= num;
126833 + /* do B relative to STOCKPILE_LOW */
126834 + while (pool->sp_fill <= BMAN_STOCKPILE_LOW) {
126835 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
126836 + if (ret < 0)
126837 + ret = __bman_acquire(pool,
126838 + pool->sp + pool->sp_fill, 1);
126839 + if (ret < 0)
126840 + break;
126841 + pool->sp_fill += ret;
126842 + }
126843 + } else {
126844 + /* Order 2: do B relative to 'num' */
126845 + do {
126846 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
126847 + if (ret < 0)
126848 + ret = __bman_acquire(pool,
126849 + pool->sp + pool->sp_fill, 1);
126850 + if (ret < 0)
126851 + /* failure */
126852 + goto acquire_done;
126853 + pool->sp_fill += ret;
126854 + } while (pool->sp_fill < num);
126855 + /* do A */
126856 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
126857 + sizeof(struct bm_buffer) * num);
126858 + pool->sp_fill -= num;
126859 + }
126860 + /* success */
126861 + ret = num;
126862 +acquire_done:
126863 +#ifdef CONFIG_FSL_DPA_CHECKING
126864 + atomic_inc(&pool->in_use);
126865 +#endif
126866 + return ret;
126867 +}
126868 +EXPORT_SYMBOL(bman_acquire);
126869 +
126870 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags)
126871 +{
126872 + u8 num;
126873 + int ret;
126874 +
126875 + while (pool->sp_fill) {
126876 + num = ((pool->sp_fill > 8) ? 8 : pool->sp_fill);
126877 + ret = __bman_release(pool, pool->sp + (pool->sp_fill - num),
126878 + num, flags);
126879 + if (ret)
126880 + return ret;
126881 + pool->sp_fill -= num;
126882 + }
126883 + return 0;
126884 +}
126885 +EXPORT_SYMBOL(bman_flush_stockpile);
126886 +
126887 +int bman_query_pools(struct bm_pool_state *state)
126888 +{
126889 + struct bman_portal *p = get_affine_portal();
126890 + struct bm_mc_result *mcr;
126891 + __maybe_unused unsigned long irqflags;
126892 +
126893 + PORTAL_IRQ_LOCK(p, irqflags);
126894 + bm_mc_start(&p->p);
126895 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
126896 + while (!(mcr = bm_mc_result(&p->p)))
126897 + cpu_relax();
126898 + DPA_ASSERT((mcr->verb & BM_MCR_VERB_CMD_MASK) == BM_MCR_VERB_CMD_QUERY);
126899 + *state = mcr->query;
126900 + state->as.state.__state[0] = be32_to_cpu(state->as.state.__state[0]);
126901 + state->as.state.__state[1] = be32_to_cpu(state->as.state.__state[1]);
126902 + state->ds.state.__state[0] = be32_to_cpu(state->ds.state.__state[0]);
126903 + state->ds.state.__state[1] = be32_to_cpu(state->ds.state.__state[1]);
126904 + PORTAL_IRQ_UNLOCK(p, irqflags);
126905 + put_affine_portal();
126906 + return 0;
126907 +}
126908 +EXPORT_SYMBOL(bman_query_pools);
126909 +
126910 +#ifdef CONFIG_FSL_BMAN_CONFIG
126911 +u32 bman_query_free_buffers(struct bman_pool *pool)
126912 +{
126913 + return bm_pool_free_buffers(pool->params.bpid);
126914 +}
126915 +EXPORT_SYMBOL(bman_query_free_buffers);
126916 +
126917 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds)
126918 +{
126919 + u32 bpid;
126920 +
126921 + bpid = bman_get_params(pool)->bpid;
126922 +
126923 + return bm_pool_set(bpid, thresholds);
126924 +}
126925 +EXPORT_SYMBOL(bman_update_pool_thresholds);
126926 +#endif
126927 +
126928 +int bman_shutdown_pool(u32 bpid)
126929 +{
126930 + struct bman_portal *p = get_affine_portal();
126931 + __maybe_unused unsigned long irqflags;
126932 + int ret;
126933 +
126934 + PORTAL_IRQ_LOCK(p, irqflags);
126935 + ret = bm_shutdown_pool(&p->p, bpid);
126936 + PORTAL_IRQ_UNLOCK(p, irqflags);
126937 + put_affine_portal();
126938 + return ret;
126939 +}
126940 +EXPORT_SYMBOL(bman_shutdown_pool);
126941 +
126942 +const struct bm_portal_config *bman_get_bm_portal_config(
126943 + struct bman_portal *portal)
126944 +{
126945 + return portal->sharing_redirect ? NULL : portal->config;
126946 +}
126947 --- /dev/null
126948 +++ b/drivers/staging/fsl_qbman/bman_low.h
126949 @@ -0,0 +1,565 @@
126950 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
126951 + *
126952 + * Redistribution and use in source and binary forms, with or without
126953 + * modification, are permitted provided that the following conditions are met:
126954 + * * Redistributions of source code must retain the above copyright
126955 + * notice, this list of conditions and the following disclaimer.
126956 + * * Redistributions in binary form must reproduce the above copyright
126957 + * notice, this list of conditions and the following disclaimer in the
126958 + * documentation and/or other materials provided with the distribution.
126959 + * * Neither the name of Freescale Semiconductor nor the
126960 + * names of its contributors may be used to endorse or promote products
126961 + * derived from this software without specific prior written permission.
126962 + *
126963 + *
126964 + * ALTERNATIVELY, this software may be distributed under the terms of the
126965 + * GNU General Public License ("GPL") as published by the Free Software
126966 + * Foundation, either version 2 of that License or (at your option) any
126967 + * later version.
126968 + *
126969 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
126970 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
126971 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
126972 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
126973 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
126974 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
126975 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
126976 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
126977 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
126978 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
126979 + */
126980 +
126981 +#include "bman_private.h"
126982 +
126983 +/***************************/
126984 +/* Portal register assists */
126985 +/***************************/
126986 +
126987 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
126988 +
126989 +/* Cache-inhibited register offsets */
126990 +#define BM_REG_RCR_PI_CINH 0x0000
126991 +#define BM_REG_RCR_CI_CINH 0x0004
126992 +#define BM_REG_RCR_ITR 0x0008
126993 +#define BM_REG_CFG 0x0100
126994 +#define BM_REG_SCN(n) (0x0200 + ((n) << 2))
126995 +#define BM_REG_ISR 0x0e00
126996 +#define BM_REG_IIR 0x0e0c
126997 +
126998 +/* Cache-enabled register offsets */
126999 +#define BM_CL_CR 0x0000
127000 +#define BM_CL_RR0 0x0100
127001 +#define BM_CL_RR1 0x0140
127002 +#define BM_CL_RCR 0x1000
127003 +#define BM_CL_RCR_PI_CENA 0x3000
127004 +#define BM_CL_RCR_CI_CENA 0x3100
127005 +
127006 +#endif
127007 +
127008 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127009 +
127010 +/* Cache-inhibited register offsets */
127011 +#define BM_REG_RCR_PI_CINH 0x3000
127012 +#define BM_REG_RCR_CI_CINH 0x3100
127013 +#define BM_REG_RCR_ITR 0x3200
127014 +#define BM_REG_CFG 0x3300
127015 +#define BM_REG_SCN(n) (0x3400 + ((n) << 6))
127016 +#define BM_REG_ISR 0x3e00
127017 +#define BM_REG_IIR 0x3ec0
127018 +
127019 +/* Cache-enabled register offsets */
127020 +#define BM_CL_CR 0x0000
127021 +#define BM_CL_RR0 0x0100
127022 +#define BM_CL_RR1 0x0140
127023 +#define BM_CL_RCR 0x1000
127024 +#define BM_CL_RCR_PI_CENA 0x3000
127025 +#define BM_CL_RCR_CI_CENA 0x3100
127026 +
127027 +#endif
127028 +
127029 +/* BTW, the drivers (and h/w programming model) already obtain the required
127030 + * synchronisation for portal accesses via lwsync(), hwsync(), and
127031 + * data-dependencies. Use of barrier()s or other order-preserving primitives
127032 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
127033 + * simply ensure that the compiler treats the portal registers as volatile (ie.
127034 + * non-coherent). */
127035 +
127036 +/* Cache-inhibited register access. */
127037 +#define __bm_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ci + (o)))
127038 +#define __bm_out(bm, o, val) __raw_writel(cpu_to_be32(val), \
127039 + (bm)->addr_ci + (o));
127040 +#define bm_in(reg) __bm_in(&portal->addr, BM_REG_##reg)
127041 +#define bm_out(reg, val) __bm_out(&portal->addr, BM_REG_##reg, val)
127042 +
127043 +/* Cache-enabled (index) register access */
127044 +#define __bm_cl_touch_ro(bm, o) dcbt_ro((bm)->addr_ce + (o))
127045 +#define __bm_cl_touch_rw(bm, o) dcbt_rw((bm)->addr_ce + (o))
127046 +#define __bm_cl_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ce + (o)))
127047 +#define __bm_cl_out(bm, o, val) \
127048 + do { \
127049 + u32 *__tmpclout = (bm)->addr_ce + (o); \
127050 + __raw_writel(cpu_to_be32(val), __tmpclout); \
127051 + dcbf(__tmpclout); \
127052 + } while (0)
127053 +#define __bm_cl_invalidate(bm, o) dcbi((bm)->addr_ce + (o))
127054 +#define bm_cl_touch_ro(reg) __bm_cl_touch_ro(&portal->addr, BM_CL_##reg##_CENA)
127055 +#define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, BM_CL_##reg##_CENA)
127056 +#define bm_cl_in(reg) __bm_cl_in(&portal->addr, BM_CL_##reg##_CENA)
127057 +#define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, BM_CL_##reg##_CENA, val)
127058 +#define bm_cl_invalidate(reg)\
127059 + __bm_cl_invalidate(&portal->addr, BM_CL_##reg##_CENA)
127060 +
127061 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
127062 + * analysis, look at using the "extra" bit in the ring index registers to avoid
127063 + * cyclic issues. */
127064 +static inline u8 bm_cyc_diff(u8 ringsize, u8 first, u8 last)
127065 +{
127066 + /* 'first' is included, 'last' is excluded */
127067 + if (first <= last)
127068 + return last - first;
127069 + return ringsize + last - first;
127070 +}
127071 +
127072 +/* Portal modes.
127073 + * Enum types;
127074 + * pmode == production mode
127075 + * cmode == consumption mode,
127076 + * Enum values use 3 letter codes. First letter matches the portal mode,
127077 + * remaining two letters indicate;
127078 + * ci == cache-inhibited portal register
127079 + * ce == cache-enabled portal register
127080 + * vb == in-band valid-bit (cache-enabled)
127081 + */
127082 +enum bm_rcr_pmode { /* matches BCSP_CFG::RPM */
127083 + bm_rcr_pci = 0, /* PI index, cache-inhibited */
127084 + bm_rcr_pce = 1, /* PI index, cache-enabled */
127085 + bm_rcr_pvb = 2 /* valid-bit */
127086 +};
127087 +enum bm_rcr_cmode { /* s/w-only */
127088 + bm_rcr_cci, /* CI index, cache-inhibited */
127089 + bm_rcr_cce /* CI index, cache-enabled */
127090 +};
127091 +
127092 +
127093 +/* ------------------------- */
127094 +/* --- Portal structures --- */
127095 +
127096 +#define BM_RCR_SIZE 8
127097 +
127098 +struct bm_rcr {
127099 + struct bm_rcr_entry *ring, *cursor;
127100 + u8 ci, available, ithresh, vbit;
127101 +#ifdef CONFIG_FSL_DPA_CHECKING
127102 + u32 busy;
127103 + enum bm_rcr_pmode pmode;
127104 + enum bm_rcr_cmode cmode;
127105 +#endif
127106 +};
127107 +
127108 +struct bm_mc {
127109 + struct bm_mc_command *cr;
127110 + struct bm_mc_result *rr;
127111 + u8 rridx, vbit;
127112 +#ifdef CONFIG_FSL_DPA_CHECKING
127113 + enum {
127114 + /* Can only be _mc_start()ed */
127115 + mc_idle,
127116 + /* Can only be _mc_commit()ed or _mc_abort()ed */
127117 + mc_user,
127118 + /* Can only be _mc_retry()ed */
127119 + mc_hw
127120 + } state;
127121 +#endif
127122 +};
127123 +
127124 +struct bm_addr {
127125 + void __iomem *addr_ce; /* cache-enabled */
127126 + void __iomem *addr_ci; /* cache-inhibited */
127127 +};
127128 +
127129 +struct bm_portal {
127130 + struct bm_addr addr;
127131 + struct bm_rcr rcr;
127132 + struct bm_mc mc;
127133 + struct bm_portal_config config;
127134 +} ____cacheline_aligned;
127135 +
127136 +
127137 +/* --------------- */
127138 +/* --- RCR API --- */
127139 +
127140 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
127141 +#define RCR_CARRYCLEAR(p) \
127142 + (void *)((unsigned long)(p) & (~(unsigned long)(BM_RCR_SIZE << 6)))
127143 +
127144 +/* Bit-wise logic to convert a ring pointer to a ring index */
127145 +static inline u8 RCR_PTR2IDX(struct bm_rcr_entry *e)
127146 +{
127147 + return ((uintptr_t)e >> 6) & (BM_RCR_SIZE - 1);
127148 +}
127149 +
127150 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
127151 +static inline void RCR_INC(struct bm_rcr *rcr)
127152 +{
127153 + /* NB: this is odd-looking, but experiments show that it generates
127154 + * fast code with essentially no branching overheads. We increment to
127155 + * the next RCR pointer and handle overflow and 'vbit'. */
127156 + struct bm_rcr_entry *partial = rcr->cursor + 1;
127157 + rcr->cursor = RCR_CARRYCLEAR(partial);
127158 + if (partial != rcr->cursor)
127159 + rcr->vbit ^= BM_RCR_VERB_VBIT;
127160 +}
127161 +
127162 +static inline int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode,
127163 + __maybe_unused enum bm_rcr_cmode cmode)
127164 +{
127165 + /* This use of 'register', as well as all other occurrences, is because
127166 + * it has been observed to generate much faster code with gcc than is
127167 + * otherwise the case. */
127168 + register struct bm_rcr *rcr = &portal->rcr;
127169 + u32 cfg;
127170 + u8 pi;
127171 +
127172 + rcr->ring = portal->addr.addr_ce + BM_CL_RCR;
127173 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127174 +
127175 + pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
127176 + rcr->cursor = rcr->ring + pi;
127177 + rcr->vbit = (bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0;
127178 + rcr->available = BM_RCR_SIZE - 1
127179 + - bm_cyc_diff(BM_RCR_SIZE, rcr->ci, pi);
127180 + rcr->ithresh = bm_in(RCR_ITR);
127181 +#ifdef CONFIG_FSL_DPA_CHECKING
127182 + rcr->busy = 0;
127183 + rcr->pmode = pmode;
127184 + rcr->cmode = cmode;
127185 +#endif
127186 + cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */
127187 + bm_out(CFG, cfg);
127188 + return 0;
127189 +}
127190 +
127191 +static inline void bm_rcr_finish(struct bm_portal *portal)
127192 +{
127193 + register struct bm_rcr *rcr = &portal->rcr;
127194 + u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
127195 + u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127196 + DPA_ASSERT(!rcr->busy);
127197 + if (pi != RCR_PTR2IDX(rcr->cursor))
127198 + pr_crit("losing uncommited RCR entries\n");
127199 + if (ci != rcr->ci)
127200 + pr_crit("missing existing RCR completions\n");
127201 + if (rcr->ci != RCR_PTR2IDX(rcr->cursor))
127202 + pr_crit("RCR destroyed unquiesced\n");
127203 +}
127204 +
127205 +static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
127206 +{
127207 + register struct bm_rcr *rcr = &portal->rcr;
127208 + DPA_ASSERT(!rcr->busy);
127209 + if (!rcr->available)
127210 + return NULL;
127211 +#ifdef CONFIG_FSL_DPA_CHECKING
127212 + rcr->busy = 1;
127213 +#endif
127214 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127215 + dcbz_64(rcr->cursor);
127216 +#endif
127217 + return rcr->cursor;
127218 +}
127219 +
127220 +static inline void bm_rcr_abort(struct bm_portal *portal)
127221 +{
127222 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127223 + DPA_ASSERT(rcr->busy);
127224 +#ifdef CONFIG_FSL_DPA_CHECKING
127225 + rcr->busy = 0;
127226 +#endif
127227 +}
127228 +
127229 +static inline struct bm_rcr_entry *bm_rcr_pend_and_next(
127230 + struct bm_portal *portal, u8 myverb)
127231 +{
127232 + register struct bm_rcr *rcr = &portal->rcr;
127233 + DPA_ASSERT(rcr->busy);
127234 + DPA_ASSERT(rcr->pmode != bm_rcr_pvb);
127235 + if (rcr->available == 1)
127236 + return NULL;
127237 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127238 + dcbf_64(rcr->cursor);
127239 + RCR_INC(rcr);
127240 + rcr->available--;
127241 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127242 + dcbz_64(rcr->cursor);
127243 +#endif
127244 + return rcr->cursor;
127245 +}
127246 +
127247 +static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb)
127248 +{
127249 + register struct bm_rcr *rcr = &portal->rcr;
127250 + DPA_ASSERT(rcr->busy);
127251 + DPA_ASSERT(rcr->pmode == bm_rcr_pci);
127252 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127253 + RCR_INC(rcr);
127254 + rcr->available--;
127255 + hwsync();
127256 + bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor));
127257 +#ifdef CONFIG_FSL_DPA_CHECKING
127258 + rcr->busy = 0;
127259 +#endif
127260 +}
127261 +
127262 +static inline void bm_rcr_pce_prefetch(struct bm_portal *portal)
127263 +{
127264 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127265 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127266 + bm_cl_invalidate(RCR_PI);
127267 + bm_cl_touch_rw(RCR_PI);
127268 +}
127269 +
127270 +static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb)
127271 +{
127272 + register struct bm_rcr *rcr = &portal->rcr;
127273 + DPA_ASSERT(rcr->busy);
127274 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127275 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127276 + RCR_INC(rcr);
127277 + rcr->available--;
127278 + lwsync();
127279 + bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor));
127280 +#ifdef CONFIG_FSL_DPA_CHECKING
127281 + rcr->busy = 0;
127282 +#endif
127283 +}
127284 +
127285 +static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
127286 +{
127287 + register struct bm_rcr *rcr = &portal->rcr;
127288 + struct bm_rcr_entry *rcursor;
127289 + DPA_ASSERT(rcr->busy);
127290 + DPA_ASSERT(rcr->pmode == bm_rcr_pvb);
127291 + lwsync();
127292 + rcursor = rcr->cursor;
127293 + rcursor->__dont_write_directly__verb = myverb | rcr->vbit;
127294 + dcbf_64(rcursor);
127295 + RCR_INC(rcr);
127296 + rcr->available--;
127297 +#ifdef CONFIG_FSL_DPA_CHECKING
127298 + rcr->busy = 0;
127299 +#endif
127300 +}
127301 +
127302 +static inline u8 bm_rcr_cci_update(struct bm_portal *portal)
127303 +{
127304 + register struct bm_rcr *rcr = &portal->rcr;
127305 + u8 diff, old_ci = rcr->ci;
127306 + DPA_ASSERT(rcr->cmode == bm_rcr_cci);
127307 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127308 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127309 + rcr->available += diff;
127310 + return diff;
127311 +}
127312 +
127313 +static inline void bm_rcr_cce_prefetch(struct bm_portal *portal)
127314 +{
127315 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127316 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127317 + bm_cl_touch_ro(RCR_CI);
127318 +}
127319 +
127320 +static inline u8 bm_rcr_cce_update(struct bm_portal *portal)
127321 +{
127322 + register struct bm_rcr *rcr = &portal->rcr;
127323 + u8 diff, old_ci = rcr->ci;
127324 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127325 + rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1);
127326 + bm_cl_invalidate(RCR_CI);
127327 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127328 + rcr->available += diff;
127329 + return diff;
127330 +}
127331 +
127332 +static inline u8 bm_rcr_get_ithresh(struct bm_portal *portal)
127333 +{
127334 + register struct bm_rcr *rcr = &portal->rcr;
127335 + return rcr->ithresh;
127336 +}
127337 +
127338 +static inline void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh)
127339 +{
127340 + register struct bm_rcr *rcr = &portal->rcr;
127341 + rcr->ithresh = ithresh;
127342 + bm_out(RCR_ITR, ithresh);
127343 +}
127344 +
127345 +static inline u8 bm_rcr_get_avail(struct bm_portal *portal)
127346 +{
127347 + register struct bm_rcr *rcr = &portal->rcr;
127348 + return rcr->available;
127349 +}
127350 +
127351 +static inline u8 bm_rcr_get_fill(struct bm_portal *portal)
127352 +{
127353 + register struct bm_rcr *rcr = &portal->rcr;
127354 + return BM_RCR_SIZE - 1 - rcr->available;
127355 +}
127356 +
127357 +
127358 +/* ------------------------------ */
127359 +/* --- Management command API --- */
127360 +
127361 +static inline int bm_mc_init(struct bm_portal *portal)
127362 +{
127363 + register struct bm_mc *mc = &portal->mc;
127364 + mc->cr = portal->addr.addr_ce + BM_CL_CR;
127365 + mc->rr = portal->addr.addr_ce + BM_CL_RR0;
127366 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
127367 + BM_MCC_VERB_VBIT) ? 0 : 1;
127368 + mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0;
127369 +#ifdef CONFIG_FSL_DPA_CHECKING
127370 + mc->state = mc_idle;
127371 +#endif
127372 + return 0;
127373 +}
127374 +
127375 +static inline void bm_mc_finish(struct bm_portal *portal)
127376 +{
127377 + __maybe_unused register struct bm_mc *mc = &portal->mc;
127378 + DPA_ASSERT(mc->state == mc_idle);
127379 +#ifdef CONFIG_FSL_DPA_CHECKING
127380 + if (mc->state != mc_idle)
127381 + pr_crit("Losing incomplete MC command\n");
127382 +#endif
127383 +}
127384 +
127385 +static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
127386 +{
127387 + register struct bm_mc *mc = &portal->mc;
127388 + DPA_ASSERT(mc->state == mc_idle);
127389 +#ifdef CONFIG_FSL_DPA_CHECKING
127390 + mc->state = mc_user;
127391 +#endif
127392 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127393 + dcbz_64(mc->cr);
127394 +#endif
127395 + return mc->cr;
127396 +}
127397 +
127398 +static inline void bm_mc_abort(struct bm_portal *portal)
127399 +{
127400 + __maybe_unused register struct bm_mc *mc = &portal->mc;
127401 + DPA_ASSERT(mc->state == mc_user);
127402 +#ifdef CONFIG_FSL_DPA_CHECKING
127403 + mc->state = mc_idle;
127404 +#endif
127405 +}
127406 +
127407 +static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
127408 +{
127409 + register struct bm_mc *mc = &portal->mc;
127410 + struct bm_mc_result *rr = mc->rr + mc->rridx;
127411 + DPA_ASSERT(mc->state == mc_user);
127412 + lwsync();
127413 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
127414 + dcbf(mc->cr);
127415 + dcbit_ro(rr);
127416 +#ifdef CONFIG_FSL_DPA_CHECKING
127417 + mc->state = mc_hw;
127418 +#endif
127419 +}
127420 +
127421 +static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal)
127422 +{
127423 + register struct bm_mc *mc = &portal->mc;
127424 + struct bm_mc_result *rr = mc->rr + mc->rridx;
127425 + DPA_ASSERT(mc->state == mc_hw);
127426 + /* The inactive response register's verb byte always returns zero until
127427 + * its command is submitted and completed. This includes the valid-bit,
127428 + * in case you were wondering... */
127429 + if (!__raw_readb(&rr->verb)) {
127430 + dcbit_ro(rr);
127431 + return NULL;
127432 + }
127433 + mc->rridx ^= 1;
127434 + mc->vbit ^= BM_MCC_VERB_VBIT;
127435 +#ifdef CONFIG_FSL_DPA_CHECKING
127436 + mc->state = mc_idle;
127437 +#endif
127438 + return rr;
127439 +}
127440 +
127441 +
127442 +/* ------------------------------------- */
127443 +/* --- Portal interrupt register API --- */
127444 +
127445 +static inline int bm_isr_init(__always_unused struct bm_portal *portal)
127446 +{
127447 + return 0;
127448 +}
127449 +
127450 +static inline void bm_isr_finish(__always_unused struct bm_portal *portal)
127451 +{
127452 +}
127453 +
127454 +#define SCN_REG(bpid) BM_REG_SCN((bpid) / 32)
127455 +#define SCN_BIT(bpid) (0x80000000 >> (bpid & 31))
127456 +static inline void bm_isr_bscn_mask(struct bm_portal *portal, u8 bpid,
127457 + int enable)
127458 +{
127459 + u32 val;
127460 + DPA_ASSERT(bpid < bman_pool_max);
127461 + /* REG_SCN for bpid=0..31, REG_SCN+4 for bpid=32..63 */
127462 + val = __bm_in(&portal->addr, SCN_REG(bpid));
127463 + if (enable)
127464 + val |= SCN_BIT(bpid);
127465 + else
127466 + val &= ~SCN_BIT(bpid);
127467 + __bm_out(&portal->addr, SCN_REG(bpid), val);
127468 +}
127469 +
127470 +static inline u32 __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n)
127471 +{
127472 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127473 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 6));
127474 +#else
127475 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 2));
127476 +#endif
127477 +}
127478 +
127479 +static inline void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n,
127480 + u32 val)
127481 +{
127482 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127483 + __bm_out(&portal->addr, BM_REG_ISR + (n << 6), val);
127484 +#else
127485 + __bm_out(&portal->addr, BM_REG_ISR + (n << 2), val);
127486 +#endif
127487 +}
127488 +
127489 +/* Buffer Pool Cleanup */
127490 +static inline int bm_shutdown_pool(struct bm_portal *p, u32 bpid)
127491 +{
127492 + struct bm_mc_command *bm_cmd;
127493 + struct bm_mc_result *bm_res;
127494 +
127495 + int aq_count = 0;
127496 + bool stop = false;
127497 + while (!stop) {
127498 + /* Acquire buffers until empty */
127499 + bm_cmd = bm_mc_start(p);
127500 + bm_cmd->acquire.bpid = bpid;
127501 + bm_mc_commit(p, BM_MCC_VERB_CMD_ACQUIRE | 1);
127502 + while (!(bm_res = bm_mc_result(p)))
127503 + cpu_relax();
127504 + if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
127505 + /* Pool is empty */
127506 + /* TBD : Should we do a few extra iterations in
127507 + case some other some blocks keep buffers 'on deck',
127508 + which may also be problematic */
127509 + stop = true;
127510 + } else
127511 + ++aq_count;
127512 + }
127513 + return 0;
127514 +}
127515 --- /dev/null
127516 +++ b/drivers/staging/fsl_qbman/bman_private.h
127517 @@ -0,0 +1,166 @@
127518 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
127519 + *
127520 + * Redistribution and use in source and binary forms, with or without
127521 + * modification, are permitted provided that the following conditions are met:
127522 + * * Redistributions of source code must retain the above copyright
127523 + * notice, this list of conditions and the following disclaimer.
127524 + * * Redistributions in binary form must reproduce the above copyright
127525 + * notice, this list of conditions and the following disclaimer in the
127526 + * documentation and/or other materials provided with the distribution.
127527 + * * Neither the name of Freescale Semiconductor nor the
127528 + * names of its contributors may be used to endorse or promote products
127529 + * derived from this software without specific prior written permission.
127530 + *
127531 + *
127532 + * ALTERNATIVELY, this software may be distributed under the terms of the
127533 + * GNU General Public License ("GPL") as published by the Free Software
127534 + * Foundation, either version 2 of that License or (at your option) any
127535 + * later version.
127536 + *
127537 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127538 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127539 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127540 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127541 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127542 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127543 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127544 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127545 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127546 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127547 + */
127548 +
127549 +#include "dpa_sys.h"
127550 +#include <linux/fsl_bman.h>
127551 +
127552 +/* Revision info (for errata and feature handling) */
127553 +#define BMAN_REV10 0x0100
127554 +#define BMAN_REV20 0x0200
127555 +#define BMAN_REV21 0x0201
127556 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
127557 +extern u16 bman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
127558 +
127559 +/*
127560 + * Global variables of the max portal/pool number this bman version supported
127561 + */
127562 +extern u16 bman_pool_max;
127563 +
127564 +/* used by CCSR and portal interrupt code */
127565 +enum bm_isr_reg {
127566 + bm_isr_status = 0,
127567 + bm_isr_enable = 1,
127568 + bm_isr_disable = 2,
127569 + bm_isr_inhibit = 3
127570 +};
127571 +
127572 +struct bm_portal_config {
127573 + /* Corenet portal addresses;
127574 + * [0]==cache-enabled, [1]==cache-inhibited. */
127575 + __iomem void *addr_virt[2];
127576 + struct resource addr_phys[2];
127577 + /* Allow these to be joined in lists */
127578 + struct list_head list;
127579 + /* User-visible portal configuration settings */
127580 + struct bman_portal_config public_cfg;
127581 + /* power management saved data */
127582 + u32 saved_isdr;
127583 +};
127584 +
127585 +#ifdef CONFIG_FSL_BMAN_CONFIG
127586 +/* Hooks from bman_driver.c to bman_config.c */
127587 +int bman_init_ccsr(struct device_node *node);
127588 +#endif
127589 +
127590 +/* Hooks from bman_driver.c in to bman_high.c */
127591 +struct bman_portal *bman_create_portal(
127592 + struct bman_portal *portal,
127593 + const struct bm_portal_config *config);
127594 +struct bman_portal *bman_create_affine_portal(
127595 + const struct bm_portal_config *config);
127596 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
127597 + int cpu);
127598 +void bman_destroy_portal(struct bman_portal *bm);
127599 +
127600 +const struct bm_portal_config *bman_destroy_affine_portal(void);
127601 +
127602 +/* Hooks from fsl_usdpaa.c to bman_driver.c */
127603 +struct bm_portal_config *bm_get_unused_portal(void);
127604 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx);
127605 +void bm_put_unused_portal(struct bm_portal_config *pcfg);
127606 +void bm_set_liodns(struct bm_portal_config *pcfg);
127607 +
127608 +/* Pool logic in the portal driver, during initialisation, needs to know if
127609 + * there's access to CCSR or not (if not, it'll cripple the pool allocator). */
127610 +#ifdef CONFIG_FSL_BMAN_CONFIG
127611 +int bman_have_ccsr(void);
127612 +#else
127613 +#define bman_have_ccsr() 0
127614 +#endif
127615 +
127616 +/* Stockpile build constants. The _LOW value: when bman_acquire() is called and
127617 + * the stockpile fill-level is <= _LOW, an acquire is attempted from h/w but it
127618 + * might fail (if the buffer pool is depleted). So this value provides some
127619 + * "stagger" in that the bman_acquire() function will only fail if lots of bufs
127620 + * are requested at once or if h/w has been tested a couple of times without
127621 + * luck. The _HIGH value: when bman_release() is called and the stockpile
127622 + * fill-level is >= _HIGH, a release is attempted to h/w but it might fail (if
127623 + * the release ring is full). So this value provides some "stagger" so that
127624 + * ring-access is retried a couple of times prior to the API returning a
127625 + * failure. The following *must* be true;
127626 + * BMAN_STOCKPILE_HIGH-BMAN_STOCKPILE_LOW > 8
127627 + * (to avoid thrashing)
127628 + * BMAN_STOCKPILE_SZ >= 16
127629 + * (as the release logic expects to either send 8 buffers to hw prior to
127630 + * adding the given buffers to the stockpile or add the buffers to the
127631 + * stockpile before sending 8 to hw, as the API must be an all-or-nothing
127632 + * success/fail.)
127633 + */
127634 +#define BMAN_STOCKPILE_SZ 16u /* number of bufs in per-pool cache */
127635 +#define BMAN_STOCKPILE_LOW 2u /* when fill is <= this, acquire from hw */
127636 +#define BMAN_STOCKPILE_HIGH 14u /* when fill is >= this, release to hw */
127637 +
127638 +/*************************************************/
127639 +/* BMan s/w corenet portal, low-level i/face */
127640 +/*************************************************/
127641 +
127642 +/* Used by all portal interrupt registers except 'inhibit'
127643 + * This mask contains all the "irqsource" bits visible to API users
127644 + */
127645 +#define BM_PIRQ_VISIBLE (BM_PIRQ_RCRI | BM_PIRQ_BSCN)
127646 +
127647 +/* These are bm_<reg>_<verb>(). So for example, bm_disable_write() means "write
127648 + * the disable register" rather than "disable the ability to write". */
127649 +#define bm_isr_status_read(bm) __bm_isr_read(bm, bm_isr_status)
127650 +#define bm_isr_status_clear(bm, m) __bm_isr_write(bm, bm_isr_status, m)
127651 +#define bm_isr_enable_read(bm) __bm_isr_read(bm, bm_isr_enable)
127652 +#define bm_isr_enable_write(bm, v) __bm_isr_write(bm, bm_isr_enable, v)
127653 +#define bm_isr_disable_read(bm) __bm_isr_read(bm, bm_isr_disable)
127654 +#define bm_isr_disable_write(bm, v) __bm_isr_write(bm, bm_isr_disable, v)
127655 +#define bm_isr_inhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 1)
127656 +#define bm_isr_uninhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 0)
127657 +
127658 +#ifdef CONFIG_FSL_BMAN_CONFIG
127659 +/* Set depletion thresholds associated with a buffer pool. Requires that the
127660 + * operating system have access to Bman CCSR (ie. compiled in support and
127661 + * run-time access courtesy of the device-tree). */
127662 +int bm_pool_set(u32 bpid, const u32 *thresholds);
127663 +#define BM_POOL_THRESH_SW_ENTER 0
127664 +#define BM_POOL_THRESH_SW_EXIT 1
127665 +#define BM_POOL_THRESH_HW_ENTER 2
127666 +#define BM_POOL_THRESH_HW_EXIT 3
127667 +
127668 +/* Read the free buffer count for a given buffer */
127669 +u32 bm_pool_free_buffers(u32 bpid);
127670 +
127671 +__init int bman_init(void);
127672 +__init int bman_resource_init(void);
127673 +
127674 +const struct bm_portal_config *bman_get_bm_portal_config(
127675 + struct bman_portal *portal);
127676 +
127677 +/* power management */
127678 +#ifdef CONFIG_SUSPEND
127679 +void suspend_unused_bportal(void);
127680 +void resume_unused_bportal(void);
127681 +#endif
127682 +
127683 +#endif /* CONFIG_FSL_BMAN_CONFIG */
127684 --- /dev/null
127685 +++ b/drivers/staging/fsl_qbman/bman_test.c
127686 @@ -0,0 +1,56 @@
127687 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127688 + *
127689 + * Redistribution and use in source and binary forms, with or without
127690 + * modification, are permitted provided that the following conditions are met:
127691 + * * Redistributions of source code must retain the above copyright
127692 + * notice, this list of conditions and the following disclaimer.
127693 + * * Redistributions in binary form must reproduce the above copyright
127694 + * notice, this list of conditions and the following disclaimer in the
127695 + * documentation and/or other materials provided with the distribution.
127696 + * * Neither the name of Freescale Semiconductor nor the
127697 + * names of its contributors may be used to endorse or promote products
127698 + * derived from this software without specific prior written permission.
127699 + *
127700 + *
127701 + * ALTERNATIVELY, this software may be distributed under the terms of the
127702 + * GNU General Public License ("GPL") as published by the Free Software
127703 + * Foundation, either version 2 of that License or (at your option) any
127704 + * later version.
127705 + *
127706 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127707 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127708 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127709 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127710 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127711 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127712 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127713 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127714 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127715 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127716 + */
127717 +
127718 +#include "bman_test.h"
127719 +
127720 +MODULE_AUTHOR("Geoff Thorpe");
127721 +MODULE_LICENSE("Dual BSD/GPL");
127722 +MODULE_DESCRIPTION("Bman testing");
127723 +
127724 +static int test_init(void)
127725 +{
127726 +#ifdef CONFIG_FSL_BMAN_TEST_HIGH
127727 + int loop = 1;
127728 + while (loop--)
127729 + bman_test_high();
127730 +#endif
127731 +#ifdef CONFIG_FSL_BMAN_TEST_THRESH
127732 + bman_test_thresh();
127733 +#endif
127734 + return 0;
127735 +}
127736 +
127737 +static void test_exit(void)
127738 +{
127739 +}
127740 +
127741 +module_init(test_init);
127742 +module_exit(test_exit);
127743 --- /dev/null
127744 +++ b/drivers/staging/fsl_qbman/bman_test.h
127745 @@ -0,0 +1,44 @@
127746 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127747 + *
127748 + * Redistribution and use in source and binary forms, with or without
127749 + * modification, are permitted provided that the following conditions are met:
127750 + * * Redistributions of source code must retain the above copyright
127751 + * notice, this list of conditions and the following disclaimer.
127752 + * * Redistributions in binary form must reproduce the above copyright
127753 + * notice, this list of conditions and the following disclaimer in the
127754 + * documentation and/or other materials provided with the distribution.
127755 + * * Neither the name of Freescale Semiconductor nor the
127756 + * names of its contributors may be used to endorse or promote products
127757 + * derived from this software without specific prior written permission.
127758 + *
127759 + *
127760 + * ALTERNATIVELY, this software may be distributed under the terms of the
127761 + * GNU General Public License ("GPL") as published by the Free Software
127762 + * Foundation, either version 2 of that License or (at your option) any
127763 + * later version.
127764 + *
127765 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127766 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127767 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127768 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127769 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127770 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127771 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127772 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127773 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127774 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127775 + */
127776 +
127777 +#include <linux/kernel.h>
127778 +#include <linux/errno.h>
127779 +#include <linux/io.h>
127780 +#include <linux/slab.h>
127781 +#include <linux/module.h>
127782 +#include <linux/interrupt.h>
127783 +#include <linux/delay.h>
127784 +#include <linux/kthread.h>
127785 +
127786 +#include <linux/fsl_bman.h>
127787 +
127788 +void bman_test_high(void);
127789 +void bman_test_thresh(void);
127790 --- /dev/null
127791 +++ b/drivers/staging/fsl_qbman/bman_test_high.c
127792 @@ -0,0 +1,183 @@
127793 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127794 + *
127795 + * Redistribution and use in source and binary forms, with or without
127796 + * modification, are permitted provided that the following conditions are met:
127797 + * * Redistributions of source code must retain the above copyright
127798 + * notice, this list of conditions and the following disclaimer.
127799 + * * Redistributions in binary form must reproduce the above copyright
127800 + * notice, this list of conditions and the following disclaimer in the
127801 + * documentation and/or other materials provided with the distribution.
127802 + * * Neither the name of Freescale Semiconductor nor the
127803 + * names of its contributors may be used to endorse or promote products
127804 + * derived from this software without specific prior written permission.
127805 + *
127806 + *
127807 + * ALTERNATIVELY, this software may be distributed under the terms of the
127808 + * GNU General Public License ("GPL") as published by the Free Software
127809 + * Foundation, either version 2 of that License or (at your option) any
127810 + * later version.
127811 + *
127812 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127813 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127814 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127815 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127816 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127817 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127818 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127819 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127820 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127821 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127822 + */
127823 +
127824 +#include "bman_test.h"
127825 +#include "bman_private.h"
127826 +
127827 +/*************/
127828 +/* constants */
127829 +/*************/
127830 +
127831 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
127832 +#define POOL_OPAQUE ((void *)0xdeadabba)
127833 +#define NUM_BUFS 93
127834 +#define LOOPS 3
127835 +#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU
127836 +
127837 +/***************/
127838 +/* global vars */
127839 +/***************/
127840 +
127841 +static struct bman_pool *pool;
127842 +static int depleted;
127843 +static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned;
127844 +static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned;
127845 +static int bufs_received;
127846 +
127847 +/* Predeclare the callback so we can instantiate pool parameters */
127848 +static void depletion_cb(struct bman_portal *, struct bman_pool *, void *, int);
127849 +
127850 +/**********************/
127851 +/* internal functions */
127852 +/**********************/
127853 +
127854 +static void bufs_init(void)
127855 +{
127856 + int i;
127857 + for (i = 0; i < NUM_BUFS; i++)
127858 + bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i);
127859 + bufs_received = 0;
127860 +}
127861 +
127862 +static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b)
127863 +{
127864 + if ((bman_ip_rev == BMAN_REV20) || (bman_ip_rev == BMAN_REV21)) {
127865 +
127866 + /* On SoCs with Bman revison 2.0, Bman only respects the 40
127867 + * LS-bits of buffer addresses, masking off the upper 8-bits on
127868 + * release commands. The API provides for 48-bit addresses
127869 + * because some SoCs support all 48-bits. When generating
127870 + * garbage addresses for testing, we either need to zero the
127871 + * upper 8-bits when releasing to Bman (otherwise we'll be
127872 + * disappointed when the buffers we acquire back from Bman
127873 + * don't match), or we need to mask the upper 8-bits off when
127874 + * comparing. We do the latter.
127875 + */
127876 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
127877 + < (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
127878 + return -1;
127879 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
127880 + > (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
127881 + return 1;
127882 + } else {
127883 + if (bm_buffer_get64(a) < bm_buffer_get64(b))
127884 + return -1;
127885 + if (bm_buffer_get64(a) > bm_buffer_get64(b))
127886 + return 1;
127887 + }
127888 +
127889 + return 0;
127890 +}
127891 +
127892 +static void bufs_confirm(void)
127893 +{
127894 + int i, j;
127895 + for (i = 0; i < NUM_BUFS; i++) {
127896 + int matches = 0;
127897 + for (j = 0; j < NUM_BUFS; j++)
127898 + if (!bufs_cmp(&bufs_in[i], &bufs_out[j]))
127899 + matches++;
127900 + BUG_ON(matches != 1);
127901 + }
127902 +}
127903 +
127904 +/********/
127905 +/* test */
127906 +/********/
127907 +
127908 +static void depletion_cb(struct bman_portal *__portal, struct bman_pool *__pool,
127909 + void *pool_ctx, int __depleted)
127910 +{
127911 + BUG_ON(__pool != pool);
127912 + BUG_ON(pool_ctx != POOL_OPAQUE);
127913 + depleted = __depleted;
127914 +}
127915 +
127916 +void bman_test_high(void)
127917 +{
127918 + struct bman_pool_params pparams = {
127919 + .flags = BMAN_POOL_FLAG_DEPLETION | BMAN_POOL_FLAG_DYNAMIC_BPID,
127920 + .cb = depletion_cb,
127921 + .cb_ctx = POOL_OPAQUE,
127922 + };
127923 + int i, loops = LOOPS;
127924 + struct bm_buffer tmp_buf;
127925 +
127926 + bufs_init();
127927 +
127928 + pr_info("BMAN: --- starting high-level test ---\n");
127929 +
127930 + pool = bman_new_pool(&pparams);
127931 + BUG_ON(!pool);
127932 +
127933 + /*******************/
127934 + /* Release buffers */
127935 + /*******************/
127936 +do_loop:
127937 + i = 0;
127938 + while (i < NUM_BUFS) {
127939 + u32 flags = BMAN_RELEASE_FLAG_WAIT;
127940 + int num = 8;
127941 + if ((i + num) > NUM_BUFS)
127942 + num = NUM_BUFS - i;
127943 + if ((i + num) == NUM_BUFS)
127944 + flags |= BMAN_RELEASE_FLAG_WAIT_SYNC;
127945 + if (bman_release(pool, bufs_in + i, num, flags))
127946 + panic("bman_release() failed\n");
127947 + i += num;
127948 + }
127949 +
127950 + /*******************/
127951 + /* Acquire buffers */
127952 + /*******************/
127953 + while (i > 0) {
127954 + int tmp, num = 8;
127955 + if (num > i)
127956 + num = i;
127957 + tmp = bman_acquire(pool, bufs_out + i - num, num, 0);
127958 + BUG_ON(tmp != num);
127959 + i -= num;
127960 + }
127961 +
127962 + i = bman_acquire(pool, &tmp_buf, 1, 0);
127963 + BUG_ON(i > 0);
127964 +
127965 + bufs_confirm();
127966 +
127967 + if (--loops)
127968 + goto do_loop;
127969 +
127970 + /************/
127971 + /* Clean up */
127972 + /************/
127973 + bman_free_pool(pool);
127974 + pr_info("BMAN: --- finished high-level test ---\n");
127975 +}
127976 --- /dev/null
127977 +++ b/drivers/staging/fsl_qbman/bman_test_thresh.c
127978 @@ -0,0 +1,196 @@
127979 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
127980 + *
127981 + * Redistribution and use in source and binary forms, with or without
127982 + * modification, are permitted provided that the following conditions are met:
127983 + * * Redistributions of source code must retain the above copyright
127984 + * notice, this list of conditions and the following disclaimer.
127985 + * * Redistributions in binary form must reproduce the above copyright
127986 + * notice, this list of conditions and the following disclaimer in the
127987 + * documentation and/or other materials provided with the distribution.
127988 + * * Neither the name of Freescale Semiconductor nor the
127989 + * names of its contributors may be used to endorse or promote products
127990 + * derived from this software without specific prior written permission.
127991 + *
127992 + *
127993 + * ALTERNATIVELY, this software may be distributed under the terms of the
127994 + * GNU General Public License ("GPL") as published by the Free Software
127995 + * Foundation, either version 2 of that License or (at your option) any
127996 + * later version.
127997 + *
127998 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127999 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128000 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128001 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128002 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128003 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128004 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128005 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128006 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128007 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128008 + */
128009 +
128010 +#include "bman_test.h"
128011 +
128012 +/* Test constants */
128013 +#define TEST_NUMBUFS 129728
128014 +#define TEST_EXIT 129536
128015 +#define TEST_ENTRY 129024
128016 +
128017 +struct affine_test_data {
128018 + struct task_struct *t;
128019 + int cpu;
128020 + int expect_affinity;
128021 + int drain;
128022 + int num_enter;
128023 + int num_exit;
128024 + struct list_head node;
128025 + struct completion wakethread;
128026 + struct completion wakeparent;
128027 +};
128028 +
128029 +static void cb_depletion(struct bman_portal *portal,
128030 + struct bman_pool *pool,
128031 + void *opaque,
128032 + int depleted)
128033 +{
128034 + struct affine_test_data *data = opaque;
128035 + int c = smp_processor_id();
128036 + pr_info("cb_depletion: bpid=%d, depleted=%d, cpu=%d, original=%d\n",
128037 + bman_get_params(pool)->bpid, !!depleted, c, data->cpu);
128038 + /* We should be executing on the CPU of the thread that owns the pool if
128039 + * and that CPU has an affine portal (ie. it isn't slaved). */
128040 + BUG_ON((c != data->cpu) && data->expect_affinity);
128041 + BUG_ON((c == data->cpu) && !data->expect_affinity);
128042 + if (depleted)
128043 + data->num_enter++;
128044 + else
128045 + data->num_exit++;
128046 +}
128047 +
128048 +/* Params used to set up a pool, this also dynamically allocates a BPID */
128049 +static const struct bman_pool_params params_nocb = {
128050 + .flags = BMAN_POOL_FLAG_DYNAMIC_BPID | BMAN_POOL_FLAG_THRESH,
128051 + .thresholds = { TEST_ENTRY, TEST_EXIT, 0, 0 }
128052 +};
128053 +
128054 +/* Params used to set up each cpu's pool with callbacks enabled */
128055 +static struct bman_pool_params params_cb = {
128056 + .bpid = 0, /* will be replaced to match pool_nocb */
128057 + .flags = BMAN_POOL_FLAG_DEPLETION,
128058 + .cb = cb_depletion
128059 +};
128060 +
128061 +static struct bman_pool *pool_nocb;
128062 +static LIST_HEAD(threads);
128063 +
128064 +static int affine_test(void *__data)
128065 +{
128066 + struct bman_pool *pool;
128067 + struct affine_test_data *data = __data;
128068 + struct bman_pool_params my_params = params_cb;
128069 +
128070 + pr_info("thread %d: starting\n", data->cpu);
128071 + /* create the pool */
128072 + my_params.cb_ctx = data;
128073 + pool = bman_new_pool(&my_params);
128074 + BUG_ON(!pool);
128075 + complete(&data->wakeparent);
128076 + wait_for_completion(&data->wakethread);
128077 + init_completion(&data->wakethread);
128078 +
128079 + /* if we're the drainer, we get signalled for that */
128080 + if (data->drain) {
128081 + struct bm_buffer buf;
128082 + int ret;
128083 + pr_info("thread %d: draining...\n", data->cpu);
128084 + do {
128085 + ret = bman_acquire(pool, &buf, 1, 0);
128086 + } while (ret > 0);
128087 + pr_info("thread %d: draining done.\n", data->cpu);
128088 + complete(&data->wakeparent);
128089 + wait_for_completion(&data->wakethread);
128090 + init_completion(&data->wakethread);
128091 + }
128092 +
128093 + /* cleanup */
128094 + bman_free_pool(pool);
128095 + while (!kthread_should_stop())
128096 + cpu_relax();
128097 + pr_info("thread %d: exiting\n", data->cpu);
128098 + return 0;
128099 +}
128100 +
128101 +static struct affine_test_data *start_affine_test(int cpu, int drain)
128102 +{
128103 + struct affine_test_data *data = kmalloc(sizeof(*data), GFP_KERNEL);
128104 +
128105 + if (!data)
128106 + return NULL;
128107 + data->cpu = cpu;
128108 + data->expect_affinity = cpumask_test_cpu(cpu, bman_affine_cpus());
128109 + data->drain = drain;
128110 + data->num_enter = 0;
128111 + data->num_exit = 0;
128112 + init_completion(&data->wakethread);
128113 + init_completion(&data->wakeparent);
128114 + list_add_tail(&data->node, &threads);
128115 + data->t = kthread_create(affine_test, data, "threshtest%d", cpu);
128116 + BUG_ON(IS_ERR(data->t));
128117 + kthread_bind(data->t, cpu);
128118 + wake_up_process(data->t);
128119 + return data;
128120 +}
128121 +
128122 +void bman_test_thresh(void)
128123 +{
128124 + int loop = TEST_NUMBUFS;
128125 + int ret, num_cpus = 0;
128126 + struct affine_test_data *data, *drainer = NULL;
128127 +
128128 + pr_info("bman_test_thresh: start\n");
128129 +
128130 + /* allocate a BPID and seed it */
128131 + pool_nocb = bman_new_pool(&params_nocb);
128132 + BUG_ON(!pool_nocb);
128133 + while (loop--) {
128134 + struct bm_buffer buf;
128135 + bm_buffer_set64(&buf, 0x0badbeef + loop);
128136 + ret = bman_release(pool_nocb, &buf, 1,
128137 + BMAN_RELEASE_FLAG_WAIT);
128138 + BUG_ON(ret);
128139 + }
128140 + while (!bman_rcr_is_empty())
128141 + cpu_relax();
128142 + pr_info("bman_test_thresh: buffers are in\n");
128143 +
128144 + /* create threads and wait for them to create pools */
128145 + params_cb.bpid = bman_get_params(pool_nocb)->bpid;
128146 + for_each_cpu(loop, cpu_online_mask) {
128147 + data = start_affine_test(loop, drainer ? 0 : 1);
128148 + BUG_ON(!data);
128149 + if (!drainer)
128150 + drainer = data;
128151 + num_cpus++;
128152 + wait_for_completion(&data->wakeparent);
128153 + }
128154 +
128155 + /* signal the drainer to start draining */
128156 + complete(&drainer->wakethread);
128157 + wait_for_completion(&drainer->wakeparent);
128158 + init_completion(&drainer->wakeparent);
128159 +
128160 + /* tear down */
128161 + list_for_each_entry_safe(data, drainer, &threads, node) {
128162 + complete(&data->wakethread);
128163 + ret = kthread_stop(data->t);
128164 + BUG_ON(ret);
128165 + list_del(&data->node);
128166 + /* check that we get the expected callbacks (and no others) */
128167 + BUG_ON(data->num_enter != 1);
128168 + BUG_ON(data->num_exit != 0);
128169 + kfree(data);
128170 + }
128171 + bman_free_pool(pool_nocb);
128172 +
128173 + pr_info("bman_test_thresh: done\n");
128174 +}
128175 --- /dev/null
128176 +++ b/drivers/staging/fsl_qbman/dpa_alloc.c
128177 @@ -0,0 +1,706 @@
128178 +/* Copyright 2009-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_qman.h>
128211 +#include <linux/fsl_bman.h>
128212 +
128213 +/* Qman and Bman APIs are front-ends to the common code; */
128214 +
128215 +static DECLARE_DPA_ALLOC(bpalloc); /* BPID allocator */
128216 +static DECLARE_DPA_ALLOC(fqalloc); /* FQID allocator */
128217 +static DECLARE_DPA_ALLOC(qpalloc); /* pool-channel allocator */
128218 +static DECLARE_DPA_ALLOC(cgralloc); /* CGR ID allocator */
128219 +static DECLARE_DPA_ALLOC(ceetm0_challoc); /* CEETM Channel ID allocator */
128220 +static DECLARE_DPA_ALLOC(ceetm0_lfqidalloc); /* CEETM LFQID allocator */
128221 +static DECLARE_DPA_ALLOC(ceetm1_challoc); /* CEETM Channel ID allocator */
128222 +static DECLARE_DPA_ALLOC(ceetm1_lfqidalloc); /* CEETM LFQID allocator */
128223 +
128224 +/* This is a sort-of-conditional dpa_alloc_free() routine. Eg. when releasing
128225 + * FQIDs (probably from user-space), it can filter out those that aren't in the
128226 + * OOS state (better to leak a h/w resource than to crash). This function
128227 + * returns the number of invalid IDs that were not released. */
128228 +static u32 release_id_range(struct dpa_alloc *alloc, u32 id, u32 count,
128229 + int (*is_valid)(u32 id))
128230 +{
128231 + int valid_mode = 0;
128232 + u32 loop = id, total_invalid = 0;
128233 + while (loop < (id + count)) {
128234 + int isvalid = is_valid ? is_valid(loop) : 1;
128235 + if (!valid_mode) {
128236 + /* We're looking for a valid ID to terminate an invalid
128237 + * range */
128238 + if (isvalid) {
128239 + /* We finished a range of invalid IDs, a valid
128240 + * range is now underway */
128241 + valid_mode = 1;
128242 + count -= (loop - id);
128243 + id = loop;
128244 + } else
128245 + total_invalid++;
128246 + } else {
128247 + /* We're looking for an invalid ID to terminate a
128248 + * valid range */
128249 + if (!isvalid) {
128250 + /* Release the range of valid IDs, an unvalid
128251 + * range is now underway */
128252 + if (loop > id)
128253 + dpa_alloc_free(alloc, id, loop - id);
128254 + valid_mode = 0;
128255 + }
128256 + }
128257 + loop++;
128258 + }
128259 + /* Release any unterminated range of valid IDs */
128260 + if (valid_mode && count)
128261 + dpa_alloc_free(alloc, id, count);
128262 + return total_invalid;
128263 +}
128264 +
128265 +/* BPID allocator front-end */
128266 +
128267 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial)
128268 +{
128269 + return dpa_alloc_new(&bpalloc, result, count, align, partial);
128270 +}
128271 +EXPORT_SYMBOL(bman_alloc_bpid_range);
128272 +
128273 +static int bp_cleanup(u32 bpid)
128274 +{
128275 + return bman_shutdown_pool(bpid) == 0;
128276 +}
128277 +void bman_release_bpid_range(u32 bpid, u32 count)
128278 +{
128279 + u32 total_invalid = release_id_range(&bpalloc, bpid, count, bp_cleanup);
128280 + if (total_invalid)
128281 + pr_err("BPID range [%d..%d] (%d) had %d leaks\n",
128282 + bpid, bpid + count - 1, count, total_invalid);
128283 +}
128284 +EXPORT_SYMBOL(bman_release_bpid_range);
128285 +
128286 +void bman_seed_bpid_range(u32 bpid, u32 count)
128287 +{
128288 + dpa_alloc_seed(&bpalloc, bpid, count);
128289 +}
128290 +EXPORT_SYMBOL(bman_seed_bpid_range);
128291 +
128292 +int bman_reserve_bpid_range(u32 bpid, u32 count)
128293 +{
128294 + return dpa_alloc_reserve(&bpalloc, bpid, count);
128295 +}
128296 +EXPORT_SYMBOL(bman_reserve_bpid_range);
128297 +
128298 +
128299 +/* FQID allocator front-end */
128300 +
128301 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial)
128302 +{
128303 + return dpa_alloc_new(&fqalloc, result, count, align, partial);
128304 +}
128305 +EXPORT_SYMBOL(qman_alloc_fqid_range);
128306 +
128307 +static int fq_cleanup(u32 fqid)
128308 +{
128309 + return qman_shutdown_fq(fqid) == 0;
128310 +}
128311 +void qman_release_fqid_range(u32 fqid, u32 count)
128312 +{
128313 + u32 total_invalid = release_id_range(&fqalloc, fqid, count, fq_cleanup);
128314 + if (total_invalid)
128315 + pr_err("FQID range [%d..%d] (%d) had %d leaks\n",
128316 + fqid, fqid + count - 1, count, total_invalid);
128317 +}
128318 +EXPORT_SYMBOL(qman_release_fqid_range);
128319 +
128320 +int qman_reserve_fqid_range(u32 fqid, u32 count)
128321 +{
128322 + return dpa_alloc_reserve(&fqalloc, fqid, count);
128323 +}
128324 +EXPORT_SYMBOL(qman_reserve_fqid_range);
128325 +
128326 +void qman_seed_fqid_range(u32 fqid, u32 count)
128327 +{
128328 + dpa_alloc_seed(&fqalloc, fqid, count);
128329 +}
128330 +EXPORT_SYMBOL(qman_seed_fqid_range);
128331 +
128332 +/* Pool-channel allocator front-end */
128333 +
128334 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial)
128335 +{
128336 + return dpa_alloc_new(&qpalloc, result, count, align, partial);
128337 +}
128338 +EXPORT_SYMBOL(qman_alloc_pool_range);
128339 +
128340 +static int qpool_cleanup(u32 qp)
128341 +{
128342 + /* We query all FQDs starting from
128343 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
128344 + * whose destination channel is the pool-channel being released.
128345 + * When a non-OOS FQD is found we attempt to clean it up */
128346 + struct qman_fq fq = {
128347 + .fqid = 1
128348 + };
128349 + int err;
128350 + do {
128351 + struct qm_mcr_queryfq_np np;
128352 + err = qman_query_fq_np(&fq, &np);
128353 + if (err)
128354 + /* FQID range exceeded, found no problems */
128355 + return 1;
128356 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
128357 + struct qm_fqd fqd;
128358 + err = qman_query_fq(&fq, &fqd);
128359 + BUG_ON(err);
128360 + if (fqd.dest.channel == qp) {
128361 + /* The channel is the FQ's target, clean it */
128362 + if (qman_shutdown_fq(fq.fqid) != 0)
128363 + /* Couldn't shut down the FQ
128364 + so the pool must be leaked */
128365 + return 0;
128366 + }
128367 + }
128368 + /* Move to the next FQID */
128369 + fq.fqid++;
128370 + } while (1);
128371 +}
128372 +void qman_release_pool_range(u32 qp, u32 count)
128373 +{
128374 + u32 total_invalid = release_id_range(&qpalloc, qp,
128375 + count, qpool_cleanup);
128376 + if (total_invalid) {
128377 + /* Pool channels are almost always used individually */
128378 + if (count == 1)
128379 + pr_err("Pool channel 0x%x had %d leaks\n",
128380 + qp, total_invalid);
128381 + else
128382 + pr_err("Pool channels [%d..%d] (%d) had %d leaks\n",
128383 + qp, qp + count - 1, count, total_invalid);
128384 + }
128385 +}
128386 +EXPORT_SYMBOL(qman_release_pool_range);
128387 +
128388 +
128389 +void qman_seed_pool_range(u32 poolid, u32 count)
128390 +{
128391 + dpa_alloc_seed(&qpalloc, poolid, count);
128392 +
128393 +}
128394 +EXPORT_SYMBOL(qman_seed_pool_range);
128395 +
128396 +int qman_reserve_pool_range(u32 poolid, u32 count)
128397 +{
128398 + return dpa_alloc_reserve(&qpalloc, poolid, count);
128399 +}
128400 +EXPORT_SYMBOL(qman_reserve_pool_range);
128401 +
128402 +
128403 +/* CGR ID allocator front-end */
128404 +
128405 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial)
128406 +{
128407 + return dpa_alloc_new(&cgralloc, result, count, align, partial);
128408 +}
128409 +EXPORT_SYMBOL(qman_alloc_cgrid_range);
128410 +
128411 +static int cqr_cleanup(u32 cgrid)
128412 +{
128413 + /* We query all FQDs starting from
128414 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
128415 + * whose CGR is the CGR being released.
128416 + */
128417 + struct qman_fq fq = {
128418 + .fqid = 1
128419 + };
128420 + int err;
128421 + do {
128422 + struct qm_mcr_queryfq_np np;
128423 + err = qman_query_fq_np(&fq, &np);
128424 + if (err)
128425 + /* FQID range exceeded, found no problems */
128426 + return 1;
128427 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
128428 + struct qm_fqd fqd;
128429 + err = qman_query_fq(&fq, &fqd);
128430 + BUG_ON(err);
128431 + if ((fqd.fq_ctrl & QM_FQCTRL_CGE) &&
128432 + (fqd.cgid == cgrid)) {
128433 + pr_err("CRGID 0x%x is being used by FQID 0x%x,"
128434 + " CGR will be leaked\n",
128435 + cgrid, fq.fqid);
128436 + return 1;
128437 + }
128438 + }
128439 + /* Move to the next FQID */
128440 + fq.fqid++;
128441 + } while (1);
128442 +}
128443 +
128444 +void qman_release_cgrid_range(u32 cgrid, u32 count)
128445 +{
128446 + u32 total_invalid = release_id_range(&cgralloc, cgrid,
128447 + count, cqr_cleanup);
128448 + if (total_invalid)
128449 + pr_err("CGRID range [%d..%d] (%d) had %d leaks\n",
128450 + cgrid, cgrid + count - 1, count, total_invalid);
128451 +}
128452 +EXPORT_SYMBOL(qman_release_cgrid_range);
128453 +
128454 +void qman_seed_cgrid_range(u32 cgrid, u32 count)
128455 +{
128456 + dpa_alloc_seed(&cgralloc, cgrid, count);
128457 +
128458 +}
128459 +EXPORT_SYMBOL(qman_seed_cgrid_range);
128460 +
128461 +/* CEETM CHANNEL ID allocator front-end */
128462 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
128463 + int partial)
128464 +{
128465 + return dpa_alloc_new(&ceetm0_challoc, result, count, align, partial);
128466 +}
128467 +EXPORT_SYMBOL(qman_alloc_ceetm0_channel_range);
128468 +
128469 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
128470 + int partial)
128471 +{
128472 + return dpa_alloc_new(&ceetm1_challoc, result, count, align, partial);
128473 +}
128474 +EXPORT_SYMBOL(qman_alloc_ceetm1_channel_range);
128475 +
128476 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count)
128477 +{
128478 + u32 total_invalid;
128479 +
128480 + total_invalid = release_id_range(&ceetm0_challoc, channelid, count,
128481 + NULL);
128482 + if (total_invalid)
128483 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
128484 + channelid, channelid + count - 1, count, total_invalid);
128485 +}
128486 +EXPORT_SYMBOL(qman_release_ceetm0_channel_range);
128487 +
128488 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count)
128489 +{
128490 + dpa_alloc_seed(&ceetm0_challoc, channelid, count);
128491 +
128492 +}
128493 +EXPORT_SYMBOL(qman_seed_ceetm0_channel_range);
128494 +
128495 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count)
128496 +{
128497 + u32 total_invalid;
128498 + total_invalid = release_id_range(&ceetm1_challoc, channelid, count,
128499 + NULL);
128500 + if (total_invalid)
128501 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
128502 + channelid, channelid + count - 1, count, total_invalid);
128503 +}
128504 +EXPORT_SYMBOL(qman_release_ceetm1_channel_range);
128505 +
128506 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count)
128507 +{
128508 + dpa_alloc_seed(&ceetm1_challoc, channelid, count);
128509 +
128510 +}
128511 +EXPORT_SYMBOL(qman_seed_ceetm1_channel_range);
128512 +
128513 +/* CEETM LFQID allocator front-end */
128514 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
128515 + int partial)
128516 +{
128517 + return dpa_alloc_new(&ceetm0_lfqidalloc, result, count, align, partial);
128518 +}
128519 +EXPORT_SYMBOL(qman_alloc_ceetm0_lfqid_range);
128520 +
128521 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
128522 + int partial)
128523 +{
128524 + return dpa_alloc_new(&ceetm1_lfqidalloc, result, count, align, partial);
128525 +}
128526 +EXPORT_SYMBOL(qman_alloc_ceetm1_lfqid_range);
128527 +
128528 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count)
128529 +{
128530 + u32 total_invalid;
128531 +
128532 + total_invalid = release_id_range(&ceetm0_lfqidalloc, lfqid, count,
128533 + NULL);
128534 + if (total_invalid)
128535 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
128536 + lfqid, lfqid + count - 1, count, total_invalid);
128537 +}
128538 +EXPORT_SYMBOL(qman_release_ceetm0_lfqid_range);
128539 +
128540 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count)
128541 +{
128542 + dpa_alloc_seed(&ceetm0_lfqidalloc, lfqid, count);
128543 +
128544 +}
128545 +EXPORT_SYMBOL(qman_seed_ceetm0_lfqid_range);
128546 +
128547 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count)
128548 +{
128549 + u32 total_invalid;
128550 +
128551 + total_invalid = release_id_range(&ceetm1_lfqidalloc, lfqid, count,
128552 + NULL);
128553 + if (total_invalid)
128554 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
128555 + lfqid, lfqid + count - 1, count, total_invalid);
128556 +}
128557 +EXPORT_SYMBOL(qman_release_ceetm1_lfqid_range);
128558 +
128559 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count)
128560 +{
128561 + dpa_alloc_seed(&ceetm1_lfqidalloc, lfqid, count);
128562 +
128563 +}
128564 +EXPORT_SYMBOL(qman_seed_ceetm1_lfqid_range);
128565 +
128566 +
128567 +/* Everything else is the common backend to all the allocators */
128568 +
128569 +/* The allocator is a (possibly-empty) list of these; */
128570 +struct alloc_node {
128571 + struct list_head list;
128572 + u32 base;
128573 + u32 num;
128574 + /* refcount and is_alloced are only set
128575 + when the node is in the used list */
128576 + unsigned int refcount;
128577 + int is_alloced;
128578 +};
128579 +
128580 +/* #define DPA_ALLOC_DEBUG */
128581 +
128582 +#ifdef DPA_ALLOC_DEBUG
128583 +#define DPRINT pr_info
128584 +static void DUMP(struct dpa_alloc *alloc)
128585 +{
128586 + int off = 0;
128587 + char buf[256];
128588 + struct alloc_node *p;
128589 + pr_info("Free Nodes\n");
128590 + list_for_each_entry(p, &alloc->free, list) {
128591 + if (off < 255)
128592 + off += snprintf(buf + off, 255-off, "{%d,%d}",
128593 + p->base, p->base + p->num - 1);
128594 + }
128595 + pr_info("%s\n", buf);
128596 +
128597 + off = 0;
128598 + pr_info("Used Nodes\n");
128599 + list_for_each_entry(p, &alloc->used, list) {
128600 + if (off < 255)
128601 + off += snprintf(buf + off, 255-off, "{%d,%d}",
128602 + p->base, p->base + p->num - 1);
128603 + }
128604 + pr_info("%s\n", buf);
128605 +
128606 +
128607 +
128608 +}
128609 +#else
128610 +#define DPRINT(x...)
128611 +#define DUMP(a)
128612 +#endif
128613 +
128614 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
128615 + int partial)
128616 +{
128617 + struct alloc_node *i = NULL, *next_best = NULL, *used_node = NULL;
128618 + u32 base, next_best_base = 0, num = 0, next_best_num = 0;
128619 + struct alloc_node *margin_left, *margin_right;
128620 +
128621 + *result = (u32)-1;
128622 + DPRINT("alloc_range(%d,%d,%d)\n", count, align, partial);
128623 + DUMP(alloc);
128624 + /* If 'align' is 0, it should behave as though it was 1 */
128625 + if (!align)
128626 + align = 1;
128627 + margin_left = kmalloc(sizeof(*margin_left), GFP_KERNEL);
128628 + if (!margin_left)
128629 + goto err;
128630 + margin_right = kmalloc(sizeof(*margin_right), GFP_KERNEL);
128631 + if (!margin_right) {
128632 + kfree(margin_left);
128633 + goto err;
128634 + }
128635 + spin_lock_irq(&alloc->lock);
128636 + list_for_each_entry(i, &alloc->free, list) {
128637 + base = (i->base + align - 1) / align;
128638 + base *= align;
128639 + if ((base - i->base) >= i->num)
128640 + /* alignment is impossible, regardless of count */
128641 + continue;
128642 + num = i->num - (base - i->base);
128643 + if (num >= count) {
128644 + /* this one will do nicely */
128645 + num = count;
128646 + goto done;
128647 + }
128648 + if (num > next_best_num) {
128649 + next_best = i;
128650 + next_best_base = base;
128651 + next_best_num = num;
128652 + }
128653 + }
128654 + if (partial && next_best) {
128655 + i = next_best;
128656 + base = next_best_base;
128657 + num = next_best_num;
128658 + } else
128659 + i = NULL;
128660 +done:
128661 + if (i) {
128662 + if (base != i->base) {
128663 + margin_left->base = i->base;
128664 + margin_left->num = base - i->base;
128665 + list_add_tail(&margin_left->list, &i->list);
128666 + } else
128667 + kfree(margin_left);
128668 + if ((base + num) < (i->base + i->num)) {
128669 + margin_right->base = base + num;
128670 + margin_right->num = (i->base + i->num) -
128671 + (base + num);
128672 + list_add(&margin_right->list, &i->list);
128673 + } else
128674 + kfree(margin_right);
128675 + list_del(&i->list);
128676 + kfree(i);
128677 + *result = base;
128678 + } else {
128679 + spin_unlock_irq(&alloc->lock);
128680 + kfree(margin_left);
128681 + kfree(margin_right);
128682 + }
128683 +
128684 +err:
128685 + DPRINT("returning %d\n", i ? num : -ENOMEM);
128686 + DUMP(alloc);
128687 + if (!i)
128688 + return -ENOMEM;
128689 +
128690 + /* Add the allocation to the used list with a refcount of 1 */
128691 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
128692 + if (!used_node) {
128693 + spin_unlock_irq(&alloc->lock);
128694 + return -ENOMEM;
128695 + }
128696 + used_node->base = *result;
128697 + used_node->num = num;
128698 + used_node->refcount = 1;
128699 + used_node->is_alloced = 1;
128700 + list_add_tail(&used_node->list, &alloc->used);
128701 + spin_unlock_irq(&alloc->lock);
128702 + return (int)num;
128703 +}
128704 +
128705 +/* Allocate the list node using GFP_ATOMIC, because we *really* want to avoid
128706 + * forcing error-handling on to users in the deallocation path. */
128707 +static void _dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
128708 +{
128709 + struct alloc_node *i, *node = kmalloc(sizeof(*node), GFP_ATOMIC);
128710 + BUG_ON(!node);
128711 + DPRINT("release_range(%d,%d)\n", base_id, count);
128712 + DUMP(alloc);
128713 + BUG_ON(!count);
128714 + spin_lock_irq(&alloc->lock);
128715 +
128716 +
128717 + node->base = base_id;
128718 + node->num = count;
128719 + list_for_each_entry(i, &alloc->free, list) {
128720 + if (i->base >= node->base) {
128721 + /* BUG_ON(any overlapping) */
128722 + BUG_ON(i->base < (node->base + node->num));
128723 + list_add_tail(&node->list, &i->list);
128724 + goto done;
128725 + }
128726 + }
128727 + list_add_tail(&node->list, &alloc->free);
128728 +done:
128729 + /* Merge to the left */
128730 + i = list_entry(node->list.prev, struct alloc_node, list);
128731 + if (node->list.prev != &alloc->free) {
128732 + BUG_ON((i->base + i->num) > node->base);
128733 + if ((i->base + i->num) == node->base) {
128734 + node->base = i->base;
128735 + node->num += i->num;
128736 + list_del(&i->list);
128737 + kfree(i);
128738 + }
128739 + }
128740 + /* Merge to the right */
128741 + i = list_entry(node->list.next, struct alloc_node, list);
128742 + if (node->list.next != &alloc->free) {
128743 + BUG_ON((node->base + node->num) > i->base);
128744 + if ((node->base + node->num) == i->base) {
128745 + node->num += i->num;
128746 + list_del(&i->list);
128747 + kfree(i);
128748 + }
128749 + }
128750 + spin_unlock_irq(&alloc->lock);
128751 + DUMP(alloc);
128752 +}
128753 +
128754 +
128755 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
128756 +{
128757 + struct alloc_node *i = NULL;
128758 + spin_lock_irq(&alloc->lock);
128759 +
128760 + /* First find the node in the used list and decrement its ref count */
128761 + list_for_each_entry(i, &alloc->used, list) {
128762 + if (i->base == base_id && i->num == count) {
128763 + --i->refcount;
128764 + if (i->refcount == 0) {
128765 + list_del(&i->list);
128766 + spin_unlock_irq(&alloc->lock);
128767 + if (i->is_alloced)
128768 + _dpa_alloc_free(alloc, base_id, count);
128769 + kfree(i);
128770 + return;
128771 + }
128772 + spin_unlock_irq(&alloc->lock);
128773 + return;
128774 + }
128775 + }
128776 + /* Couldn't find the allocation */
128777 + pr_err("Attempt to free ID 0x%x COUNT %d that wasn't alloc'd or reserved\n",
128778 + base_id, count);
128779 + spin_unlock_irq(&alloc->lock);
128780 +}
128781 +
128782 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 base_id, u32 count)
128783 +{
128784 + /* Same as free but no previous allocation checking is needed */
128785 + _dpa_alloc_free(alloc, base_id, count);
128786 +}
128787 +
128788 +
128789 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base, u32 num)
128790 +{
128791 + struct alloc_node *i = NULL, *used_node;
128792 +
128793 + DPRINT("alloc_reserve(%d,%d)\n", base, num);
128794 + DUMP(alloc);
128795 +
128796 + spin_lock_irq(&alloc->lock);
128797 +
128798 + /* Check for the node in the used list.
128799 + If found, increase it's refcount */
128800 + list_for_each_entry(i, &alloc->used, list) {
128801 + if ((i->base == base) && (i->num == num)) {
128802 + ++i->refcount;
128803 + spin_unlock_irq(&alloc->lock);
128804 + return 0;
128805 + }
128806 + if ((base >= i->base) && (base < (i->base + i->num))) {
128807 + /* This is an attempt to reserve a region that was
128808 + already reserved or alloced with a different
128809 + base or num */
128810 + pr_err("Cannot reserve %d - %d, it overlaps with"
128811 + " existing reservation from %d - %d\n",
128812 + base, base + num - 1, i->base,
128813 + i->base + i->num - 1);
128814 + spin_unlock_irq(&alloc->lock);
128815 + return -1;
128816 + }
128817 + }
128818 + /* Check to make sure this ID isn't in the free list */
128819 + list_for_each_entry(i, &alloc->free, list) {
128820 + if ((base >= i->base) && (base < (i->base + i->num))) {
128821 + /* yep, the reservation is within this node */
128822 + pr_err("Cannot reserve %d - %d, it overlaps with"
128823 + " free range %d - %d and must be alloced\n",
128824 + base, base + num - 1,
128825 + i->base, i->base + i->num - 1);
128826 + spin_unlock_irq(&alloc->lock);
128827 + return -1;
128828 + }
128829 + }
128830 + /* Add the allocation to the used list with a refcount of 1 */
128831 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
128832 + if (!used_node) {
128833 + spin_unlock_irq(&alloc->lock);
128834 + return -ENOMEM;
128835 +
128836 + }
128837 + used_node->base = base;
128838 + used_node->num = num;
128839 + used_node->refcount = 1;
128840 + used_node->is_alloced = 0;
128841 + list_add_tail(&used_node->list, &alloc->used);
128842 + spin_unlock_irq(&alloc->lock);
128843 + return 0;
128844 +}
128845 +
128846 +
128847 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count)
128848 +{
128849 + struct alloc_node *i = NULL;
128850 + DPRINT("alloc_pop()\n");
128851 + DUMP(alloc);
128852 + spin_lock_irq(&alloc->lock);
128853 + if (!list_empty(&alloc->free)) {
128854 + i = list_entry(alloc->free.next, struct alloc_node, list);
128855 + list_del(&i->list);
128856 + }
128857 + spin_unlock_irq(&alloc->lock);
128858 + DPRINT("returning %d\n", i ? 0 : -ENOMEM);
128859 + DUMP(alloc);
128860 + if (!i)
128861 + return -ENOMEM;
128862 + *result = i->base;
128863 + *count = i->num;
128864 + kfree(i);
128865 + return 0;
128866 +}
128867 +
128868 +int dpa_alloc_check(struct dpa_alloc *list_head, u32 item)
128869 +{
128870 + struct alloc_node *i = NULL;
128871 + int res = 0;
128872 + DPRINT("alloc_check()\n");
128873 + spin_lock_irq(&list_head->lock);
128874 +
128875 + list_for_each_entry(i, &list_head->free, list) {
128876 + if ((item >= i->base) && (item < (i->base + i->num))) {
128877 + res = 1;
128878 + break;
128879 + }
128880 + }
128881 + spin_unlock_irq(&list_head->lock);
128882 + return res;
128883 +}
128884 --- /dev/null
128885 +++ b/drivers/staging/fsl_qbman/dpa_sys.h
128886 @@ -0,0 +1,259 @@
128887 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
128888 + *
128889 + * Redistribution and use in source and binary forms, with or without
128890 + * modification, are permitted provided that the following conditions are met:
128891 + * * Redistributions of source code must retain the above copyright
128892 + * notice, this list of conditions and the following disclaimer.
128893 + * * Redistributions in binary form must reproduce the above copyright
128894 + * notice, this list of conditions and the following disclaimer in the
128895 + * documentation and/or other materials provided with the distribution.
128896 + * * Neither the name of Freescale Semiconductor nor the
128897 + * names of its contributors may be used to endorse or promote products
128898 + * derived from this software without specific prior written permission.
128899 + *
128900 + *
128901 + * ALTERNATIVELY, this software may be distributed under the terms of the
128902 + * GNU General Public License ("GPL") as published by the Free Software
128903 + * Foundation, either version 2 of that License or (at your option) any
128904 + * later version.
128905 + *
128906 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128907 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128908 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128909 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128910 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128911 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128912 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128913 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128914 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128915 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128916 + */
128917 +
128918 +#ifndef DPA_SYS_H
128919 +#define DPA_SYS_H
128920 +
128921 +#include <linux/kernel.h>
128922 +#include <linux/errno.h>
128923 +#include <linux/io.h>
128924 +#include <linux/dma-mapping.h>
128925 +#include <linux/bootmem.h>
128926 +#include <linux/slab.h>
128927 +#include <linux/module.h>
128928 +#include <linux/init.h>
128929 +#include <linux/interrupt.h>
128930 +#include <linux/delay.h>
128931 +#include <linux/of_platform.h>
128932 +#include <linux/of_address.h>
128933 +#include <linux/of_irq.h>
128934 +#include <linux/kthread.h>
128935 +#include <linux/memblock.h>
128936 +#include <linux/completion.h>
128937 +#include <linux/log2.h>
128938 +#include <linux/types.h>
128939 +#include <linux/ioctl.h>
128940 +#include <linux/miscdevice.h>
128941 +#include <linux/uaccess.h>
128942 +#include <linux/debugfs.h>
128943 +#include <linux/seq_file.h>
128944 +#include <linux/device.h>
128945 +#include <linux/uio_driver.h>
128946 +#include <linux/smp.h>
128947 +#include <linux/fsl_hypervisor.h>
128948 +#include <linux/vmalloc.h>
128949 +#include <linux/ctype.h>
128950 +#include <linux/math64.h>
128951 +#include <linux/bitops.h>
128952 +
128953 +#include <linux/fsl_usdpaa.h>
128954 +
128955 +/* When copying aligned words or shorts, try to avoid memcpy() */
128956 +#define CONFIG_TRY_BETTER_MEMCPY
128957 +
128958 +/* For 2-element tables related to cache-inhibited and cache-enabled mappings */
128959 +#define DPA_PORTAL_CE 0
128960 +#define DPA_PORTAL_CI 1
128961 +
128962 +/***********************/
128963 +/* Misc inline assists */
128964 +/***********************/
128965 +
128966 +#if defined CONFIG_PPC32
128967 +#include "dpa_sys_ppc32.h"
128968 +#elif defined CONFIG_PPC64
128969 +#include "dpa_sys_ppc64.h"
128970 +#elif defined CONFIG_ARM
128971 +#include "dpa_sys_arm.h"
128972 +#elif defined CONFIG_ARM64
128973 +#include "dpa_sys_arm64.h"
128974 +#endif
128975 +
128976 +
128977 +#ifdef CONFIG_FSL_DPA_CHECKING
128978 +#define DPA_ASSERT(x) \
128979 + do { \
128980 + if (!(x)) { \
128981 + pr_crit("ASSERT: (%s:%d) %s\n", __FILE__, __LINE__, \
128982 + __stringify_1(x)); \
128983 + dump_stack(); \
128984 + panic("assertion failure"); \
128985 + } \
128986 + } while (0)
128987 +#else
128988 +#define DPA_ASSERT(x)
128989 +#endif
128990 +
128991 +/* memcpy() stuff - when you know alignments in advance */
128992 +#ifdef CONFIG_TRY_BETTER_MEMCPY
128993 +static inline void copy_words(void *dest, const void *src, size_t sz)
128994 +{
128995 + u32 *__dest = dest;
128996 + const u32 *__src = src;
128997 + size_t __sz = sz >> 2;
128998 + BUG_ON((unsigned long)dest & 0x3);
128999 + BUG_ON((unsigned long)src & 0x3);
129000 + BUG_ON(sz & 0x3);
129001 + while (__sz--)
129002 + *(__dest++) = *(__src++);
129003 +}
129004 +static inline void copy_shorts(void *dest, const void *src, size_t sz)
129005 +{
129006 + u16 *__dest = dest;
129007 + const u16 *__src = src;
129008 + size_t __sz = sz >> 1;
129009 + BUG_ON((unsigned long)dest & 0x1);
129010 + BUG_ON((unsigned long)src & 0x1);
129011 + BUG_ON(sz & 0x1);
129012 + while (__sz--)
129013 + *(__dest++) = *(__src++);
129014 +}
129015 +static inline void copy_bytes(void *dest, const void *src, size_t sz)
129016 +{
129017 + u8 *__dest = dest;
129018 + const u8 *__src = src;
129019 + while (sz--)
129020 + *(__dest++) = *(__src++);
129021 +}
129022 +#else
129023 +#define copy_words memcpy
129024 +#define copy_shorts memcpy
129025 +#define copy_bytes memcpy
129026 +#endif
129027 +
129028 +/************/
129029 +/* RB-trees */
129030 +/************/
129031 +
129032 +/* We encapsulate RB-trees so that its easier to use non-linux forms in
129033 + * non-linux systems. This also encapsulates the extra plumbing that linux code
129034 + * usually provides when using RB-trees. This encapsulation assumes that the
129035 + * data type held by the tree is u32. */
129036 +
129037 +struct dpa_rbtree {
129038 + struct rb_root root;
129039 +};
129040 +#define DPA_RBTREE { .root = RB_ROOT }
129041 +
129042 +static inline void dpa_rbtree_init(struct dpa_rbtree *tree)
129043 +{
129044 + tree->root = RB_ROOT;
129045 +}
129046 +
129047 +#define IMPLEMENT_DPA_RBTREE(name, type, node_field, val_field) \
129048 +static inline int name##_push(struct dpa_rbtree *tree, type *obj) \
129049 +{ \
129050 + struct rb_node *parent = NULL, **p = &tree->root.rb_node; \
129051 + while (*p) { \
129052 + u32 item; \
129053 + parent = *p; \
129054 + item = rb_entry(parent, type, node_field)->val_field; \
129055 + if (obj->val_field < item) \
129056 + p = &parent->rb_left; \
129057 + else if (obj->val_field > item) \
129058 + p = &parent->rb_right; \
129059 + else \
129060 + return -EBUSY; \
129061 + } \
129062 + rb_link_node(&obj->node_field, parent, p); \
129063 + rb_insert_color(&obj->node_field, &tree->root); \
129064 + return 0; \
129065 +} \
129066 +static inline void name##_del(struct dpa_rbtree *tree, type *obj) \
129067 +{ \
129068 + rb_erase(&obj->node_field, &tree->root); \
129069 +} \
129070 +static inline type *name##_find(struct dpa_rbtree *tree, u32 val) \
129071 +{ \
129072 + type *ret; \
129073 + struct rb_node *p = tree->root.rb_node; \
129074 + while (p) { \
129075 + ret = rb_entry(p, type, node_field); \
129076 + if (val < ret->val_field) \
129077 + p = p->rb_left; \
129078 + else if (val > ret->val_field) \
129079 + p = p->rb_right; \
129080 + else \
129081 + return ret; \
129082 + } \
129083 + return NULL; \
129084 +}
129085 +
129086 +/************/
129087 +/* Bootargs */
129088 +/************/
129089 +
129090 +/* Qman has "qportals=" and Bman has "bportals=", they use the same syntax
129091 + * though; a comma-separated list of items, each item being a cpu index and/or a
129092 + * range of cpu indices, and each item optionally be prefixed by "s" to indicate
129093 + * that the portal associated with that cpu should be shared. See bman_driver.c
129094 + * for more specifics. */
129095 +static int __parse_portals_cpu(const char **s, unsigned int *cpu)
129096 +{
129097 + *cpu = 0;
129098 + if (!isdigit(**s))
129099 + return -EINVAL;
129100 + while (isdigit(**s))
129101 + *cpu = *cpu * 10 + (*((*s)++) - '0');
129102 + return 0;
129103 +}
129104 +static inline int parse_portals_bootarg(char *str, struct cpumask *want_shared,
129105 + struct cpumask *want_unshared,
129106 + const char *argname)
129107 +{
129108 + const char *s = str;
129109 + unsigned int shared, cpu1, cpu2, loop;
129110 +
129111 +keep_going:
129112 + if (*s == 's') {
129113 + shared = 1;
129114 + s++;
129115 + } else
129116 + shared = 0;
129117 + if (__parse_portals_cpu(&s, &cpu1))
129118 + goto err;
129119 + if (*s == '-') {
129120 + s++;
129121 + if (__parse_portals_cpu(&s, &cpu2))
129122 + goto err;
129123 + if (cpu2 < cpu1)
129124 + goto err;
129125 + } else
129126 + cpu2 = cpu1;
129127 + for (loop = cpu1; loop <= cpu2; loop++)
129128 + cpumask_set_cpu(loop, shared ? want_shared : want_unshared);
129129 + if (*s == ',') {
129130 + s++;
129131 + goto keep_going;
129132 + } else if ((*s == '\0') || isspace(*s))
129133 + return 0;
129134 +err:
129135 + pr_crit("Malformed %s argument: %s, offset: %lu\n", argname, str,
129136 + (unsigned long)s - (unsigned long)str);
129137 + return -EINVAL;
129138 +}
129139 +#ifdef CONFIG_FSL_USDPAA
129140 +/* Hooks from fsl_usdpaa_irq.c to fsl_usdpaa.c */
129141 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
129142 + enum usdpaa_portal_type ptype, unsigned int *irq,
129143 + void **iir_reg);
129144 +#endif
129145 +#endif /* DPA_SYS_H */
129146 --- /dev/null
129147 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm.h
129148 @@ -0,0 +1,95 @@
129149 +/* Copyright 2016 Freescale Semiconductor, Inc.
129150 + *
129151 + * Redistribution and use in source and binary forms, with or without
129152 + * modification, are permitted provided that the following conditions are met:
129153 + * * Redistributions of source code must retain the above copyright
129154 + * notice, this list of conditions and the following disclaimer.
129155 + * * Redistributions in binary form must reproduce the above copyright
129156 + * notice, this list of conditions and the following disclaimer in the
129157 + * documentation and/or other materials provided with the distribution.
129158 + * * Neither the name of Freescale Semiconductor nor the
129159 + * names of its contributors may be used to endorse or promote products
129160 + * derived from this software without specific prior written permission.
129161 + *
129162 + *
129163 + * ALTERNATIVELY, this software may be distributed under the terms of the
129164 + * GNU General Public License ("GPL") as published by the Free Software
129165 + * Foundation, either version 2 of that License or (at your option) any
129166 + * later version.
129167 + *
129168 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129169 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129170 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129171 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129172 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129173 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129174 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129175 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129176 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129177 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129178 + */
129179 +
129180 +#ifndef DPA_SYS_ARM_H
129181 +#define DPA_SYS_ARM_H
129182 +
129183 +#include <asm/cacheflush.h>
129184 +#include <asm/barrier.h>
129185 +
129186 +/* Implementation of ARM specific routines */
129187 +
129188 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129189 + * barriers and that dcb*() won't fall victim to compiler or execution
129190 + * reordering with respect to other code/instructions that manipulate the same
129191 + * cacheline. */
129192 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
129193 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
129194 +#define dcbf(p) { asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r" (p) : "memory"); }
129195 +#define dcbt_ro(p) { asm volatile("pld [%0, #64];": : "r" (p)); }
129196 +#define dcbt_rw(p) { asm volatile("pldw [%0, #64];": : "r" (p)); }
129197 +#define dcbi(p) { asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (p) : "memory"); }
129198 +
129199 +#define dcbz_64(p) { memset(p, 0, sizeof(*p)); }
129200 +
129201 +#define dcbf_64(p) \
129202 + do { \
129203 + dcbf((u32)p); \
129204 + } while (0)
129205 +/* Commonly used combo */
129206 +#define dcbit_ro(p) \
129207 + do { \
129208 + dcbi((u32)p); \
129209 + dcbt_ro((u32)p); \
129210 + } while (0)
129211 +
129212 +static inline u64 mfatb(void)
129213 +{
129214 + return get_cycles();
129215 +}
129216 +
129217 +static inline u32 in_be32(volatile void *addr)
129218 +{
129219 + return be32_to_cpu(*((volatile u32 *) addr));
129220 +}
129221 +
129222 +static inline void out_be32(void *addr, u32 val)
129223 +{
129224 + *((u32 *) addr) = cpu_to_be32(val);
129225 +}
129226 +
129227 +
129228 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
129229 +{
129230 + *p |= mask;
129231 +}
129232 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
129233 +{
129234 + *p &= ~mask;
129235 +}
129236 +
129237 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
129238 +{
129239 + __cpuc_flush_dcache_area((void *) start, stop - start);
129240 +}
129241 +
129242 +#define hard_smp_processor_id() raw_smp_processor_id()
129243 +#endif
129244 --- /dev/null
129245 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm64.h
129246 @@ -0,0 +1,102 @@
129247 +/* Copyright 2014 Freescale Semiconductor, Inc.
129248 + *
129249 + * Redistribution and use in source and binary forms, with or without
129250 + * modification, are permitted provided that the following conditions are met:
129251 + * * Redistributions of source code must retain the above copyright
129252 + * notice, this list of conditions and the following disclaimer.
129253 + * * Redistributions in binary form must reproduce the above copyright
129254 + * notice, this list of conditions and the following disclaimer in the
129255 + * documentation and/or other materials provided with the distribution.
129256 + * * Neither the name of Freescale Semiconductor nor the
129257 + * names of its contributors may be used to endorse or promote products
129258 + * derived from this software without specific prior written permission.
129259 + *
129260 + *
129261 + * ALTERNATIVELY, this software may be distributed under the terms of the
129262 + * GNU General Public License ("GPL") as published by the Free Software
129263 + * Foundation, either version 2 of that License or (at your option) any
129264 + * later version.
129265 + *
129266 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129267 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129268 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129269 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129270 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129271 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129272 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129273 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129274 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129275 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129276 + */
129277 +
129278 +#ifndef DPA_SYS_ARM64_H
129279 +#define DPA_SYS_ARM64_H
129280 +
129281 +#include <asm/cacheflush.h>
129282 +#include <asm/barrier.h>
129283 +
129284 +/* Implementation of ARM 64 bit specific routines */
129285 +
129286 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129287 + * barriers and that dcb*() won't fall victim to compiler or execution
129288 + * reordering with respect to other code/instructions that manipulate the same
129289 + * cacheline. */
129290 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
129291 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
129292 +#define dcbf(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); }
129293 +#define dcbt_ro(p) { asm volatile("prfm pldl1keep, [%0, #0]" : : "r" (p)); }
129294 +#define dcbt_rw(p) { asm volatile("prfm pstl1keep, [%0, #0]" : : "r" (p)); }
129295 +#define dcbi(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); }
129296 +#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
129297 +
129298 +#define dcbz_64(p) \
129299 + do { \
129300 + dcbz(p); \
129301 + } while (0)
129302 +
129303 +#define dcbf_64(p) \
129304 + do { \
129305 + dcbf(p); \
129306 + } while (0)
129307 +/* Commonly used combo */
129308 +#define dcbit_ro(p) \
129309 + do { \
129310 + dcbi(p); \
129311 + dcbt_ro(p); \
129312 + } while (0)
129313 +
129314 +static inline u64 mfatb(void)
129315 +{
129316 + return get_cycles();
129317 +}
129318 +
129319 +static inline u32 in_be32(volatile void *addr)
129320 +{
129321 + return be32_to_cpu(*((volatile u32 *) addr));
129322 +}
129323 +
129324 +static inline void out_be32(void *addr, u32 val)
129325 +{
129326 + *((u32 *) addr) = cpu_to_be32(val);
129327 +}
129328 +
129329 +
129330 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
129331 +{
129332 + *p |= mask;
129333 +}
129334 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
129335 +{
129336 + *p &= ~mask;
129337 +}
129338 +
129339 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
129340 +{
129341 + __flush_dcache_area((void *) start, stop - start);
129342 +}
129343 +
129344 +#define hard_smp_processor_id() raw_smp_processor_id()
129345 +
129346 +
129347 +
129348 +#endif
129349 --- /dev/null
129350 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc32.h
129351 @@ -0,0 +1,70 @@
129352 +/* Copyright 2014 Freescale Semiconductor, Inc.
129353 + *
129354 + * Redistribution and use in source and binary forms, with or without
129355 + * modification, are permitted provided that the following conditions are met:
129356 + * * Redistributions of source code must retain the above copyright
129357 + * notice, this list of conditions and the following disclaimer.
129358 + * * Redistributions in binary form must reproduce the above copyright
129359 + * notice, this list of conditions and the following disclaimer in the
129360 + * documentation and/or other materials provided with the distribution.
129361 + * * Neither the name of Freescale Semiconductor nor the
129362 + * names of its contributors may be used to endorse or promote products
129363 + * derived from this software without specific prior written permission.
129364 + *
129365 + *
129366 + * ALTERNATIVELY, this software may be distributed under the terms of the
129367 + * GNU General Public License ("GPL") as published by the Free Software
129368 + * Foundation, either version 2 of that License or (at your option) any
129369 + * later version.
129370 + *
129371 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129372 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129373 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129374 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129375 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129376 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129377 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129378 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129379 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129380 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129381 + */
129382 +
129383 +#ifndef DPA_SYS_PPC32_H
129384 +#define DPA_SYS_PPC32_H
129385 +
129386 +/* Implementation of PowerPC 32 bit specific routines */
129387 +
129388 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129389 + * barriers and that dcb*() won't fall victim to compiler or execution
129390 + * reordering with respect to other code/instructions that manipulate the same
129391 + * cacheline. */
129392 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
129393 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
129394 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
129395 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
129396 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
129397 +#define dcbi(p) dcbf(p)
129398 +
129399 +#define dcbzl(p) __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p))
129400 +#define dcbz_64(p) dcbzl(p)
129401 +#define dcbf_64(p) dcbf(p)
129402 +
129403 +/* Commonly used combo */
129404 +#define dcbit_ro(p) \
129405 + do { \
129406 + dcbi(p); \
129407 + dcbt_ro(p); \
129408 + } while (0)
129409 +
129410 +static inline u64 mfatb(void)
129411 +{
129412 + u32 hi, lo, chk;
129413 + do {
129414 + hi = mfspr(SPRN_ATBU);
129415 + lo = mfspr(SPRN_ATBL);
129416 + chk = mfspr(SPRN_ATBU);
129417 + } while (unlikely(hi != chk));
129418 + return ((u64)hi << 32) | (u64)lo;
129419 +}
129420 +
129421 +#endif
129422 --- /dev/null
129423 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc64.h
129424 @@ -0,0 +1,79 @@
129425 +/* Copyright 2014 Freescale Semiconductor, Inc.
129426 + *
129427 + * Redistribution and use in source and binary forms, with or without
129428 + * modification, are permitted provided that the following conditions are met:
129429 + * * Redistributions of source code must retain the above copyright
129430 + * notice, this list of conditions and the following disclaimer.
129431 + * * Redistributions in binary form must reproduce the above copyright
129432 + * notice, this list of conditions and the following disclaimer in the
129433 + * documentation and/or other materials provided with the distribution.
129434 + * * Neither the name of Freescale Semiconductor nor the
129435 + * names of its contributors may be used to endorse or promote products
129436 + * derived from this software without specific prior written permission.
129437 + *
129438 + *
129439 + * ALTERNATIVELY, this software may be distributed under the terms of the
129440 + * GNU General Public License ("GPL") as published by the Free Software
129441 + * Foundation, either version 2 of that License or (at your option) any
129442 + * later version.
129443 + *
129444 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129445 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129446 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129447 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129448 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129449 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129450 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129451 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129452 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129453 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129454 + */
129455 +
129456 +#ifndef DPA_SYS_PPC64_H
129457 +#define DPA_SYS_PPC64_H
129458 +
129459 +/* Implementation of PowerPC 64 bit specific routines */
129460 +
129461 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129462 + * barriers and that dcb*() won't fall victim to compiler or execution
129463 + * reordering with respect to other code/instructions that manipulate the same
129464 + * cacheline. */
129465 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
129466 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
129467 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
129468 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
129469 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
129470 +#define dcbi(p) dcbf(p)
129471 +
129472 +#define dcbz(p) __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p))
129473 +#define dcbz_64(p) \
129474 + do { \
129475 + dcbz((void*)p + 32); \
129476 + dcbz(p); \
129477 + } while (0)
129478 +#define dcbf_64(p) \
129479 + do { \
129480 + dcbf((void*)p + 32); \
129481 + dcbf(p); \
129482 + } while (0)
129483 +/* Commonly used combo */
129484 +#define dcbit_ro(p) \
129485 + do { \
129486 + dcbi(p); \
129487 + dcbi((void*)p + 32); \
129488 + dcbt_ro(p); \
129489 + dcbt_ro((void*)p + 32); \
129490 + } while (0)
129491 +
129492 +static inline u64 mfatb(void)
129493 +{
129494 + u32 hi, lo, chk;
129495 + do {
129496 + hi = mfspr(SPRN_ATBU);
129497 + lo = mfspr(SPRN_ATBL);
129498 + chk = mfspr(SPRN_ATBU);
129499 + } while (unlikely(hi != chk));
129500 + return ((u64)hi << 32) | (u64)lo;
129501 +}
129502 +
129503 +#endif
129504 --- /dev/null
129505 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c
129506 @@ -0,0 +1,1983 @@
129507 +/* Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
129508 + * Authors: Andy Fleming <afleming@freescale.com>
129509 + * Timur Tabi <timur@freescale.com>
129510 + * Geoff Thorpe <Geoff.Thorpe@freescale.com>
129511 + *
129512 + * This file is licensed under the terms of the GNU General Public License
129513 + * version 2. This program is licensed "as is" without any warranty of any
129514 + * kind, whether express or implied.
129515 + */
129516 +
129517 +
129518 +#include <linux/miscdevice.h>
129519 +#include <linux/fs.h>
129520 +#include <linux/cdev.h>
129521 +#include <linux/mm.h>
129522 +#include <linux/of.h>
129523 +#include <linux/memblock.h>
129524 +#include <linux/slab.h>
129525 +#include <linux/mman.h>
129526 +#include <linux/of_reserved_mem.h>
129527 +
129528 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
129529 +#include <mm/mmu_decl.h>
129530 +#endif
129531 +
129532 +#include "dpa_sys.h"
129533 +#include <linux/fsl_usdpaa.h>
129534 +#include "bman_low.h"
129535 +#include "qman_low.h"
129536 +
129537 +/* Physical address range of the memory reservation, exported for mm/mem.c */
129538 +static u64 phys_start;
129539 +static u64 phys_size;
129540 +static u64 arg_phys_size;
129541 +
129542 +/* PFN versions of the above */
129543 +static unsigned long pfn_start;
129544 +static unsigned long pfn_size;
129545 +
129546 +/* Memory reservations are manipulated under this spinlock (which is why 'refs'
129547 + * isn't atomic_t). */
129548 +static DEFINE_SPINLOCK(mem_lock);
129549 +
129550 +/* The range of TLB1 indices */
129551 +static unsigned int first_tlb;
129552 +static unsigned int num_tlb = 1;
129553 +static unsigned int current_tlb; /* loops around for fault handling */
129554 +
129555 +/* Memory reservation is represented as a list of 'mem_fragment's, some of which
129556 + * may be mapped. Unmapped fragments are always merged where possible. */
129557 +static LIST_HEAD(mem_list);
129558 +
129559 +struct mem_mapping;
129560 +
129561 +/* Memory fragments are in 'mem_list'. */
129562 +struct mem_fragment {
129563 + u64 base;
129564 + u64 len;
129565 + unsigned long pfn_base; /* PFN version of 'base' */
129566 + unsigned long pfn_len; /* PFN version of 'len' */
129567 + unsigned int refs; /* zero if unmapped */
129568 + u64 root_len; /* Size of the orignal fragment */
129569 + unsigned long root_pfn; /* PFN of the orignal fragment */
129570 + struct list_head list;
129571 + /* if mapped, flags+name captured at creation time */
129572 + u32 flags;
129573 + char name[USDPAA_DMA_NAME_MAX];
129574 + u64 map_len;
129575 + /* support multi-process locks per-memory-fragment. */
129576 + int has_locking;
129577 + wait_queue_head_t wq;
129578 + struct mem_mapping *owner;
129579 +};
129580 +
129581 +/* Mappings of memory fragments in 'struct ctx'. These are created from
129582 + * ioctl(USDPAA_IOCTL_DMA_MAP), though the actual mapping then happens via a
129583 + * mmap(). */
129584 +struct mem_mapping {
129585 + struct mem_fragment *root_frag;
129586 + u32 frag_count;
129587 + u64 total_size;
129588 + struct list_head list;
129589 + int refs;
129590 + void *virt_addr;
129591 +};
129592 +
129593 +struct portal_mapping {
129594 + struct usdpaa_ioctl_portal_map user;
129595 + union {
129596 + struct qm_portal_config *qportal;
129597 + struct bm_portal_config *bportal;
129598 + };
129599 + /* Declare space for the portals in case the process
129600 + exits unexpectedly and needs to be cleaned by the kernel */
129601 + union {
129602 + struct qm_portal qman_portal_low;
129603 + struct bm_portal bman_portal_low;
129604 + };
129605 + struct list_head list;
129606 + struct resource *phys;
129607 + struct iommu_domain *iommu_domain;
129608 +};
129609 +
129610 +/* Track the DPAA resources the process is using */
129611 +struct active_resource {
129612 + struct list_head list;
129613 + u32 id;
129614 + u32 num;
129615 + unsigned int refcount;
129616 +};
129617 +
129618 +/* Per-FD state (which should also be per-process but we don't enforce that) */
129619 +struct ctx {
129620 + /* Lock to protect the context */
129621 + spinlock_t lock;
129622 + /* Allocated resources get put here for accounting */
129623 + struct list_head resources[usdpaa_id_max];
129624 + /* list of DMA maps */
129625 + struct list_head maps;
129626 + /* list of portal maps */
129627 + struct list_head portals;
129628 +};
129629 +
129630 +/* Different resource classes */
129631 +static const struct alloc_backend {
129632 + enum usdpaa_id_type id_type;
129633 + int (*alloc)(u32 *, u32, u32, int);
129634 + void (*release)(u32 base, unsigned int count);
129635 + int (*reserve)(u32 base, unsigned int count);
129636 + const char *acronym;
129637 +} alloc_backends[] = {
129638 + {
129639 + .id_type = usdpaa_id_fqid,
129640 + .alloc = qman_alloc_fqid_range,
129641 + .release = qman_release_fqid_range,
129642 + .reserve = qman_reserve_fqid_range,
129643 + .acronym = "FQID"
129644 + },
129645 + {
129646 + .id_type = usdpaa_id_bpid,
129647 + .alloc = bman_alloc_bpid_range,
129648 + .release = bman_release_bpid_range,
129649 + .reserve = bman_reserve_bpid_range,
129650 + .acronym = "BPID"
129651 + },
129652 + {
129653 + .id_type = usdpaa_id_qpool,
129654 + .alloc = qman_alloc_pool_range,
129655 + .release = qman_release_pool_range,
129656 + .reserve = qman_reserve_pool_range,
129657 + .acronym = "QPOOL"
129658 + },
129659 + {
129660 + .id_type = usdpaa_id_cgrid,
129661 + .alloc = qman_alloc_cgrid_range,
129662 + .release = qman_release_cgrid_range,
129663 + .acronym = "CGRID"
129664 + },
129665 + {
129666 + .id_type = usdpaa_id_ceetm0_lfqid,
129667 + .alloc = qman_alloc_ceetm0_lfqid_range,
129668 + .release = qman_release_ceetm0_lfqid_range,
129669 + .acronym = "CEETM0_LFQID"
129670 + },
129671 + {
129672 + .id_type = usdpaa_id_ceetm0_channelid,
129673 + .alloc = qman_alloc_ceetm0_channel_range,
129674 + .release = qman_release_ceetm0_channel_range,
129675 + .acronym = "CEETM0_LFQID"
129676 + },
129677 + {
129678 + .id_type = usdpaa_id_ceetm1_lfqid,
129679 + .alloc = qman_alloc_ceetm1_lfqid_range,
129680 + .release = qman_release_ceetm1_lfqid_range,
129681 + .acronym = "CEETM1_LFQID"
129682 + },
129683 + {
129684 + .id_type = usdpaa_id_ceetm1_channelid,
129685 + .alloc = qman_alloc_ceetm1_channel_range,
129686 + .release = qman_release_ceetm1_channel_range,
129687 + .acronym = "CEETM1_LFQID"
129688 + },
129689 + {
129690 + /* This terminates the array */
129691 + .id_type = usdpaa_id_max
129692 + }
129693 +};
129694 +
129695 +/* Determines the largest acceptable page size for a given size
129696 + The sizes are determined by what the TLB1 acceptable page sizes are */
129697 +static u32 largest_page_size(u32 size)
129698 +{
129699 + int shift = 30; /* Start at 1G size */
129700 + if (size < 4096)
129701 + return 0;
129702 + do {
129703 + if (size >= (1<<shift))
129704 + return 1<<shift;
129705 + shift -= 2;
129706 + } while (shift >= 12); /* Up to 4k */
129707 + return 0;
129708 +}
129709 +
129710 +/* Determine if value is power of 4 */
129711 +static inline bool is_power_of_4(u64 x)
129712 +{
129713 + if (x == 0 || ((x & (x - 1)) != 0))
129714 + return false;
129715 + return !!(x & 0x5555555555555555ull);
129716 +}
129717 +
129718 +/* Helper for ioctl_dma_map() when we have a larger fragment than we need. This
129719 + * splits the fragment into 4 and returns the upper-most. (The caller can loop
129720 + * until it has a suitable fragment size.) */
129721 +static struct mem_fragment *split_frag(struct mem_fragment *frag)
129722 +{
129723 + struct mem_fragment *x[3];
129724 +
129725 + x[0] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129726 + x[1] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129727 + x[2] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129728 + if (!x[0] || !x[1] || !x[2]) {
129729 + kfree(x[0]);
129730 + kfree(x[1]);
129731 + kfree(x[2]);
129732 + return NULL;
129733 + }
129734 + BUG_ON(frag->refs);
129735 + frag->len >>= 2;
129736 + frag->pfn_len >>= 2;
129737 + x[0]->base = frag->base + frag->len;
129738 + x[1]->base = x[0]->base + frag->len;
129739 + x[2]->base = x[1]->base + frag->len;
129740 + x[0]->len = x[1]->len = x[2]->len = frag->len;
129741 + x[0]->pfn_base = frag->pfn_base + frag->pfn_len;
129742 + x[1]->pfn_base = x[0]->pfn_base + frag->pfn_len;
129743 + x[2]->pfn_base = x[1]->pfn_base + frag->pfn_len;
129744 + x[0]->pfn_len = x[1]->pfn_len = x[2]->pfn_len = frag->pfn_len;
129745 + x[0]->refs = x[1]->refs = x[2]->refs = 0;
129746 + x[0]->root_len = x[1]->root_len = x[2]->root_len = frag->root_len;
129747 + x[0]->root_pfn = x[1]->root_pfn = x[2]->root_pfn = frag->root_pfn;
129748 + x[0]->name[0] = x[1]->name[0] = x[2]->name[0] = 0;
129749 + list_add_tail(&x[0]->list, &frag->list);
129750 + list_add_tail(&x[1]->list, &x[0]->list);
129751 + list_add_tail(&x[2]->list, &x[1]->list);
129752 + return x[2];
129753 +}
129754 +
129755 +static __maybe_unused void dump_frags(void)
129756 +{
129757 + struct mem_fragment *frag;
129758 + int i = 0;
129759 + list_for_each_entry(frag, &mem_list, list) {
129760 + 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",
129761 + i, frag->base, frag->pfn_base,
129762 + frag->len, frag->root_len, frag->root_pfn,
129763 + frag->refs, frag->name);
129764 + ++i;
129765 + }
129766 +}
129767 +
129768 +/* Walk the list of fragments and adjoin neighbouring segments if possible */
129769 +static void compress_frags(void)
129770 +{
129771 + /* Walk the fragment list and combine fragments */
129772 + struct mem_fragment *frag, *nxtfrag;
129773 + u64 len = 0;
129774 +
129775 + int i, numfrags;
129776 +
129777 +
129778 + frag = list_entry(mem_list.next, struct mem_fragment, list);
129779 +
129780 + while (&frag->list != &mem_list) {
129781 + /* Must combine consecutive fragemenst with
129782 + same root_pfn such that they are power of 4 */
129783 + if (frag->refs != 0) {
129784 + frag = list_entry(frag->list.next,
129785 + struct mem_fragment, list);
129786 + continue; /* Not this window */
129787 + }
129788 + len = frag->len;
129789 + numfrags = 0;
129790 + nxtfrag = list_entry(frag->list.next,
129791 + struct mem_fragment, list);
129792 + while (true) {
129793 + if (&nxtfrag->list == &mem_list) {
129794 + numfrags = 0;
129795 + break; /* End of list */
129796 + }
129797 + if (nxtfrag->refs) {
129798 + numfrags = 0;
129799 + break; /* In use still */
129800 + }
129801 + if (nxtfrag->root_pfn != frag->root_pfn) {
129802 + numfrags = 0;
129803 + break; /* Crosses root fragment boundary */
129804 + }
129805 + len += nxtfrag->len;
129806 + numfrags++;
129807 + if (is_power_of_4(len)) {
129808 + /* These fragments can be combined */
129809 + break;
129810 + }
129811 + nxtfrag = list_entry(nxtfrag->list.next,
129812 + struct mem_fragment, list);
129813 + }
129814 + if (numfrags == 0) {
129815 + frag = list_entry(frag->list.next,
129816 + struct mem_fragment, list);
129817 + continue; /* try the next window */
129818 + }
129819 + for (i = 0; i < numfrags; i++) {
129820 + struct mem_fragment *todel =
129821 + list_entry(nxtfrag->list.prev,
129822 + struct mem_fragment, list);
129823 + nxtfrag->len += todel->len;
129824 + nxtfrag->pfn_len += todel->pfn_len;
129825 + list_del(&todel->list);
129826 + }
129827 + /* Re evaluate the list, things may merge now */
129828 + frag = list_entry(mem_list.next, struct mem_fragment, list);
129829 + }
129830 +}
129831 +
129832 +/* Hook from arch/powerpc/mm/mem.c */
129833 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size)
129834 +{
129835 + struct mem_fragment *frag;
129836 + int idx = -1;
129837 + if ((pfn < pfn_start) || (pfn >= (pfn_start + pfn_size)))
129838 + return -1;
129839 + /* It's in-range, we need to find the fragment */
129840 + spin_lock(&mem_lock);
129841 + list_for_each_entry(frag, &mem_list, list) {
129842 + if ((pfn >= frag->pfn_base) && (pfn < (frag->pfn_base +
129843 + frag->pfn_len))) {
129844 + *phys_addr = frag->base;
129845 + *size = frag->len;
129846 + idx = current_tlb++;
129847 + if (current_tlb >= (first_tlb + num_tlb))
129848 + current_tlb = first_tlb;
129849 + break;
129850 + }
129851 + }
129852 + spin_unlock(&mem_lock);
129853 + return idx;
129854 +}
129855 +
129856 +static int usdpaa_open(struct inode *inode, struct file *filp)
129857 +{
129858 + const struct alloc_backend *backend = &alloc_backends[0];
129859 + struct ctx *ctx = kmalloc(sizeof(struct ctx), GFP_KERNEL);
129860 + if (!ctx)
129861 + return -ENOMEM;
129862 + filp->private_data = ctx;
129863 +
129864 + while (backend->id_type != usdpaa_id_max) {
129865 + INIT_LIST_HEAD(&ctx->resources[backend->id_type]);
129866 + backend++;
129867 + }
129868 +
129869 + INIT_LIST_HEAD(&ctx->maps);
129870 + INIT_LIST_HEAD(&ctx->portals);
129871 + spin_lock_init(&ctx->lock);
129872 +
129873 + //filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi;
129874 +
129875 + return 0;
129876 +}
129877 +
129878 +#define DQRR_MAXFILL 15
129879 +
129880 +/* Reset a QMan portal to its default state */
129881 +static int init_qm_portal(struct qm_portal_config *config,
129882 + struct qm_portal *portal)
129883 +{
129884 + const struct qm_dqrr_entry *dqrr = NULL;
129885 + int i;
129886 +
129887 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
129888 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
129889 +
129890 + /* Make sure interrupts are inhibited */
129891 + qm_out(IIR, 1);
129892 +
129893 + /* Initialize the DQRR. This will stop any dequeue
129894 + commands that are in progress */
129895 + if (qm_dqrr_init(portal, config, qm_dqrr_dpush, qm_dqrr_pvb,
129896 + qm_dqrr_cdc, DQRR_MAXFILL)) {
129897 + pr_err("qm_dqrr_init() failed when trying to"
129898 + " recover portal, portal will be leaked\n");
129899 + return 1;
129900 + }
129901 +
129902 + /* Discard any entries on the DQRR */
129903 + /* If we consume the ring twice something is wrong */
129904 + for (i = 0; i < DQRR_MAXFILL * 2; i++) {
129905 + qm_dqrr_pvb_update(portal);
129906 + dqrr = qm_dqrr_current(portal);
129907 + if (!dqrr)
129908 + break;
129909 + qm_dqrr_cdc_consume_1ptr(portal, dqrr, 0);
129910 + qm_dqrr_pvb_update(portal);
129911 + qm_dqrr_next(portal);
129912 + }
129913 + /* Initialize the EQCR */
129914 + if (qm_eqcr_init(portal, qm_eqcr_pvb,
129915 + qm_eqcr_get_ci_stashing(portal), 1)) {
129916 + pr_err("Qman EQCR initialisation failed\n");
129917 + return 1;
129918 + }
129919 + /* initialize the MR */
129920 + if (qm_mr_init(portal, qm_mr_pvb, qm_mr_cci)) {
129921 + pr_err("Qman MR initialisation failed\n");
129922 + return 1;
129923 + }
129924 + qm_mr_pvb_update(portal);
129925 + while (qm_mr_current(portal)) {
129926 + qm_mr_next(portal);
129927 + qm_mr_cci_consume_to_current(portal);
129928 + qm_mr_pvb_update(portal);
129929 + }
129930 +
129931 + if (qm_mc_init(portal)) {
129932 + pr_err("Qman MC initialisation failed\n");
129933 + return 1;
129934 + }
129935 + return 0;
129936 +}
129937 +
129938 +static int init_bm_portal(struct bm_portal_config *config,
129939 + struct bm_portal *portal)
129940 +{
129941 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
129942 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
129943 +
129944 + if (bm_rcr_init(portal, bm_rcr_pvb, bm_rcr_cce)) {
129945 + pr_err("Bman RCR initialisation failed\n");
129946 + return 1;
129947 + }
129948 + if (bm_mc_init(portal)) {
129949 + pr_err("Bman MC initialisation failed\n");
129950 + return 1;
129951 + }
129952 + return 0;
129953 +}
129954 +
129955 +/* Function that will scan all FQ's in the system. For each FQ that is not
129956 + OOS it will call the check_channel helper to determine if the FQ should
129957 + be torn down. If the check_channel helper returns true the FQ will be
129958 + transitioned to the OOS state */
129959 +static int qm_check_and_destroy_fqs(struct qm_portal *portal, void *ctx,
129960 + bool (*check_channel)(void*, u32))
129961 +{
129962 + u32 fq_id = 0;
129963 + while (1) {
129964 + struct qm_mc_command *mcc;
129965 + struct qm_mc_result *mcr;
129966 + u8 state;
129967 + u32 channel;
129968 +
129969 + /* Determine the channel for the FQID */
129970 + mcc = qm_mc_start(portal);
129971 + mcc->queryfq.fqid = fq_id;
129972 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ);
129973 + while (!(mcr = qm_mc_result(portal)))
129974 + cpu_relax();
129975 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
129976 + == QM_MCR_VERB_QUERYFQ);
129977 + if (mcr->result != QM_MCR_RESULT_OK)
129978 + break; /* End of valid FQIDs */
129979 +
129980 + channel = mcr->queryfq.fqd.dest.channel;
129981 + /* Determine the state of the FQID */
129982 + mcc = qm_mc_start(portal);
129983 + mcc->queryfq_np.fqid = fq_id;
129984 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ_NP);
129985 + while (!(mcr = qm_mc_result(portal)))
129986 + cpu_relax();
129987 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
129988 + == QM_MCR_VERB_QUERYFQ_NP);
129989 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
129990 + if (state == QM_MCR_NP_STATE_OOS)
129991 + /* Already OOS, no need to do anymore checks */
129992 + goto next;
129993 +
129994 + if (check_channel(ctx, channel))
129995 + qm_shutdown_fq(&portal, 1, fq_id);
129996 + next:
129997 + ++fq_id;
129998 + }
129999 + return 0;
130000 +}
130001 +
130002 +static bool check_channel_device(void *_ctx, u32 channel)
130003 +{
130004 + struct ctx *ctx = _ctx;
130005 + struct portal_mapping *portal, *tmpportal;
130006 + struct active_resource *res;
130007 +
130008 + /* See if the FQ is destined for one of the portals we're cleaning up */
130009 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130010 + if (portal->user.type == usdpaa_portal_qman) {
130011 + if (portal->qportal->public_cfg.channel == channel) {
130012 + /* This FQs destination is a portal
130013 + we're cleaning, send a retire */
130014 + return true;
130015 + }
130016 + }
130017 + }
130018 +
130019 + /* Check the pool channels that will be released as well */
130020 + list_for_each_entry(res, &ctx->resources[usdpaa_id_qpool], list) {
130021 + if ((res->id >= channel) &&
130022 + ((res->id + res->num - 1) <= channel))
130023 + return true;
130024 + }
130025 + return false;
130026 +}
130027 +
130028 +static bool check_portal_channel(void *ctx, u32 channel)
130029 +{
130030 + u32 portal_channel = *(u32 *)ctx;
130031 + if (portal_channel == channel) {
130032 + /* This FQs destination is a portal
130033 + we're cleaning, send a retire */
130034 + return true;
130035 + }
130036 + return false;
130037 +}
130038 +
130039 +
130040 +
130041 +
130042 +static int usdpaa_release(struct inode *inode, struct file *filp)
130043 +{
130044 + struct ctx *ctx = filp->private_data;
130045 + struct mem_mapping *map, *tmpmap;
130046 + struct portal_mapping *portal, *tmpportal;
130047 + const struct alloc_backend *backend = &alloc_backends[0];
130048 + struct active_resource *res;
130049 + struct qm_portal *qm_cleanup_portal = NULL;
130050 + struct bm_portal *bm_cleanup_portal = NULL;
130051 + struct qm_portal_config *qm_alloced_portal = NULL;
130052 + struct bm_portal_config *bm_alloced_portal = NULL;
130053 +
130054 + struct qm_portal *portal_array[qman_portal_max];
130055 + int portal_count = 0;
130056 +
130057 + /* Ensure the release operation cannot be migrated to another
130058 + CPU as CPU specific variables may be needed during cleanup */
130059 +#ifdef CONFIG_PREEMPT_RT_FULL
130060 + migrate_disable();
130061 +#endif
130062 + /* The following logic is used to recover resources that were not
130063 + correctly released by the process that is closing the FD.
130064 + Step 1: syncronize the HW with the qm_portal/bm_portal structures
130065 + in the kernel
130066 + */
130067 +
130068 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130069 + /* Try to recover any portals that weren't shut down */
130070 + if (portal->user.type == usdpaa_portal_qman) {
130071 + portal_array[portal_count] = &portal->qman_portal_low;
130072 + ++portal_count;
130073 + init_qm_portal(portal->qportal,
130074 + &portal->qman_portal_low);
130075 + if (!qm_cleanup_portal) {
130076 + qm_cleanup_portal = &portal->qman_portal_low;
130077 + } else {
130078 + /* Clean FQs on the dedicated channel */
130079 + u32 chan = portal->qportal->public_cfg.channel;
130080 + qm_check_and_destroy_fqs(
130081 + &portal->qman_portal_low, &chan,
130082 + check_portal_channel);
130083 + }
130084 + } else {
130085 + /* BMAN */
130086 + init_bm_portal(portal->bportal,
130087 + &portal->bman_portal_low);
130088 + if (!bm_cleanup_portal)
130089 + bm_cleanup_portal = &portal->bman_portal_low;
130090 + }
130091 + }
130092 + /* If no portal was found, allocate one for cleanup */
130093 + if (!qm_cleanup_portal) {
130094 + qm_alloced_portal = qm_get_unused_portal();
130095 + if (!qm_alloced_portal) {
130096 + pr_crit("No QMan portal avalaible for cleanup\n");
130097 +#ifdef CONFIG_PREEMPT_RT_FULL
130098 + migrate_enable();
130099 +#endif
130100 + return -1;
130101 + }
130102 + qm_cleanup_portal = kmalloc(sizeof(struct qm_portal),
130103 + GFP_KERNEL);
130104 + if (!qm_cleanup_portal) {
130105 +#ifdef CONFIG_PREEMPT_RT_FULL
130106 + migrate_enable();
130107 +#endif
130108 + return -ENOMEM;
130109 + }
130110 + init_qm_portal(qm_alloced_portal, qm_cleanup_portal);
130111 + portal_array[portal_count] = qm_cleanup_portal;
130112 + ++portal_count;
130113 + }
130114 + if (!bm_cleanup_portal) {
130115 + bm_alloced_portal = bm_get_unused_portal();
130116 + if (!bm_alloced_portal) {
130117 + pr_crit("No BMan portal avalaible for cleanup\n");
130118 +#ifdef CONFIG_PREEMPT_RT_FULL
130119 + migrate_enable();
130120 +#endif
130121 + return -1;
130122 + }
130123 + bm_cleanup_portal = kmalloc(sizeof(struct bm_portal),
130124 + GFP_KERNEL);
130125 + if (!bm_cleanup_portal) {
130126 +#ifdef CONFIG_PREEMPT_RT_FULL
130127 + migrate_enable();
130128 +#endif
130129 + return -ENOMEM;
130130 + }
130131 + init_bm_portal(bm_alloced_portal, bm_cleanup_portal);
130132 + }
130133 +
130134 + /* OOS the FQs associated with this process */
130135 + qm_check_and_destroy_fqs(qm_cleanup_portal, ctx, check_channel_device);
130136 +
130137 + while (backend->id_type != usdpaa_id_max) {
130138 + int leaks = 0;
130139 + list_for_each_entry(res, &ctx->resources[backend->id_type],
130140 + list) {
130141 + if (backend->id_type == usdpaa_id_fqid) {
130142 + int i = 0;
130143 + for (; i < res->num; i++) {
130144 + /* Clean FQs with the cleanup portal */
130145 + qm_shutdown_fq(portal_array,
130146 + portal_count,
130147 + res->id + i);
130148 + }
130149 + }
130150 + leaks += res->num;
130151 + backend->release(res->id, res->num);
130152 + }
130153 + if (leaks)
130154 + pr_crit("USDPAA process leaking %d %s%s\n", leaks,
130155 + backend->acronym, (leaks > 1) ? "s" : "");
130156 + backend++;
130157 + }
130158 + /* Release any DMA regions */
130159 + spin_lock(&mem_lock);
130160 + list_for_each_entry_safe(map, tmpmap, &ctx->maps, list) {
130161 + struct mem_fragment *current_frag = map->root_frag;
130162 + int i;
130163 + if (map->root_frag->has_locking &&
130164 + (map->root_frag->owner == map)) {
130165 + map->root_frag->owner = NULL;
130166 + wake_up(&map->root_frag->wq);
130167 + }
130168 + /* Check each fragment and merge if the ref count is 0 */
130169 + for (i = 0; i < map->frag_count; i++) {
130170 + --current_frag->refs;
130171 + current_frag = list_entry(current_frag->list.prev,
130172 + struct mem_fragment, list);
130173 + }
130174 +
130175 + compress_frags();
130176 + list_del(&map->list);
130177 + kfree(map);
130178 + }
130179 + spin_unlock(&mem_lock);
130180 +
130181 + /* Return portals */
130182 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130183 + if (portal->user.type == usdpaa_portal_qman) {
130184 + /* Give the portal back to the allocator */
130185 + init_qm_portal(portal->qportal,
130186 + &portal->qman_portal_low);
130187 + qm_put_unused_portal(portal->qportal);
130188 + } else {
130189 + init_bm_portal(portal->bportal,
130190 + &portal->bman_portal_low);
130191 + bm_put_unused_portal(portal->bportal);
130192 + }
130193 + list_del(&portal->list);
130194 + kfree(portal);
130195 + }
130196 + if (qm_alloced_portal) {
130197 + qm_put_unused_portal(qm_alloced_portal);
130198 + kfree(qm_cleanup_portal);
130199 + }
130200 + if (bm_alloced_portal) {
130201 + bm_put_unused_portal(bm_alloced_portal);
130202 + kfree(bm_cleanup_portal);
130203 + }
130204 +
130205 + kfree(ctx);
130206 +#ifdef CONFIG_PREEMPT_RT_FULL
130207 + migrate_enable();
130208 +#endif
130209 + return 0;
130210 +}
130211 +
130212 +static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma,
130213 + int *match, unsigned long *pfn)
130214 +{
130215 + struct mem_mapping *map;
130216 +
130217 + list_for_each_entry(map, &ctx->maps, list) {
130218 + int i;
130219 + struct mem_fragment *frag = map->root_frag;
130220 +
130221 + for (i = 0; i < map->frag_count; i++) {
130222 + if (frag->pfn_base == vma->vm_pgoff) {
130223 + *match = 1;
130224 + *pfn = frag->pfn_base;
130225 + return 0;
130226 + }
130227 + frag = list_entry(frag->list.next, struct mem_fragment,
130228 + list);
130229 + }
130230 + }
130231 + *match = 0;
130232 + return 0;
130233 +}
130234 +
130235 +static int check_mmap_resource(struct resource *res, struct vm_area_struct *vma,
130236 + int *match, unsigned long *pfn)
130237 +{
130238 + *pfn = res->start >> PAGE_SHIFT;
130239 + if (*pfn == vma->vm_pgoff) {
130240 + *match = 1;
130241 + if ((vma->vm_end - vma->vm_start) != resource_size(res))
130242 + return -EINVAL;
130243 + } else
130244 + *match = 0;
130245 + return 0;
130246 +}
130247 +
130248 +static int check_mmap_portal(struct ctx *ctx, struct vm_area_struct *vma,
130249 + int *match, unsigned long *pfn)
130250 +{
130251 + struct portal_mapping *portal;
130252 + int ret;
130253 +
130254 + list_for_each_entry(portal, &ctx->portals, list) {
130255 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CE], vma,
130256 + match, pfn);
130257 + if (*match) {
130258 + vma->vm_page_prot =
130259 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
130260 + pgprot_cached_ns(vma->vm_page_prot);
130261 +#else
130262 + pgprot_cached_noncoherent(vma->vm_page_prot);
130263 +#endif
130264 + return ret;
130265 + }
130266 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CI], vma,
130267 + match, pfn);
130268 + if (*match) {
130269 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
130270 + return ret;
130271 + }
130272 + }
130273 + *match = 0;
130274 + return 0;
130275 +}
130276 +
130277 +static int usdpaa_mmap(struct file *filp, struct vm_area_struct *vma)
130278 +{
130279 + struct ctx *ctx = filp->private_data;
130280 + unsigned long pfn = 0;
130281 + int match, ret;
130282 +
130283 + spin_lock(&mem_lock);
130284 + ret = check_mmap_dma(ctx, vma, &match, &pfn);
130285 + if (!match)
130286 + ret = check_mmap_portal(ctx, vma, &match, &pfn);
130287 + spin_unlock(&mem_lock);
130288 + if (!match)
130289 + return -EINVAL;
130290 + if (!ret)
130291 + ret = remap_pfn_range(vma, vma->vm_start, pfn,
130292 + vma->vm_end - vma->vm_start,
130293 + vma->vm_page_prot);
130294 + return ret;
130295 +}
130296 +
130297 +/* Return the nearest rounded-up address >= 'addr' that is 'sz'-aligned. 'sz'
130298 + * must be a power of 2, but both 'addr' and 'sz' can be expressions. */
130299 +#define USDPAA_MEM_ROUNDUP(addr, sz) \
130300 + ({ \
130301 + unsigned long foo_align = (sz) - 1; \
130302 + ((addr) + foo_align) & ~foo_align; \
130303 + })
130304 +/* Searching for a size-aligned virtual address range starting from 'addr' */
130305 +static unsigned long usdpaa_get_unmapped_area(struct file *file,
130306 + unsigned long addr,
130307 + unsigned long len,
130308 + unsigned long pgoff,
130309 + unsigned long flags)
130310 +{
130311 + struct vm_area_struct *vma;
130312 +
130313 + if (len % PAGE_SIZE)
130314 + return -EINVAL;
130315 + if (!len)
130316 + return -EINVAL;
130317 +
130318 + /* Need to align the address to the largest pagesize of the mapping
130319 + * because the MMU requires the virtual address to have the same
130320 + * alignment as the physical address */
130321 + addr = USDPAA_MEM_ROUNDUP(addr, largest_page_size(len));
130322 + vma = find_vma(current->mm, addr);
130323 + /* Keep searching until we reach the end of currently-used virtual
130324 + * address-space or we find a big enough gap. */
130325 + while (vma) {
130326 + if ((addr + len) < vma->vm_start)
130327 + return addr;
130328 +
130329 + addr = USDPAA_MEM_ROUNDUP(vma->vm_end, largest_page_size(len));
130330 + vma = vma->vm_next;
130331 + }
130332 + if ((TASK_SIZE - len) < addr)
130333 + return -ENOMEM;
130334 + return addr;
130335 +}
130336 +
130337 +static long ioctl_id_alloc(struct ctx *ctx, void __user *arg)
130338 +{
130339 + struct usdpaa_ioctl_id_alloc i;
130340 + const struct alloc_backend *backend;
130341 + struct active_resource *res;
130342 + int ret = copy_from_user(&i, arg, sizeof(i));
130343 + if (ret)
130344 + return ret;
130345 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130346 + return -EINVAL;
130347 + backend = &alloc_backends[i.id_type];
130348 + /* Allocate the required resource type */
130349 + ret = backend->alloc(&i.base, i.num, i.align, i.partial);
130350 + if (ret < 0)
130351 + return ret;
130352 + i.num = ret;
130353 + /* Copy the result to user-space */
130354 + ret = copy_to_user(arg, &i, sizeof(i));
130355 + if (ret) {
130356 + backend->release(i.base, i.num);
130357 + return ret;
130358 + }
130359 + /* Assign the allocated range to the FD accounting */
130360 + res = kmalloc(sizeof(*res), GFP_KERNEL);
130361 + if (!res) {
130362 + backend->release(i.base, i.num);
130363 + return -ENOMEM;
130364 + }
130365 + spin_lock(&ctx->lock);
130366 + res->id = i.base;
130367 + res->num = i.num;
130368 + res->refcount = 1;
130369 + list_add(&res->list, &ctx->resources[i.id_type]);
130370 + spin_unlock(&ctx->lock);
130371 + return 0;
130372 +}
130373 +
130374 +static long ioctl_id_release(struct ctx *ctx, void __user *arg)
130375 +{
130376 + struct usdpaa_ioctl_id_release i;
130377 + const struct alloc_backend *backend;
130378 + struct active_resource *tmp, *pos;
130379 +
130380 + int ret = copy_from_user(&i, arg, sizeof(i));
130381 + if (ret)
130382 + return ret;
130383 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130384 + return -EINVAL;
130385 + backend = &alloc_backends[i.id_type];
130386 + /* Pull the range out of the FD accounting - the range is valid iff this
130387 + * succeeds. */
130388 + spin_lock(&ctx->lock);
130389 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
130390 + if (pos->id == i.base && pos->num == i.num) {
130391 + pos->refcount--;
130392 + if (pos->refcount) {
130393 + spin_unlock(&ctx->lock);
130394 + return 0; /* Still being used */
130395 + }
130396 + list_del(&pos->list);
130397 + kfree(pos);
130398 + spin_unlock(&ctx->lock);
130399 + goto found;
130400 + }
130401 + }
130402 + /* Failed to find the resource */
130403 + spin_unlock(&ctx->lock);
130404 + pr_err("Couldn't find resource type %d base 0x%x num %d\n",
130405 + i.id_type, i.base, i.num);
130406 + return -EINVAL;
130407 +found:
130408 + /* Release the resource to the backend */
130409 + backend->release(i.base, i.num);
130410 + return 0;
130411 +}
130412 +
130413 +static long ioctl_id_reserve(struct ctx *ctx, void __user *arg)
130414 +{
130415 + struct usdpaa_ioctl_id_reserve i;
130416 + const struct alloc_backend *backend;
130417 + struct active_resource *tmp, *pos;
130418 +
130419 + int ret = copy_from_user(&i, arg, sizeof(i));
130420 + if (ret)
130421 + return ret;
130422 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130423 + return -EINVAL;
130424 + backend = &alloc_backends[i.id_type];
130425 + if (!backend->reserve)
130426 + return -EINVAL;
130427 + /* Pull the range out of the FD accounting - the range is valid iff this
130428 + * succeeds. */
130429 + spin_lock(&ctx->lock);
130430 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
130431 + if (pos->id == i.base && pos->num == i.num) {
130432 + pos->refcount++;
130433 + spin_unlock(&ctx->lock);
130434 + return 0;
130435 + }
130436 + }
130437 +
130438 + /* Failed to find the resource */
130439 + spin_unlock(&ctx->lock);
130440 +
130441 + /* Reserve the resource in the backend */
130442 + ret = backend->reserve(i.base, i.num);
130443 + if (ret)
130444 + return ret;
130445 + /* Assign the reserved range to the FD accounting */
130446 + pos = kmalloc(sizeof(*pos), GFP_KERNEL);
130447 + if (!pos) {
130448 + backend->release(i.base, i.num);
130449 + return -ENOMEM;
130450 + }
130451 + spin_lock(&ctx->lock);
130452 + pos->id = i.base;
130453 + pos->num = i.num;
130454 + pos->refcount = 1;
130455 + list_add(&pos->list, &ctx->resources[i.id_type]);
130456 + spin_unlock(&ctx->lock);
130457 + return 0;
130458 +}
130459 +
130460 +static long ioctl_dma_map(struct file *fp, struct ctx *ctx,
130461 + struct usdpaa_ioctl_dma_map *i)
130462 +{
130463 + struct mem_fragment *frag, *start_frag, *next_frag;
130464 + struct mem_mapping *map, *tmp;
130465 + int ret = 0;
130466 + u32 largest_page, so_far = 0;
130467 + int frag_count = 0;
130468 + unsigned long next_addr = PAGE_SIZE, populate;
130469 +
130470 + /* error checking to ensure values copied from user space are valid */
130471 + if (i->len % PAGE_SIZE)
130472 + return -EINVAL;
130473 +
130474 + map = kmalloc(sizeof(*map), GFP_KERNEL);
130475 + if (!map)
130476 + return -ENOMEM;
130477 +
130478 + spin_lock(&mem_lock);
130479 + if (i->flags & USDPAA_DMA_FLAG_SHARE) {
130480 + list_for_each_entry(frag, &mem_list, list) {
130481 + if (frag->refs && (frag->flags &
130482 + USDPAA_DMA_FLAG_SHARE) &&
130483 + !strncmp(i->name, frag->name,
130484 + USDPAA_DMA_NAME_MAX)) {
130485 + /* Matching entry */
130486 + if ((i->flags & USDPAA_DMA_FLAG_CREATE) &&
130487 + !(i->flags & USDPAA_DMA_FLAG_LAZY)) {
130488 + ret = -EBUSY;
130489 + goto out;
130490 + }
130491 +
130492 + /* Check to ensure size matches record */
130493 + if (i->len != frag->map_len && i->len) {
130494 + pr_err("ioctl_dma_map() Size requested does not match %s and is none zero\n",
130495 + frag->name);
130496 + return -EINVAL;
130497 + }
130498 +
130499 + /* Check if this has already been mapped
130500 + to this process */
130501 + list_for_each_entry(tmp, &ctx->maps, list)
130502 + if (tmp->root_frag == frag) {
130503 + /* Already mapped, just need to
130504 + inc ref count */
130505 + tmp->refs++;
130506 + kfree(map);
130507 + i->did_create = 0;
130508 + i->len = tmp->total_size;
130509 + i->phys_addr = frag->base;
130510 + i->ptr = tmp->virt_addr;
130511 + spin_unlock(&mem_lock);
130512 + return 0;
130513 + }
130514 + /* Matching entry - just need to map */
130515 + i->has_locking = frag->has_locking;
130516 + i->did_create = 0;
130517 + i->len = frag->map_len;
130518 + start_frag = frag;
130519 + goto do_map;
130520 + }
130521 + }
130522 + /* No matching entry */
130523 + if (!(i->flags & USDPAA_DMA_FLAG_CREATE)) {
130524 + pr_err("ioctl_dma_map() No matching entry\n");
130525 + ret = -ENOMEM;
130526 + goto out;
130527 + }
130528 + }
130529 + /* New fragment required, size must be provided. */
130530 + if (!i->len) {
130531 + ret = -EINVAL;
130532 + goto out;
130533 + }
130534 +
130535 + /* Find one of more contiguous fragments that satisfy the total length
130536 + trying to minimize the number of fragments
130537 + compute the largest page size that the allocation could use */
130538 + largest_page = largest_page_size(i->len);
130539 + start_frag = NULL;
130540 + while (largest_page &&
130541 + largest_page <= largest_page_size(phys_size) &&
130542 + start_frag == NULL) {
130543 + /* Search the list for a frag of that size */
130544 + list_for_each_entry(frag, &mem_list, list) {
130545 + if (!frag->refs && (frag->len == largest_page)) {
130546 + /* See if the next x fragments are free
130547 + and can accomidate the size */
130548 + u32 found_size = largest_page;
130549 + next_frag = list_entry(frag->list.prev,
130550 + struct mem_fragment,
130551 + list);
130552 + /* If the fragement is too small check
130553 + if the neighbours cab support it */
130554 + while (found_size < i->len) {
130555 + if (&mem_list == &next_frag->list)
130556 + break; /* End of list */
130557 + if (next_frag->refs != 0 ||
130558 + next_frag->len == 0)
130559 + break; /* not enough space */
130560 + found_size += next_frag->len;
130561 + next_frag = list_entry(
130562 + next_frag->list.prev,
130563 + struct mem_fragment,
130564 + list);
130565 + }
130566 + if (found_size >= i->len) {
130567 + /* Success! there is enough contigous
130568 + free space */
130569 + start_frag = frag;
130570 + break;
130571 + }
130572 + }
130573 + } /* next frag loop */
130574 + /* Couldn't statisfy the request with this
130575 + largest page size, try a smaller one */
130576 + largest_page <<= 2;
130577 + }
130578 + if (start_frag == NULL) {
130579 + /* Couldn't find proper amount of space */
130580 + ret = -ENOMEM;
130581 + goto out;
130582 + }
130583 + i->did_create = 1;
130584 +do_map:
130585 + /* Verify there is sufficient space to do the mapping */
130586 + down_write(&current->mm->mmap_sem);
130587 + next_addr = usdpaa_get_unmapped_area(fp, next_addr, i->len, 0, 0);
130588 + up_write(&current->mm->mmap_sem);
130589 +
130590 + if (next_addr & ~PAGE_MASK) {
130591 + ret = -ENOMEM;
130592 + goto out;
130593 + }
130594 +
130595 + /* We may need to divide the final fragment to accomidate the mapping */
130596 + next_frag = start_frag;
130597 + while (so_far != i->len) {
130598 + BUG_ON(next_frag->len == 0);
130599 + while ((next_frag->len + so_far) > i->len) {
130600 + /* Split frag until they match */
130601 + split_frag(next_frag);
130602 + }
130603 + so_far += next_frag->len;
130604 + next_frag->refs++;
130605 + ++frag_count;
130606 + next_frag = list_entry(next_frag->list.prev,
130607 + struct mem_fragment, list);
130608 + }
130609 + if (i->did_create) {
130610 + size_t name_len = 0;
130611 + start_frag->flags = i->flags;
130612 + strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX);
130613 + name_len = strnlen(start_frag->name, USDPAA_DMA_NAME_MAX);
130614 + if (name_len >= USDPAA_DMA_NAME_MAX) {
130615 + ret = -EFAULT;
130616 + goto out;
130617 + }
130618 + start_frag->map_len = i->len;
130619 + start_frag->has_locking = i->has_locking;
130620 + init_waitqueue_head(&start_frag->wq);
130621 + start_frag->owner = NULL;
130622 + }
130623 +
130624 + /* Setup the map entry */
130625 + map->root_frag = start_frag;
130626 + map->total_size = i->len;
130627 + map->frag_count = frag_count;
130628 + map->refs = 1;
130629 + list_add(&map->list, &ctx->maps);
130630 + i->phys_addr = start_frag->base;
130631 +out:
130632 + spin_unlock(&mem_lock);
130633 +
130634 + if (!ret) {
130635 + unsigned long longret;
130636 + down_write(&current->mm->mmap_sem);
130637 + longret = do_mmap_pgoff(fp, next_addr, map->total_size,
130638 + PROT_READ |
130639 + (i->flags &
130640 + USDPAA_DMA_FLAG_RDONLY ? 0
130641 + : PROT_WRITE),
130642 + MAP_SHARED,
130643 + start_frag->pfn_base,
130644 + &populate);
130645 + up_write(&current->mm->mmap_sem);
130646 + if (longret & ~PAGE_MASK) {
130647 + ret = (int)longret;
130648 + } else {
130649 + i->ptr = (void *)longret;
130650 + map->virt_addr = i->ptr;
130651 + }
130652 + } else
130653 + kfree(map);
130654 + return ret;
130655 +}
130656 +
130657 +static long ioctl_dma_unmap(struct ctx *ctx, void __user *arg)
130658 +{
130659 + struct mem_mapping *map;
130660 + struct vm_area_struct *vma;
130661 + int ret, i;
130662 + struct mem_fragment *current_frag;
130663 + size_t sz;
130664 + unsigned long base;
130665 + unsigned long vaddr;
130666 +
130667 + down_write(&current->mm->mmap_sem);
130668 + vma = find_vma(current->mm, (unsigned long)arg);
130669 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
130670 + up_write(&current->mm->mmap_sem);
130671 + return -EFAULT;
130672 + }
130673 + spin_lock(&mem_lock);
130674 + list_for_each_entry(map, &ctx->maps, list) {
130675 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
130676 + /* Drop the map lock if we hold it */
130677 + if (map->root_frag->has_locking &&
130678 + (map->root_frag->owner == map)) {
130679 + map->root_frag->owner = NULL;
130680 + wake_up(&map->root_frag->wq);
130681 + }
130682 + goto map_match;
130683 + }
130684 + }
130685 + /* Failed to find a matching mapping for this process */
130686 + ret = -EFAULT;
130687 + spin_unlock(&mem_lock);
130688 + goto out;
130689 +map_match:
130690 + map->refs--;
130691 + if (map->refs != 0) {
130692 + /* Another call the dma_map is referencing this */
130693 + ret = 0;
130694 + spin_unlock(&mem_lock);
130695 + goto out;
130696 + }
130697 +
130698 + current_frag = map->root_frag;
130699 + vaddr = (unsigned long) map->virt_addr;
130700 + for (i = 0; i < map->frag_count; i++) {
130701 + DPA_ASSERT(current_frag->refs > 0);
130702 + --current_frag->refs;
130703 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
130704 + /*
130705 + * Make sure we invalidate the TLB entry for
130706 + * this fragment, otherwise a remap of a different
130707 + * page to this vaddr would give acces to an
130708 + * incorrect piece of memory
130709 + */
130710 + cleartlbcam(vaddr, mfspr(SPRN_PID));
130711 +#endif
130712 + vaddr += current_frag->len;
130713 + current_frag = list_entry(current_frag->list.prev,
130714 + struct mem_fragment, list);
130715 + }
130716 + map->root_frag->name[0] = 0;
130717 + list_del(&map->list);
130718 + compress_frags();
130719 + spin_unlock(&mem_lock);
130720 +
130721 + base = vma->vm_start;
130722 + sz = vma->vm_end - vma->vm_start;
130723 + do_munmap(current->mm, base, sz);
130724 + ret = 0;
130725 + out:
130726 + up_write(&current->mm->mmap_sem);
130727 + return ret;
130728 +}
130729 +
130730 +static long ioctl_dma_stats(struct ctx *ctx, void __user *arg)
130731 +{
130732 + struct mem_fragment *frag;
130733 + struct usdpaa_ioctl_dma_used result;
130734 +
130735 + result.free_bytes = 0;
130736 + result.total_bytes = phys_size;
130737 +
130738 + list_for_each_entry(frag, &mem_list, list) {
130739 + if (frag->refs == 0)
130740 + result.free_bytes += frag->len;
130741 + }
130742 +
130743 + return copy_to_user(arg, &result, sizeof(result)); }
130744 +
130745 +static int test_lock(struct mem_mapping *map)
130746 +{
130747 + int ret = 0;
130748 + spin_lock(&mem_lock);
130749 + if (!map->root_frag->owner) {
130750 + map->root_frag->owner = map;
130751 + ret = 1;
130752 + }
130753 + spin_unlock(&mem_lock);
130754 + return ret;
130755 +}
130756 +
130757 +static long ioctl_dma_lock(struct ctx *ctx, void __user *arg)
130758 +{
130759 + struct mem_mapping *map;
130760 + struct vm_area_struct *vma;
130761 +
130762 + down_read(&current->mm->mmap_sem);
130763 + vma = find_vma(current->mm, (unsigned long)arg);
130764 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
130765 + up_read(&current->mm->mmap_sem);
130766 + return -EFAULT;
130767 + }
130768 + spin_lock(&mem_lock);
130769 + list_for_each_entry(map, &ctx->maps, list) {
130770 + if (map->root_frag->pfn_base == vma->vm_pgoff)
130771 + goto map_match;
130772 + }
130773 + map = NULL;
130774 +map_match:
130775 + spin_unlock(&mem_lock);
130776 + up_read(&current->mm->mmap_sem);
130777 +
130778 + if (!map)
130779 + return -EFAULT;
130780 + if (!map->root_frag->has_locking)
130781 + return -ENODEV;
130782 + return wait_event_interruptible(map->root_frag->wq, test_lock(map));
130783 +}
130784 +
130785 +static long ioctl_dma_unlock(struct ctx *ctx, void __user *arg)
130786 +{
130787 + struct mem_mapping *map;
130788 + struct vm_area_struct *vma;
130789 + int ret;
130790 +
130791 + down_read(&current->mm->mmap_sem);
130792 + vma = find_vma(current->mm, (unsigned long)arg);
130793 + if (!vma || (vma->vm_start > (unsigned long)arg))
130794 + ret = -EFAULT;
130795 + else {
130796 + spin_lock(&mem_lock);
130797 + list_for_each_entry(map, &ctx->maps, list) {
130798 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
130799 + if (!map->root_frag->has_locking)
130800 + ret = -ENODEV;
130801 + else if (map->root_frag->owner == map) {
130802 + map->root_frag->owner = NULL;
130803 + wake_up(&map->root_frag->wq);
130804 + ret = 0;
130805 + } else
130806 + ret = -EBUSY;
130807 + goto map_match;
130808 + }
130809 + }
130810 + ret = -EINVAL;
130811 +map_match:
130812 + spin_unlock(&mem_lock);
130813 + }
130814 + up_read(&current->mm->mmap_sem);
130815 + return ret;
130816 +}
130817 +
130818 +static int portal_mmap(struct file *fp, struct resource *res, void **ptr)
130819 +{
130820 + unsigned long longret = 0, populate;
130821 + resource_size_t len;
130822 +
130823 + down_write(&current->mm->mmap_sem);
130824 + len = resource_size(res);
130825 + if (len != (unsigned long)len)
130826 + return -EINVAL;
130827 + longret = do_mmap_pgoff(fp, PAGE_SIZE, (unsigned long)len,
130828 + PROT_READ | PROT_WRITE, MAP_SHARED,
130829 + res->start >> PAGE_SHIFT, &populate);
130830 + up_write(&current->mm->mmap_sem);
130831 +
130832 + if (longret & ~PAGE_MASK)
130833 + return (int)longret;
130834 +
130835 + *ptr = (void *) longret;
130836 + return 0;
130837 +}
130838 +
130839 +static void portal_munmap(struct resource *res, void *ptr)
130840 +{
130841 + down_write(&current->mm->mmap_sem);
130842 + do_munmap(current->mm, (unsigned long)ptr, resource_size(res));
130843 + up_write(&current->mm->mmap_sem);
130844 +}
130845 +
130846 +static long ioctl_portal_map(struct file *fp, struct ctx *ctx,
130847 + struct usdpaa_ioctl_portal_map *arg)
130848 +{
130849 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
130850 + int ret;
130851 +
130852 + if (!mapping)
130853 + return -ENOMEM;
130854 +
130855 + mapping->user = *arg;
130856 + mapping->iommu_domain = NULL;
130857 +
130858 + if (mapping->user.type == usdpaa_portal_qman) {
130859 + mapping->qportal =
130860 + qm_get_unused_portal_idx(mapping->user.index);
130861 + if (!mapping->qportal) {
130862 + ret = -ENODEV;
130863 + goto err_get_portal;
130864 + }
130865 + mapping->phys = &mapping->qportal->addr_phys[0];
130866 + mapping->user.channel = mapping->qportal->public_cfg.channel;
130867 + mapping->user.pools = mapping->qportal->public_cfg.pools;
130868 + mapping->user.index = mapping->qportal->public_cfg.index;
130869 + } else if (mapping->user.type == usdpaa_portal_bman) {
130870 + mapping->bportal =
130871 + bm_get_unused_portal_idx(mapping->user.index);
130872 + if (!mapping->bportal) {
130873 + ret = -ENODEV;
130874 + goto err_get_portal;
130875 + }
130876 + mapping->phys = &mapping->bportal->addr_phys[0];
130877 + mapping->user.index = mapping->bportal->public_cfg.index;
130878 + } else {
130879 + ret = -EINVAL;
130880 + goto err_copy_from_user;
130881 + }
130882 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
130883 + * handlers look it up. */
130884 + spin_lock(&mem_lock);
130885 + list_add(&mapping->list, &ctx->portals);
130886 + spin_unlock(&mem_lock);
130887 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CE],
130888 + &mapping->user.addr.cena);
130889 + if (ret)
130890 + goto err_mmap_cena;
130891 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CI],
130892 + &mapping->user.addr.cinh);
130893 + if (ret)
130894 + goto err_mmap_cinh;
130895 + *arg = mapping->user;
130896 + return ret;
130897 +
130898 +err_mmap_cinh:
130899 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
130900 +err_mmap_cena:
130901 + if ((mapping->user.type == usdpaa_portal_qman) && mapping->qportal)
130902 + qm_put_unused_portal(mapping->qportal);
130903 + else if ((mapping->user.type == usdpaa_portal_bman) && mapping->bportal)
130904 + bm_put_unused_portal(mapping->bportal);
130905 + spin_lock(&mem_lock);
130906 + list_del(&mapping->list);
130907 + spin_unlock(&mem_lock);
130908 +err_get_portal:
130909 +err_copy_from_user:
130910 + kfree(mapping);
130911 + return ret;
130912 +}
130913 +
130914 +static long ioctl_portal_unmap(struct ctx *ctx, struct usdpaa_portal_map *i)
130915 +{
130916 + struct portal_mapping *mapping;
130917 + struct vm_area_struct *vma;
130918 + unsigned long pfn;
130919 + u32 channel;
130920 +
130921 + /* Get the PFN corresponding to one of the virt addresses */
130922 + down_read(&current->mm->mmap_sem);
130923 + vma = find_vma(current->mm, (unsigned long)i->cinh);
130924 + if (!vma || (vma->vm_start > (unsigned long)i->cinh)) {
130925 + up_read(&current->mm->mmap_sem);
130926 + return -EFAULT;
130927 + }
130928 + pfn = vma->vm_pgoff;
130929 + up_read(&current->mm->mmap_sem);
130930 +
130931 + /* Find the corresponding portal */
130932 + spin_lock(&mem_lock);
130933 + list_for_each_entry(mapping, &ctx->portals, list) {
130934 + if (pfn == (mapping->phys[DPA_PORTAL_CI].start >> PAGE_SHIFT))
130935 + goto found;
130936 + }
130937 + mapping = NULL;
130938 +found:
130939 + if (mapping)
130940 + list_del(&mapping->list);
130941 + spin_unlock(&mem_lock);
130942 + if (!mapping)
130943 + return -ENODEV;
130944 + portal_munmap(&mapping->phys[DPA_PORTAL_CI], mapping->user.addr.cinh);
130945 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
130946 + if (mapping->user.type == usdpaa_portal_qman) {
130947 + init_qm_portal(mapping->qportal,
130948 + &mapping->qman_portal_low);
130949 +
130950 + /* Tear down any FQs this portal is referencing */
130951 + channel = mapping->qportal->public_cfg.channel;
130952 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
130953 + &channel,
130954 + check_portal_channel);
130955 + qm_put_unused_portal(mapping->qportal);
130956 + } else if (mapping->user.type == usdpaa_portal_bman) {
130957 + init_bm_portal(mapping->bportal,
130958 + &mapping->bman_portal_low);
130959 + bm_put_unused_portal(mapping->bportal);
130960 + }
130961 + kfree(mapping);
130962 + return 0;
130963 +}
130964 +
130965 +static void portal_config_pamu(struct qm_portal_config *pcfg, uint8_t sdest,
130966 + uint32_t cpu, uint32_t cache, uint32_t window)
130967 +{
130968 +#ifdef CONFIG_FSL_PAMU
130969 + int ret;
130970 + int window_count = 1;
130971 + struct iommu_domain_geometry geom_attr;
130972 + struct pamu_stash_attribute stash_attr;
130973 +
130974 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
130975 + if (!pcfg->iommu_domain) {
130976 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
130977 + __func__);
130978 + goto _no_iommu;
130979 + }
130980 + geom_attr.aperture_start = 0;
130981 + geom_attr.aperture_end =
130982 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
130983 + geom_attr.force_aperture = true;
130984 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
130985 + &geom_attr);
130986 + if (ret < 0) {
130987 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
130988 + __func__, ret);
130989 + goto _iommu_domain_free;
130990 + }
130991 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
130992 + &window_count);
130993 + if (ret < 0) {
130994 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
130995 + __func__, ret);
130996 + goto _iommu_domain_free;
130997 + }
130998 + stash_attr.cpu = cpu;
130999 + stash_attr.cache = cache;
131000 + /* set stash information for the window */
131001 + stash_attr.window = 0;
131002 +
131003 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
131004 + DOMAIN_ATTR_FSL_PAMU_STASH,
131005 + &stash_attr);
131006 + if (ret < 0) {
131007 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131008 + __func__, ret);
131009 + goto _iommu_domain_free;
131010 + }
131011 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
131012 + IOMMU_READ | IOMMU_WRITE);
131013 + if (ret < 0) {
131014 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
131015 + __func__, ret);
131016 + goto _iommu_domain_free;
131017 + }
131018 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
131019 + if (ret < 0) {
131020 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
131021 + __func__, ret);
131022 + goto _iommu_domain_free;
131023 + }
131024 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
131025 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
131026 + &window_count);
131027 + if (ret < 0) {
131028 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131029 + __func__, ret);
131030 + goto _iommu_detach_device;
131031 + }
131032 +_no_iommu:
131033 +#endif
131034 +
131035 +#ifdef CONFIG_FSL_QMAN_CONFIG
131036 + if (qman_set_sdest(pcfg->public_cfg.channel, sdest))
131037 +#endif
131038 + pr_warn("Failed to set QMan portal's stash request queue\n");
131039 +
131040 + return;
131041 +
131042 +#ifdef CONFIG_FSL_PAMU
131043 +_iommu_detach_device:
131044 + iommu_detach_device(pcfg->iommu_domain, NULL);
131045 +_iommu_domain_free:
131046 + iommu_domain_free(pcfg->iommu_domain);
131047 +#endif
131048 +}
131049 +
131050 +static long ioctl_allocate_raw_portal(struct file *fp, struct ctx *ctx,
131051 + struct usdpaa_ioctl_raw_portal *arg)
131052 +{
131053 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
131054 + int ret;
131055 +
131056 + if (!mapping)
131057 + return -ENOMEM;
131058 +
131059 + mapping->user.type = arg->type;
131060 + mapping->iommu_domain = NULL;
131061 + if (arg->type == usdpaa_portal_qman) {
131062 + mapping->qportal = qm_get_unused_portal_idx(arg->index);
131063 + if (!mapping->qportal) {
131064 + ret = -ENODEV;
131065 + goto err;
131066 + }
131067 + mapping->phys = &mapping->qportal->addr_phys[0];
131068 + arg->index = mapping->qportal->public_cfg.index;
131069 + arg->cinh = mapping->qportal->addr_phys[DPA_PORTAL_CI].start;
131070 + arg->cena = mapping->qportal->addr_phys[DPA_PORTAL_CE].start;
131071 + if (arg->enable_stash) {
131072 + /* Setup the PAMU with the supplied parameters */
131073 + portal_config_pamu(mapping->qportal, arg->sdest,
131074 + arg->cpu, arg->cache, arg->window);
131075 + }
131076 + } else if (mapping->user.type == usdpaa_portal_bman) {
131077 + mapping->bportal =
131078 + bm_get_unused_portal_idx(arg->index);
131079 + if (!mapping->bportal) {
131080 + ret = -ENODEV;
131081 + goto err;
131082 + }
131083 + mapping->phys = &mapping->bportal->addr_phys[0];
131084 + arg->index = mapping->bportal->public_cfg.index;
131085 + arg->cinh = mapping->bportal->addr_phys[DPA_PORTAL_CI].start;
131086 + arg->cena = mapping->bportal->addr_phys[DPA_PORTAL_CE].start;
131087 + } else {
131088 + ret = -EINVAL;
131089 + goto err;
131090 + }
131091 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
131092 + * handlers look it up. */
131093 + spin_lock(&mem_lock);
131094 + list_add(&mapping->list, &ctx->portals);
131095 + spin_unlock(&mem_lock);
131096 + return 0;
131097 +err:
131098 + kfree(mapping);
131099 + return ret;
131100 +}
131101 +
131102 +static long ioctl_free_raw_portal(struct file *fp, struct ctx *ctx,
131103 + struct usdpaa_ioctl_raw_portal *arg)
131104 +{
131105 + struct portal_mapping *mapping;
131106 + u32 channel;
131107 +
131108 + /* Find the corresponding portal */
131109 + spin_lock(&mem_lock);
131110 + list_for_each_entry(mapping, &ctx->portals, list) {
131111 + if (mapping->phys[DPA_PORTAL_CI].start == arg->cinh)
131112 + goto found;
131113 + }
131114 + mapping = NULL;
131115 +found:
131116 + if (mapping)
131117 + list_del(&mapping->list);
131118 + spin_unlock(&mem_lock);
131119 + if (!mapping)
131120 + return -ENODEV;
131121 + if (mapping->user.type == usdpaa_portal_qman) {
131122 + init_qm_portal(mapping->qportal,
131123 + &mapping->qman_portal_low);
131124 +
131125 + /* Tear down any FQs this portal is referencing */
131126 + channel = mapping->qportal->public_cfg.channel;
131127 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
131128 + &channel,
131129 + check_portal_channel);
131130 + qm_put_unused_portal(mapping->qportal);
131131 + } else if (mapping->user.type == usdpaa_portal_bman) {
131132 + init_bm_portal(mapping->bportal,
131133 + &mapping->bman_portal_low);
131134 + bm_put_unused_portal(mapping->bportal);
131135 + }
131136 + kfree(mapping);
131137 + return 0;
131138 +}
131139 +
131140 +static long usdpaa_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
131141 +{
131142 + struct ctx *ctx = fp->private_data;
131143 + void __user *a = (void __user *)arg;
131144 + switch (cmd) {
131145 + case USDPAA_IOCTL_ID_ALLOC:
131146 + return ioctl_id_alloc(ctx, a);
131147 + case USDPAA_IOCTL_ID_RELEASE:
131148 + return ioctl_id_release(ctx, a);
131149 + case USDPAA_IOCTL_ID_RESERVE:
131150 + return ioctl_id_reserve(ctx, a);
131151 + case USDPAA_IOCTL_DMA_MAP:
131152 + {
131153 + struct usdpaa_ioctl_dma_map input;
131154 + int ret;
131155 + if (copy_from_user(&input, a, sizeof(input)))
131156 + return -EFAULT;
131157 + ret = ioctl_dma_map(fp, ctx, &input);
131158 + if (copy_to_user(a, &input, sizeof(input)))
131159 + return -EFAULT;
131160 + return ret;
131161 + }
131162 + case USDPAA_IOCTL_DMA_UNMAP:
131163 + return ioctl_dma_unmap(ctx, a);
131164 + case USDPAA_IOCTL_DMA_LOCK:
131165 + return ioctl_dma_lock(ctx, a);
131166 + case USDPAA_IOCTL_DMA_UNLOCK:
131167 + return ioctl_dma_unlock(ctx, a);
131168 + case USDPAA_IOCTL_PORTAL_MAP:
131169 + {
131170 + struct usdpaa_ioctl_portal_map input;
131171 + int ret;
131172 + if (copy_from_user(&input, a, sizeof(input)))
131173 + return -EFAULT;
131174 + ret = ioctl_portal_map(fp, ctx, &input);
131175 + if (copy_to_user(a, &input, sizeof(input)))
131176 + return -EFAULT;
131177 + return ret;
131178 + }
131179 + case USDPAA_IOCTL_PORTAL_UNMAP:
131180 + {
131181 + struct usdpaa_portal_map input;
131182 + if (copy_from_user(&input, a, sizeof(input)))
131183 + return -EFAULT;
131184 + return ioctl_portal_unmap(ctx, &input);
131185 + }
131186 + case USDPAA_IOCTL_DMA_USED:
131187 + return ioctl_dma_stats(ctx, a);
131188 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL:
131189 + {
131190 + struct usdpaa_ioctl_raw_portal input;
131191 + int ret;
131192 + if (copy_from_user(&input, a, sizeof(input)))
131193 + return -EFAULT;
131194 + ret = ioctl_allocate_raw_portal(fp, ctx, &input);
131195 + if (copy_to_user(a, &input, sizeof(input)))
131196 + return -EFAULT;
131197 + return ret;
131198 + }
131199 + case USDPAA_IOCTL_FREE_RAW_PORTAL:
131200 + {
131201 + struct usdpaa_ioctl_raw_portal input;
131202 + if (copy_from_user(&input, a, sizeof(input)))
131203 + return -EFAULT;
131204 + return ioctl_free_raw_portal(fp, ctx, &input);
131205 + }
131206 + }
131207 + return -EINVAL;
131208 +}
131209 +
131210 +static long usdpaa_ioctl_compat(struct file *fp, unsigned int cmd,
131211 + unsigned long arg)
131212 +{
131213 +#ifdef CONFIG_COMPAT
131214 + struct ctx *ctx = fp->private_data;
131215 + void __user *a = (void __user *)arg;
131216 +#endif
131217 + switch (cmd) {
131218 +#ifdef CONFIG_COMPAT
131219 + case USDPAA_IOCTL_DMA_MAP_COMPAT:
131220 + {
131221 + int ret;
131222 + struct usdpaa_ioctl_dma_map_compat input;
131223 + struct usdpaa_ioctl_dma_map converted;
131224 +
131225 + if (copy_from_user(&input, a, sizeof(input)))
131226 + return -EFAULT;
131227 +
131228 + converted.ptr = compat_ptr(input.ptr);
131229 + converted.phys_addr = input.phys_addr;
131230 + converted.len = input.len;
131231 + converted.flags = input.flags;
131232 + strncpy(converted.name, input.name, USDPAA_DMA_NAME_MAX);
131233 + converted.has_locking = input.has_locking;
131234 + converted.did_create = input.did_create;
131235 +
131236 + ret = ioctl_dma_map(fp, ctx, &converted);
131237 + input.ptr = ptr_to_compat(converted.ptr);
131238 + input.phys_addr = converted.phys_addr;
131239 + input.len = converted.len;
131240 + input.flags = converted.flags;
131241 + strncpy(input.name, converted.name, USDPAA_DMA_NAME_MAX);
131242 + input.has_locking = converted.has_locking;
131243 + input.did_create = converted.did_create;
131244 + if (copy_to_user(a, &input, sizeof(input)))
131245 + return -EFAULT;
131246 + return ret;
131247 + }
131248 + case USDPAA_IOCTL_PORTAL_MAP_COMPAT:
131249 + {
131250 + int ret;
131251 + struct compat_usdpaa_ioctl_portal_map input;
131252 + struct usdpaa_ioctl_portal_map converted;
131253 + if (copy_from_user(&input, a, sizeof(input)))
131254 + return -EFAULT;
131255 + converted.type = input.type;
131256 + converted.index = input.index;
131257 + ret = ioctl_portal_map(fp, ctx, &converted);
131258 + input.addr.cinh = ptr_to_compat(converted.addr.cinh);
131259 + input.addr.cena = ptr_to_compat(converted.addr.cena);
131260 + input.channel = converted.channel;
131261 + input.pools = converted.pools;
131262 + input.index = converted.index;
131263 + if (copy_to_user(a, &input, sizeof(input)))
131264 + return -EFAULT;
131265 + return ret;
131266 + }
131267 + case USDPAA_IOCTL_PORTAL_UNMAP_COMPAT:
131268 + {
131269 + struct usdpaa_portal_map_compat input;
131270 + struct usdpaa_portal_map converted;
131271 +
131272 + if (copy_from_user(&input, a, sizeof(input)))
131273 + return -EFAULT;
131274 + converted.cinh = compat_ptr(input.cinh);
131275 + converted.cena = compat_ptr(input.cena);
131276 + return ioctl_portal_unmap(ctx, &converted);
131277 + }
131278 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT:
131279 + {
131280 + int ret;
131281 + struct usdpaa_ioctl_raw_portal converted;
131282 + struct compat_ioctl_raw_portal input;
131283 + if (copy_from_user(&input, a, sizeof(input)))
131284 + return -EFAULT;
131285 + converted.type = input.type;
131286 + converted.index = input.index;
131287 + converted.enable_stash = input.enable_stash;
131288 + converted.cpu = input.cpu;
131289 + converted.cache = input.cache;
131290 + converted.window = input.window;
131291 + converted.sdest = input.sdest;
131292 + ret = ioctl_allocate_raw_portal(fp, ctx, &converted);
131293 +
131294 + input.cinh = converted.cinh;
131295 + input.cena = converted.cena;
131296 + input.index = converted.index;
131297 +
131298 + if (copy_to_user(a, &input, sizeof(input)))
131299 + return -EFAULT;
131300 + return ret;
131301 + }
131302 + case USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT:
131303 + {
131304 + struct usdpaa_ioctl_raw_portal converted;
131305 + struct compat_ioctl_raw_portal input;
131306 + if (copy_from_user(&input, a, sizeof(input)))
131307 + return -EFAULT;
131308 + converted.type = input.type;
131309 + converted.index = input.index;
131310 + converted.cinh = input.cinh;
131311 + converted.cena = input.cena;
131312 + return ioctl_free_raw_portal(fp, ctx, &converted);
131313 + }
131314 +#endif
131315 + default:
131316 + return usdpaa_ioctl(fp, cmd, arg);
131317 + }
131318 + return -EINVAL;
131319 +}
131320 +
131321 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
131322 + enum usdpaa_portal_type ptype, unsigned int *irq,
131323 + void **iir_reg)
131324 +{
131325 + /* Walk the list of portals for filp and return the config
131326 + for the portal that matches the hint */
131327 + struct ctx *context;
131328 + struct portal_mapping *portal;
131329 +
131330 + /* First sanitize the filp */
131331 + if (filp->f_op->open != usdpaa_open)
131332 + return -ENODEV;
131333 + context = filp->private_data;
131334 + spin_lock(&context->lock);
131335 + list_for_each_entry(portal, &context->portals, list) {
131336 + if (portal->user.type == ptype &&
131337 + portal->user.addr.cinh == cinh) {
131338 + if (ptype == usdpaa_portal_qman) {
131339 + *irq = portal->qportal->public_cfg.irq;
131340 + *iir_reg = portal->qportal->addr_virt[1] +
131341 + QM_REG_IIR;
131342 + } else {
131343 + *irq = portal->bportal->public_cfg.irq;
131344 + *iir_reg = portal->bportal->addr_virt[1] +
131345 + BM_REG_IIR;
131346 + }
131347 + spin_unlock(&context->lock);
131348 + return 0;
131349 + }
131350 + }
131351 + spin_unlock(&context->lock);
131352 + return -EINVAL;
131353 +}
131354 +
131355 +static const struct file_operations usdpaa_fops = {
131356 + .open = usdpaa_open,
131357 + .release = usdpaa_release,
131358 + .mmap = usdpaa_mmap,
131359 + .get_unmapped_area = usdpaa_get_unmapped_area,
131360 + .unlocked_ioctl = usdpaa_ioctl,
131361 + .compat_ioctl = usdpaa_ioctl_compat
131362 +};
131363 +
131364 +static struct miscdevice usdpaa_miscdev = {
131365 + .name = "fsl-usdpaa",
131366 + .fops = &usdpaa_fops,
131367 + .minor = MISC_DYNAMIC_MINOR,
131368 +};
131369 +
131370 +/* Early-boot memory allocation. The boot-arg "usdpaa_mem=<x>" is used to
131371 + * indicate how much memory (if any) to allocate during early boot. If the
131372 + * format "usdpaa_mem=<x>,<y>" is used, then <y> will be interpreted as the
131373 + * number of TLB1 entries to reserve (default is 1). If there are more mappings
131374 + * than there are TLB1 entries, fault-handling will occur. */
131375 +
131376 +static __init int usdpaa_mem(char *arg)
131377 +{
131378 + pr_warn("uspdaa_mem argument is depracated\n");
131379 + arg_phys_size = memparse(arg, &arg);
131380 + num_tlb = 1;
131381 + if (*arg == ',') {
131382 + unsigned long ul;
131383 + int err = kstrtoul(arg + 1, 0, &ul);
131384 + if (err < 0) {
131385 + num_tlb = 1;
131386 + pr_warn("ERROR, usdpaa_mem arg is invalid\n");
131387 + } else
131388 + num_tlb = (unsigned int)ul;
131389 + }
131390 + return 0;
131391 +}
131392 +early_param("usdpaa_mem", usdpaa_mem);
131393 +
131394 +static int usdpaa_mem_init(struct reserved_mem *rmem)
131395 +{
131396 + phys_start = rmem->base;
131397 + phys_size = rmem->size;
131398 +
131399 + WARN_ON(!(phys_start && phys_size));
131400 +
131401 + return 0;
131402 +}
131403 +RESERVEDMEM_OF_DECLARE(usdpaa_mem_init, "fsl,usdpaa-mem", usdpaa_mem_init);
131404 +
131405 +__init int fsl_usdpaa_init_early(void)
131406 +{
131407 + if (!phys_size || !phys_start) {
131408 + pr_info("No USDPAA memory, no 'fsl,usdpaa-mem' in device-tree\n");
131409 + return 0;
131410 + }
131411 + if (phys_size % PAGE_SIZE) {
131412 + pr_err("'fsl,usdpaa-mem' size must be a multiple of page size\n");
131413 + phys_size = 0;
131414 + return 0;
131415 + }
131416 + if (arg_phys_size && phys_size != arg_phys_size) {
131417 + pr_err("'usdpaa_mem argument size (0x%llx) does not match device tree size (0x%llx)\n",
131418 + arg_phys_size, phys_size);
131419 + phys_size = 0;
131420 + return 0;
131421 + }
131422 + pfn_start = phys_start >> PAGE_SHIFT;
131423 + pfn_size = phys_size >> PAGE_SHIFT;
131424 +#ifdef CONFIG_PPC
131425 + first_tlb = current_tlb = tlbcam_index;
131426 + tlbcam_index += num_tlb;
131427 +#endif
131428 + pr_info("USDPAA region at %llx:%llx(%lx:%lx), %d TLB1 entries)\n",
131429 + phys_start, phys_size, pfn_start, pfn_size, num_tlb);
131430 + return 0;
131431 +}
131432 +subsys_initcall(fsl_usdpaa_init_early);
131433 +
131434 +
131435 +static int __init usdpaa_init(void)
131436 +{
131437 + struct mem_fragment *frag;
131438 + int ret;
131439 + u64 tmp_size = phys_size;
131440 + u64 tmp_start = phys_start;
131441 + u64 tmp_pfn_size = pfn_size;
131442 + u64 tmp_pfn_start = pfn_start;
131443 +
131444 + pr_info("Freescale USDPAA process driver\n");
131445 + if (!phys_start) {
131446 + pr_warn("fsl-usdpaa: no region found\n");
131447 + return 0;
131448 + }
131449 +
131450 + while (tmp_size != 0) {
131451 + u32 frag_size = largest_page_size(tmp_size);
131452 + frag = kmalloc(sizeof(*frag), GFP_KERNEL);
131453 + if (!frag) {
131454 + pr_err("Failed to setup USDPAA memory accounting\n");
131455 + return -ENOMEM;
131456 + }
131457 + frag->base = tmp_start;
131458 + frag->len = frag->root_len = frag_size;
131459 + frag->root_pfn = tmp_pfn_start;
131460 + frag->pfn_base = tmp_pfn_start;
131461 + frag->pfn_len = frag_size / PAGE_SIZE;
131462 + frag->refs = 0;
131463 + init_waitqueue_head(&frag->wq);
131464 + frag->owner = NULL;
131465 + list_add(&frag->list, &mem_list);
131466 +
131467 + /* Adjust for this frag */
131468 + tmp_start += frag_size;
131469 + tmp_size -= frag_size;
131470 + tmp_pfn_start += frag_size / PAGE_SIZE;
131471 + tmp_pfn_size -= frag_size / PAGE_SIZE;
131472 + }
131473 + ret = misc_register(&usdpaa_miscdev);
131474 + if (ret)
131475 + pr_err("fsl-usdpaa: failed to register misc device\n");
131476 + return ret;
131477 +}
131478 +
131479 +static void __exit usdpaa_exit(void)
131480 +{
131481 + misc_deregister(&usdpaa_miscdev);
131482 +}
131483 +
131484 +module_init(usdpaa_init);
131485 +module_exit(usdpaa_exit);
131486 +
131487 +MODULE_LICENSE("GPL");
131488 +MODULE_AUTHOR("Freescale Semiconductor");
131489 +MODULE_DESCRIPTION("Freescale USDPAA process driver");
131490 --- /dev/null
131491 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
131492 @@ -0,0 +1,289 @@
131493 +/* Copyright (c) 2013 Freescale Semiconductor, Inc.
131494 + * All rights reserved.
131495 + *
131496 + * Redistribution and use in source and binary forms, with or without
131497 + * modification, are permitted provided that the following conditions are met:
131498 + * * Redistributions of source code must retain the above copyright
131499 + * notice, this list of conditions and the following disclaimer.
131500 + * * Redistributions in binary form must reproduce the above copyright
131501 + * notice, this list of conditions and the following disclaimer in the
131502 + * documentation and/or other materials provided with the distribution.
131503 + * * Neither the name of Freescale Semiconductor nor the
131504 + * names of its contributors may be used to endorse or promote products
131505 + * derived from this software without specific prior written permission.
131506 + *
131507 + *
131508 + * ALTERNATIVELY, this software may be distributed under the terms of the
131509 + * GNU General Public License ("GPL") as published by the Free Software
131510 + * Foundation, either version 2 of that License or (at your option) any
131511 + * later version.
131512 + *
131513 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131514 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131515 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131516 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131517 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131518 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131519 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131520 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131521 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131522 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131523 + */
131524 +
131525 +/* define a device that allows USPDAA processes to open a file
131526 + descriptor and specify which IRQ it wants to montior using an ioctl()
131527 + When an IRQ is received, the device becomes readable so that a process
131528 + can use read() or select() type calls to monitor for IRQs */
131529 +
131530 +#include <linux/miscdevice.h>
131531 +#include <linux/fs.h>
131532 +#include <linux/cdev.h>
131533 +#include <linux/slab.h>
131534 +#include <linux/interrupt.h>
131535 +#include <linux/poll.h>
131536 +#include <linux/uaccess.h>
131537 +#include <linux/fsl_usdpaa.h>
131538 +#include <linux/module.h>
131539 +#include <linux/fdtable.h>
131540 +#include <linux/file.h>
131541 +
131542 +#include "qman_low.h"
131543 +#include "bman_low.h"
131544 +
131545 +struct usdpaa_irq_ctx {
131546 + int irq_set; /* Set to true once the irq is set via ioctl */
131547 + unsigned int irq_num;
131548 + u32 last_irq_count; /* Last value returned from read */
131549 + u32 irq_count; /* Number of irqs since last read */
131550 + wait_queue_head_t wait_queue; /* Waiting processes */
131551 + spinlock_t lock;
131552 + void *inhibit_addr; /* inhibit register address */
131553 + struct file *usdpaa_filp;
131554 + char irq_name[128];
131555 +};
131556 +
131557 +static int usdpaa_irq_open(struct inode *inode, struct file *filp)
131558 +{
131559 + struct usdpaa_irq_ctx *ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
131560 + if (!ctx)
131561 + return -ENOMEM;
131562 + ctx->irq_set = 0;
131563 + ctx->irq_count = 0;
131564 + ctx->last_irq_count = 0;
131565 + init_waitqueue_head(&ctx->wait_queue);
131566 + spin_lock_init(&ctx->lock);
131567 + filp->private_data = ctx;
131568 + return 0;
131569 +}
131570 +
131571 +static int usdpaa_irq_release(struct inode *inode, struct file *filp)
131572 +{
131573 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131574 + if (ctx->irq_set) {
131575 + /* Inhibit the IRQ */
131576 + out_be32(ctx->inhibit_addr, 0x1);
131577 + irq_set_affinity_hint(ctx->irq_num, NULL);
131578 + free_irq(ctx->irq_num, ctx);
131579 + ctx->irq_set = 0;
131580 + fput(ctx->usdpaa_filp);
131581 + }
131582 + kfree(filp->private_data);
131583 + return 0;
131584 +}
131585 +
131586 +static irqreturn_t usdpaa_irq_handler(int irq, void *_ctx)
131587 +{
131588 + unsigned long flags;
131589 + struct usdpaa_irq_ctx *ctx = _ctx;
131590 + spin_lock_irqsave(&ctx->lock, flags);
131591 + ++ctx->irq_count;
131592 + spin_unlock_irqrestore(&ctx->lock, flags);
131593 + wake_up_all(&ctx->wait_queue);
131594 + /* Set the inhibit register. This will be reenabled
131595 + once the USDPAA code handles the IRQ */
131596 + out_be32(ctx->inhibit_addr, 0x1);
131597 + pr_info("Inhibit at %p count %d", ctx->inhibit_addr, ctx->irq_count);
131598 + return IRQ_HANDLED;
131599 +}
131600 +
131601 +static int map_irq(struct file *fp, struct usdpaa_ioctl_irq_map *irq_map)
131602 +{
131603 + struct usdpaa_irq_ctx *ctx = fp->private_data;
131604 + int ret;
131605 +
131606 + if (ctx->irq_set) {
131607 + pr_debug("Setting USDPAA IRQ when it was already set!\n");
131608 + return -EBUSY;
131609 + }
131610 +
131611 + ctx->usdpaa_filp = fget(irq_map->fd);
131612 + if (!ctx->usdpaa_filp) {
131613 + pr_debug("USDPAA fget(%d) returned NULL\n", irq_map->fd);
131614 + return -EINVAL;
131615 + }
131616 +
131617 + ret = usdpaa_get_portal_config(ctx->usdpaa_filp, irq_map->portal_cinh,
131618 + irq_map->type, &ctx->irq_num,
131619 + &ctx->inhibit_addr);
131620 + if (ret) {
131621 + pr_debug("USDPAA IRQ couldn't identify portal\n");
131622 + fput(ctx->usdpaa_filp);
131623 + return ret;
131624 + }
131625 +
131626 + ctx->irq_set = 1;
131627 +
131628 + snprintf(ctx->irq_name, sizeof(ctx->irq_name),
131629 + "usdpaa_irq %d", ctx->irq_num);
131630 +
131631 + ret = request_irq(ctx->irq_num, usdpaa_irq_handler, 0,
131632 + ctx->irq_name, ctx);
131633 + if (ret) {
131634 + pr_err("USDPAA request_irq(%d) failed, ret= %d\n",
131635 + ctx->irq_num, ret);
131636 + ctx->irq_set = 0;
131637 + fput(ctx->usdpaa_filp);
131638 + return ret;
131639 + }
131640 + ret = irq_set_affinity(ctx->irq_num, &current->cpus_allowed);
131641 + if (ret)
131642 + pr_err("USDPAA irq_set_affinity() failed, ret= %d\n", ret);
131643 +
131644 + ret = irq_set_affinity_hint(ctx->irq_num, &current->cpus_allowed);
131645 + if (ret)
131646 + pr_err("USDPAA irq_set_affinity_hint() failed, ret= %d\n", ret);
131647 +
131648 + return 0;
131649 +}
131650 +
131651 +static long usdpaa_irq_ioctl(struct file *fp, unsigned int cmd,
131652 + unsigned long arg)
131653 +{
131654 + int ret;
131655 + struct usdpaa_ioctl_irq_map irq_map;
131656 +
131657 + if (cmd != USDPAA_IOCTL_PORTAL_IRQ_MAP) {
131658 + pr_debug("USDPAA IRQ unknown command 0x%x\n", cmd);
131659 + return -EINVAL;
131660 + }
131661 +
131662 + ret = copy_from_user(&irq_map, (void __user *)arg,
131663 + sizeof(irq_map));
131664 + if (ret)
131665 + return ret;
131666 + return map_irq(fp, &irq_map);
131667 +}
131668 +
131669 +static ssize_t usdpaa_irq_read(struct file *filp, char __user *buff,
131670 + size_t count, loff_t *offp)
131671 +{
131672 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131673 + int ret;
131674 +
131675 + if (!ctx->irq_set) {
131676 + pr_debug("Reading USDPAA IRQ before it was set\n");
131677 + return -EINVAL;
131678 + }
131679 +
131680 + if (count < sizeof(ctx->irq_count)) {
131681 + pr_debug("USDPAA IRQ Read too small\n");
131682 + return -EINVAL;
131683 + }
131684 + if (ctx->irq_count == ctx->last_irq_count) {
131685 + if (filp->f_flags & O_NONBLOCK)
131686 + return -EAGAIN;
131687 +
131688 + ret = wait_event_interruptible(ctx->wait_queue,
131689 + ctx->irq_count != ctx->last_irq_count);
131690 + if (ret == -ERESTARTSYS)
131691 + return ret;
131692 + }
131693 +
131694 + ctx->last_irq_count = ctx->irq_count;
131695 +
131696 + if (copy_to_user(buff, &ctx->last_irq_count,
131697 + sizeof(ctx->last_irq_count)))
131698 + return -EFAULT;
131699 + return sizeof(ctx->irq_count);
131700 +}
131701 +
131702 +static unsigned int usdpaa_irq_poll(struct file *filp, poll_table *wait)
131703 +{
131704 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131705 + unsigned int ret = 0;
131706 + unsigned long flags;
131707 +
131708 + if (!ctx->irq_set)
131709 + return POLLHUP;
131710 +
131711 + poll_wait(filp, &ctx->wait_queue, wait);
131712 +
131713 + spin_lock_irqsave(&ctx->lock, flags);
131714 + if (ctx->irq_count != ctx->last_irq_count)
131715 + ret |= POLLIN | POLLRDNORM;
131716 + spin_unlock_irqrestore(&ctx->lock, flags);
131717 + return ret;
131718 +}
131719 +
131720 +static long usdpaa_irq_ioctl_compat(struct file *fp, unsigned int cmd,
131721 + unsigned long arg)
131722 +{
131723 +#ifdef CONFIG_COMPAT
131724 + void __user *a = (void __user *)arg;
131725 +#endif
131726 + switch (cmd) {
131727 +#ifdef CONFIG_COMPAT
131728 + case USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT:
131729 + {
131730 + struct compat_ioctl_irq_map input;
131731 + struct usdpaa_ioctl_irq_map converted;
131732 + if (copy_from_user(&input, a, sizeof(input)))
131733 + return -EFAULT;
131734 + converted.type = input.type;
131735 + converted.fd = input.fd;
131736 + converted.portal_cinh = compat_ptr(input.portal_cinh);
131737 + return map_irq(fp, &converted);
131738 + }
131739 +#endif
131740 + default:
131741 + return usdpaa_irq_ioctl(fp, cmd, arg);
131742 + }
131743 +}
131744 +
131745 +static const struct file_operations usdpaa_irq_fops = {
131746 + .open = usdpaa_irq_open,
131747 + .release = usdpaa_irq_release,
131748 + .unlocked_ioctl = usdpaa_irq_ioctl,
131749 + .compat_ioctl = usdpaa_irq_ioctl_compat,
131750 + .read = usdpaa_irq_read,
131751 + .poll = usdpaa_irq_poll
131752 +};
131753 +
131754 +static struct miscdevice usdpaa_miscdev = {
131755 + .name = "fsl-usdpaa-irq",
131756 + .fops = &usdpaa_irq_fops,
131757 + .minor = MISC_DYNAMIC_MINOR,
131758 +};
131759 +
131760 +static int __init usdpaa_irq_init(void)
131761 +{
131762 + int ret;
131763 +
131764 + pr_info("Freescale USDPAA process IRQ driver\n");
131765 + ret = misc_register(&usdpaa_miscdev);
131766 + if (ret)
131767 + pr_err("fsl-usdpaa-irq: failed to register misc device\n");
131768 + return ret;
131769 +}
131770 +
131771 +static void __exit usdpaa_irq_exit(void)
131772 +{
131773 + misc_deregister(&usdpaa_miscdev);
131774 +}
131775 +
131776 +module_init(usdpaa_irq_init);
131777 +module_exit(usdpaa_irq_exit);
131778 +
131779 +MODULE_LICENSE("GPL");
131780 +MODULE_AUTHOR("Freescale Semiconductor");
131781 +MODULE_DESCRIPTION("Freescale USDPAA process IRQ driver");
131782 --- /dev/null
131783 +++ b/drivers/staging/fsl_qbman/qbman_driver.c
131784 @@ -0,0 +1,88 @@
131785 +/* Copyright 2013 Freescale Semiconductor, Inc.
131786 + *
131787 + * Redistribution and use in source and binary forms, with or without
131788 + * modification, are permitted provided that the following conditions are met:
131789 + * * Redistributions of source code must retain the above copyright
131790 + * notice, this list of conditions and the following disclaimer.
131791 + * * Redistributions in binary form must reproduce the above copyright
131792 + * notice, this list of conditions and the following disclaimer in the
131793 + * documentation and/or other materials provided with the distribution.
131794 + * * Neither the name of Freescale Semiconductor nor the
131795 + * names of its contributors may be used to endorse or promote products
131796 + * derived from this software without specific prior written permission.
131797 + *
131798 + *
131799 + * ALTERNATIVELY, this software may be distributed under the terms of the
131800 + * GNU General Public License ("GPL") as published by the Free Software
131801 + * Foundation, either version 2 of that License or (at your option) any
131802 + * later version.
131803 + *
131804 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131805 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131806 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131807 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131808 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131809 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131810 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131811 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131812 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131813 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131814 + */
131815 +
131816 +#include <linux/time.h>
131817 +#include "qman_private.h"
131818 +#include "bman_private.h"
131819 +__init void qman_init_early(void);
131820 +__init void bman_init_early(void);
131821 +
131822 +static __init int qbman_init(void)
131823 +{
131824 + struct device_node *dn;
131825 + u32 is_portal_available;
131826 +
131827 + bman_init();
131828 + qman_init();
131829 +
131830 + is_portal_available = 0;
131831 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
131832 + if (!of_device_is_available(dn))
131833 + continue;
131834 + else
131835 + is_portal_available = 1;
131836 + }
131837 +
131838 + if (!qman_have_ccsr() && is_portal_available) {
131839 + struct qman_fq fq = {
131840 + .fqid = 1
131841 + };
131842 + struct qm_mcr_queryfq_np np;
131843 + int err, retry = CONFIG_FSL_QMAN_INIT_TIMEOUT;
131844 + struct timespec nowts, diffts, startts = current_kernel_time();
131845 + /* Loop while querying given fqid succeeds or time out */
131846 + while (1) {
131847 + err = qman_query_fq_np(&fq, &np);
131848 + if (!err) {
131849 + /* success, control-plane has configured QMan */
131850 + break;
131851 + } else if (err != -ERANGE) {
131852 + pr_err("QMan: I/O error, continuing anyway\n");
131853 + break;
131854 + }
131855 + nowts = current_kernel_time();
131856 + diffts = timespec_sub(nowts, startts);
131857 + if (diffts.tv_sec > 0) {
131858 + if (!retry--) {
131859 + pr_err("QMan: time out, control-plane"
131860 + " dead?\n");
131861 + break;
131862 + }
131863 + pr_warn("QMan: polling for the control-plane"
131864 + " (%d)\n", retry);
131865 + }
131866 + }
131867 + }
131868 + bman_resource_init();
131869 + qman_resource_init();
131870 + return 0;
131871 +}
131872 +subsys_initcall(qbman_init);
131873 --- /dev/null
131874 +++ b/drivers/staging/fsl_qbman/qman_config.c
131875 @@ -0,0 +1,1224 @@
131876 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
131877 + *
131878 + * Redistribution and use in source and binary forms, with or without
131879 + * modification, are permitted provided that the following conditions are met:
131880 + * * Redistributions of source code must retain the above copyright
131881 + * notice, this list of conditions and the following disclaimer.
131882 + * * Redistributions in binary form must reproduce the above copyright
131883 + * notice, this list of conditions and the following disclaimer in the
131884 + * documentation and/or other materials provided with the distribution.
131885 + * * Neither the name of Freescale Semiconductor nor the
131886 + * names of its contributors may be used to endorse or promote products
131887 + * derived from this software without specific prior written permission.
131888 + *
131889 + *
131890 + * ALTERNATIVELY, this software may be distributed under the terms of the
131891 + * GNU General Public License ("GPL") as published by the Free Software
131892 + * Foundation, either version 2 of that License or (at your option) any
131893 + * later version.
131894 + *
131895 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131896 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131897 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131898 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131899 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131900 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131901 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131902 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131903 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131904 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131905 + */
131906 +
131907 +#include <asm/cacheflush.h>
131908 +#include "qman_private.h"
131909 +#include <linux/highmem.h>
131910 +#include <linux/of_reserved_mem.h>
131911 +
131912 +/* Last updated for v00.800 of the BG */
131913 +
131914 +/* Register offsets */
131915 +#define REG_QCSP_LIO_CFG(n) (0x0000 + ((n) * 0x10))
131916 +#define REG_QCSP_IO_CFG(n) (0x0004 + ((n) * 0x10))
131917 +#define REG_QCSP_DD_CFG(n) (0x000c + ((n) * 0x10))
131918 +#define REG_DD_CFG 0x0200
131919 +#define REG_DCP_CFG(n) (0x0300 + ((n) * 0x10))
131920 +#define REG_DCP_DD_CFG(n) (0x0304 + ((n) * 0x10))
131921 +#define REG_DCP_DLM_AVG(n) (0x030c + ((n) * 0x10))
131922 +#define REG_PFDR_FPC 0x0400
131923 +#define REG_PFDR_FP_HEAD 0x0404
131924 +#define REG_PFDR_FP_TAIL 0x0408
131925 +#define REG_PFDR_FP_LWIT 0x0410
131926 +#define REG_PFDR_CFG 0x0414
131927 +#define REG_SFDR_CFG 0x0500
131928 +#define REG_SFDR_IN_USE 0x0504
131929 +#define REG_WQ_CS_CFG(n) (0x0600 + ((n) * 0x04))
131930 +#define REG_WQ_DEF_ENC_WQID 0x0630
131931 +#define REG_WQ_SC_DD_CFG(n) (0x640 + ((n) * 0x04))
131932 +#define REG_WQ_PC_DD_CFG(n) (0x680 + ((n) * 0x04))
131933 +#define REG_WQ_DC0_DD_CFG(n) (0x6c0 + ((n) * 0x04))
131934 +#define REG_WQ_DC1_DD_CFG(n) (0x700 + ((n) * 0x04))
131935 +#define REG_WQ_DCn_DD_CFG(n) (0x6c0 + ((n) * 0x40)) /* n=2,3 */
131936 +#define REG_CM_CFG 0x0800
131937 +#define REG_ECSR 0x0a00
131938 +#define REG_ECIR 0x0a04
131939 +#define REG_EADR 0x0a08
131940 +#define REG_ECIR2 0x0a0c
131941 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
131942 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
131943 +#define REG_MCR 0x0b00
131944 +#define REG_MCP(n) (0x0b04 + ((n) * 0x04))
131945 +#define REG_MISC_CFG 0x0be0
131946 +#define REG_HID_CFG 0x0bf0
131947 +#define REG_IDLE_STAT 0x0bf4
131948 +#define REG_IP_REV_1 0x0bf8
131949 +#define REG_IP_REV_2 0x0bfc
131950 +#define REG_FQD_BARE 0x0c00
131951 +#define REG_PFDR_BARE 0x0c20
131952 +#define REG_offset_BAR 0x0004 /* relative to REG_[FQD|PFDR]_BARE */
131953 +#define REG_offset_AR 0x0010 /* relative to REG_[FQD|PFDR]_BARE */
131954 +#define REG_QCSP_BARE 0x0c80
131955 +#define REG_QCSP_BAR 0x0c84
131956 +#define REG_CI_SCHED_CFG 0x0d00
131957 +#define REG_SRCIDR 0x0d04
131958 +#define REG_LIODNR 0x0d08
131959 +#define REG_CI_RLM_AVG 0x0d14
131960 +#define REG_ERR_ISR 0x0e00 /* + "enum qm_isr_reg" */
131961 +#define REG_REV3_QCSP_LIO_CFG(n) (0x1000 + ((n) * 0x10))
131962 +#define REG_REV3_QCSP_IO_CFG(n) (0x1004 + ((n) * 0x10))
131963 +#define REG_REV3_QCSP_DD_CFG(n) (0x100c + ((n) * 0x10))
131964 +#define REG_CEETM_CFG_IDX 0x900
131965 +#define REG_CEETM_CFG_PRES 0x904
131966 +#define REG_CEETM_XSFDR_IN_USE 0x908
131967 +
131968 +/* Assists for QMAN_MCR */
131969 +#define MCR_INIT_PFDR 0x01000000
131970 +#define MCR_get_rslt(v) (u8)((v) >> 24)
131971 +#define MCR_rslt_idle(r) (!rslt || (rslt >= 0xf0))
131972 +#define MCR_rslt_ok(r) (rslt == 0xf0)
131973 +#define MCR_rslt_eaccess(r) (rslt == 0xf8)
131974 +#define MCR_rslt_inval(r) (rslt == 0xff)
131975 +
131976 +struct qman;
131977 +
131978 +/* Follows WQ_CS_CFG0-5 */
131979 +enum qm_wq_class {
131980 + qm_wq_portal = 0,
131981 + qm_wq_pool = 1,
131982 + qm_wq_fman0 = 2,
131983 + qm_wq_fman1 = 3,
131984 + qm_wq_caam = 4,
131985 + qm_wq_pme = 5,
131986 + qm_wq_first = qm_wq_portal,
131987 + qm_wq_last = qm_wq_pme
131988 +};
131989 +
131990 +/* Follows FQD_[BARE|BAR|AR] and PFDR_[BARE|BAR|AR] */
131991 +enum qm_memory {
131992 + qm_memory_fqd,
131993 + qm_memory_pfdr
131994 +};
131995 +
131996 +/* Used by all error interrupt registers except 'inhibit' */
131997 +#define QM_EIRQ_CIDE 0x20000000 /* Corenet Initiator Data Error */
131998 +#define QM_EIRQ_CTDE 0x10000000 /* Corenet Target Data Error */
131999 +#define QM_EIRQ_CITT 0x08000000 /* Corenet Invalid Target Transaction */
132000 +#define QM_EIRQ_PLWI 0x04000000 /* PFDR Low Watermark */
132001 +#define QM_EIRQ_MBEI 0x02000000 /* Multi-bit ECC Error */
132002 +#define QM_EIRQ_SBEI 0x01000000 /* Single-bit ECC Error */
132003 +#define QM_EIRQ_PEBI 0x00800000 /* PFDR Enqueues Blocked Interrupt */
132004 +#define QM_EIRQ_IFSI 0x00020000 /* Invalid FQ Flow Control State */
132005 +#define QM_EIRQ_ICVI 0x00010000 /* Invalid Command Verb */
132006 +#define QM_EIRQ_IDDI 0x00000800 /* Invalid Dequeue (Direct-connect) */
132007 +#define QM_EIRQ_IDFI 0x00000400 /* Invalid Dequeue FQ */
132008 +#define QM_EIRQ_IDSI 0x00000200 /* Invalid Dequeue Source */
132009 +#define QM_EIRQ_IDQI 0x00000100 /* Invalid Dequeue Queue */
132010 +#define QM_EIRQ_IECE 0x00000010 /* Invalid Enqueue Configuration */
132011 +#define QM_EIRQ_IEOI 0x00000008 /* Invalid Enqueue Overflow */
132012 +#define QM_EIRQ_IESI 0x00000004 /* Invalid Enqueue State */
132013 +#define QM_EIRQ_IECI 0x00000002 /* Invalid Enqueue Channel */
132014 +#define QM_EIRQ_IEQI 0x00000001 /* Invalid Enqueue Queue */
132015 +
132016 +/* QMAN_ECIR valid error bit */
132017 +#define PORTAL_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IESI | QM_EIRQ_IEOI | \
132018 + QM_EIRQ_IDQI | QM_EIRQ_IDSI | QM_EIRQ_IDFI | \
132019 + QM_EIRQ_IDDI | QM_EIRQ_ICVI | QM_EIRQ_IFSI)
132020 +#define FQID_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IECI | QM_EIRQ_IESI | \
132021 + QM_EIRQ_IEOI | QM_EIRQ_IDQI | QM_EIRQ_IDFI | \
132022 + QM_EIRQ_IFSI)
132023 +
132024 +union qman_ecir {
132025 + u32 ecir_raw;
132026 + struct {
132027 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132028 + u32 __reserved:2;
132029 + u32 portal_type:1;
132030 + u32 portal_num:5;
132031 + u32 fqid:24;
132032 +#else
132033 + u32 fqid:24;
132034 + u32 portal_num:5;
132035 + u32 portal_type:1;
132036 + u32 __reserved:2;
132037 +#endif
132038 + } __packed info;
132039 +};
132040 +
132041 +union qman_ecir2 {
132042 + u32 ecir2_raw;
132043 + struct {
132044 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132045 + u32 portal_type:1;
132046 + u32 __reserved:21;
132047 + u32 portal_num:10;
132048 +#else
132049 + u32 portal_num:10;
132050 + u32 __reserved:21;
132051 + u32 portal_type:1;
132052 +#endif
132053 + } __packed info;
132054 +};
132055 +
132056 +union qman_eadr {
132057 + u32 eadr_raw;
132058 + struct {
132059 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132060 + u32 __reserved1:4;
132061 + u32 memid:4;
132062 + u32 __reserved2:12;
132063 + u32 eadr:12;
132064 +#else
132065 + u32 eadr:12;
132066 + u32 __reserved2:12;
132067 + u32 memid:4;
132068 + u32 __reserved1:4;
132069 +#endif
132070 + } __packed info;
132071 + struct {
132072 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132073 + u32 __reserved1:3;
132074 + u32 memid:5;
132075 + u32 __reserved:8;
132076 + u32 eadr:16;
132077 +#else
132078 + u32 eadr:16;
132079 + u32 __reserved:8;
132080 + u32 memid:5;
132081 + u32 __reserved1:3;
132082 +#endif
132083 + } __packed info_rev3;
132084 +};
132085 +
132086 +struct qman_hwerr_txt {
132087 + u32 mask;
132088 + const char *txt;
132089 +};
132090 +
132091 +#define QMAN_HWE_TXT(a, b) { .mask = QM_EIRQ_##a, .txt = b }
132092 +
132093 +static const struct qman_hwerr_txt qman_hwerr_txts[] = {
132094 + QMAN_HWE_TXT(CIDE, "Corenet Initiator Data Error"),
132095 + QMAN_HWE_TXT(CTDE, "Corenet Target Data Error"),
132096 + QMAN_HWE_TXT(CITT, "Corenet Invalid Target Transaction"),
132097 + QMAN_HWE_TXT(PLWI, "PFDR Low Watermark"),
132098 + QMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
132099 + QMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
132100 + QMAN_HWE_TXT(PEBI, "PFDR Enqueues Blocked Interrupt"),
132101 + QMAN_HWE_TXT(ICVI, "Invalid Command Verb"),
132102 + QMAN_HWE_TXT(IFSI, "Invalid Flow Control State"),
132103 + QMAN_HWE_TXT(IDDI, "Invalid Dequeue (Direct-connect)"),
132104 + QMAN_HWE_TXT(IDFI, "Invalid Dequeue FQ"),
132105 + QMAN_HWE_TXT(IDSI, "Invalid Dequeue Source"),
132106 + QMAN_HWE_TXT(IDQI, "Invalid Dequeue Queue"),
132107 + QMAN_HWE_TXT(IECE, "Invalid Enqueue Configuration"),
132108 + QMAN_HWE_TXT(IEOI, "Invalid Enqueue Overflow"),
132109 + QMAN_HWE_TXT(IESI, "Invalid Enqueue State"),
132110 + QMAN_HWE_TXT(IECI, "Invalid Enqueue Channel"),
132111 + QMAN_HWE_TXT(IEQI, "Invalid Enqueue Queue")
132112 +};
132113 +#define QMAN_HWE_COUNT (sizeof(qman_hwerr_txts)/sizeof(struct qman_hwerr_txt))
132114 +
132115 +struct qman_error_info_mdata {
132116 + u16 addr_mask;
132117 + u16 bits;
132118 + const char *txt;
132119 +};
132120 +
132121 +#define QMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
132122 +static const struct qman_error_info_mdata error_mdata[] = {
132123 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 0"),
132124 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 1"),
132125 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 2"),
132126 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 3"),
132127 + QMAN_ERR_MDATA(0x0FFF, 512, "FQD cache memory"),
132128 + QMAN_ERR_MDATA(0x07FF, 128, "SFDR memory"),
132129 + QMAN_ERR_MDATA(0x01FF, 72, "WQ context memory"),
132130 + QMAN_ERR_MDATA(0x00FF, 240, "CGR memory"),
132131 + QMAN_ERR_MDATA(0x00FF, 302, "Internal Order Restoration List memory"),
132132 + QMAN_ERR_MDATA(0x01FF, 256, "SW portal ring memory"),
132133 + QMAN_ERR_MDATA(0x07FF, 181, "CEETM class queue descriptor memory"),
132134 + QMAN_ERR_MDATA(0x0FFF, 140, "CEETM extended SFDR memory"),
132135 + QMAN_ERR_MDATA(0x0FFF, 25, "CEETM logical FQ mapping memory"),
132136 + QMAN_ERR_MDATA(0x0FFF, 96, "CEETM dequeue context memory"),
132137 + QMAN_ERR_MDATA(0x07FF, 396, "CEETM ccgr memory"),
132138 + QMAN_ERR_MDATA(0x00FF, 146, "CEETM CQ channel shaping memory"),
132139 + QMAN_ERR_MDATA(0x007F, 256, "CEETM CQ channel scheduling memory"),
132140 + QMAN_ERR_MDATA(0x01FF, 88, "CEETM dequeue statistics memory"),
132141 +};
132142 +#define QMAN_ERR_MDATA_COUNT \
132143 + (sizeof(error_mdata)/sizeof(struct qman_error_info_mdata))
132144 +
132145 +/* Add this in Kconfig */
132146 +#define QMAN_ERRS_TO_UNENABLE (QM_EIRQ_PLWI | QM_EIRQ_PEBI)
132147 +
132148 +/**
132149 + * qm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
132150 + * @v: for accessors that write values, this is the 32-bit value
132151 + *
132152 + * Manipulates QMAN_ERR_ISR, QMAN_ERR_IER, QMAN_ERR_ISDR, QMAN_ERR_IIR. All
132153 + * manipulations except qm_err_isr_[un]inhibit() use 32-bit masks composed of
132154 + * the QM_EIRQ_*** definitions. Note that "qm_err_isr_enable_write" means
132155 + * "write the enable register" rather than "enable the write register"!
132156 + */
132157 +#define qm_err_isr_status_read(qm) \
132158 + __qm_err_isr_read(qm, qm_isr_status)
132159 +#define qm_err_isr_status_clear(qm, m) \
132160 + __qm_err_isr_write(qm, qm_isr_status, m)
132161 +#define qm_err_isr_enable_read(qm) \
132162 + __qm_err_isr_read(qm, qm_isr_enable)
132163 +#define qm_err_isr_enable_write(qm, v) \
132164 + __qm_err_isr_write(qm, qm_isr_enable, v)
132165 +#define qm_err_isr_disable_read(qm) \
132166 + __qm_err_isr_read(qm, qm_isr_disable)
132167 +#define qm_err_isr_disable_write(qm, v) \
132168 + __qm_err_isr_write(qm, qm_isr_disable, v)
132169 +#define qm_err_isr_inhibit(qm) \
132170 + __qm_err_isr_write(qm, qm_isr_inhibit, 1)
132171 +#define qm_err_isr_uninhibit(qm) \
132172 + __qm_err_isr_write(qm, qm_isr_inhibit, 0)
132173 +
132174 +/*
132175 + * TODO: unimplemented registers
132176 + *
132177 + * Keeping a list here of Qman registers I have not yet covered;
132178 + * QCSP_DD_IHRSR, QCSP_DD_IHRFR, QCSP_DD_HASR,
132179 + * DCP_DD_IHRSR, DCP_DD_IHRFR, DCP_DD_HASR, CM_CFG,
132180 + * QMAN_EECC, QMAN_SBET, QMAN_EINJ, QMAN_SBEC0-12
132181 + */
132182 +
132183 +/* Encapsulate "struct qman *" as a cast of the register space address. */
132184 +
132185 +static struct qman *qm_create(void *regs)
132186 +{
132187 + return (struct qman *)regs;
132188 +}
132189 +
132190 +static inline u32 __qm_in(struct qman *qm, u32 offset)
132191 +{
132192 + return in_be32((void *)qm + offset);
132193 +}
132194 +static inline void __qm_out(struct qman *qm, u32 offset, u32 val)
132195 +{
132196 + out_be32((void *)qm + offset, val);
132197 +}
132198 +#define qm_in(reg) __qm_in(qm, REG_##reg)
132199 +#define qm_out(reg, val) __qm_out(qm, REG_##reg, val)
132200 +
132201 +static u32 __qm_err_isr_read(struct qman *qm, enum qm_isr_reg n)
132202 +{
132203 + return __qm_in(qm, REG_ERR_ISR + (n << 2));
132204 +}
132205 +
132206 +static void __qm_err_isr_write(struct qman *qm, enum qm_isr_reg n, u32 val)
132207 +{
132208 + __qm_out(qm, REG_ERR_ISR + (n << 2), val);
132209 +}
132210 +
132211 +static void qm_set_dc(struct qman *qm, enum qm_dc_portal portal,
132212 + int ed, u8 sernd)
132213 +{
132214 + DPA_ASSERT(!ed || (portal == qm_dc_portal_fman0) ||
132215 + (portal == qm_dc_portal_fman1));
132216 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132217 + qm_out(DCP_CFG(portal), (ed ? 0x1000 : 0) | (sernd & 0x3ff));
132218 + else
132219 + qm_out(DCP_CFG(portal), (ed ? 0x100 : 0) | (sernd & 0x1f));
132220 +}
132221 +
132222 +static void qm_set_wq_scheduling(struct qman *qm, enum qm_wq_class wq_class,
132223 + u8 cs_elev, u8 csw2, u8 csw3, u8 csw4, u8 csw5,
132224 + u8 csw6, u8 csw7)
132225 +{
132226 + qm_out(WQ_CS_CFG(wq_class), ((cs_elev & 0xff) << 24) |
132227 + ((csw2 & 0x7) << 20) | ((csw3 & 0x7) << 16) |
132228 + ((csw4 & 0x7) << 12) | ((csw5 & 0x7) << 8) |
132229 + ((csw6 & 0x7) << 4) | (csw7 & 0x7));
132230 +}
132231 +
132232 +static void qm_set_hid(struct qman *qm)
132233 +{
132234 + qm_out(HID_CFG, 0);
132235 +}
132236 +
132237 +static void qm_set_corenet_initiator(struct qman *qm)
132238 +{
132239 + qm_out(CI_SCHED_CFG,
132240 + 0x80000000 | /* write srcciv enable */
132241 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRCCIV << 24) |
132242 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRQ_W << 8) |
132243 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_RW_W << 4) |
132244 + CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W);
132245 +}
132246 +
132247 +static void qm_get_version(struct qman *qm, u16 *id, u8 *major, u8 *minor,
132248 + u8 *cfg)
132249 +{
132250 + u32 v = qm_in(IP_REV_1);
132251 + u32 v2 = qm_in(IP_REV_2);
132252 + *id = (v >> 16);
132253 + *major = (v >> 8) & 0xff;
132254 + *minor = v & 0xff;
132255 + *cfg = v2 & 0xff;
132256 +}
132257 +
132258 +static void qm_set_memory(struct qman *qm, enum qm_memory memory, u64 ba,
132259 + int enable, int prio, int stash, u32 size)
132260 +{
132261 + u32 offset = (memory == qm_memory_fqd) ? REG_FQD_BARE : REG_PFDR_BARE;
132262 + u32 exp = ilog2(size);
132263 + /* choke if size isn't within range */
132264 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
132265 + is_power_of_2(size));
132266 + /* choke if 'ba' has lower-alignment than 'size' */
132267 + DPA_ASSERT(!(ba & (size - 1)));
132268 + __qm_out(qm, offset, upper_32_bits(ba));
132269 + __qm_out(qm, offset + REG_offset_BAR, lower_32_bits(ba));
132270 + __qm_out(qm, offset + REG_offset_AR,
132271 + (enable ? 0x80000000 : 0) |
132272 + (prio ? 0x40000000 : 0) |
132273 + (stash ? 0x20000000 : 0) |
132274 + (exp - 1));
132275 +}
132276 +
132277 +static void qm_set_pfdr_threshold(struct qman *qm, u32 th, u8 k)
132278 +{
132279 + qm_out(PFDR_FP_LWIT, th & 0xffffff);
132280 + qm_out(PFDR_CFG, k);
132281 +}
132282 +
132283 +static void qm_set_sfdr_threshold(struct qman *qm, u16 th)
132284 +{
132285 + qm_out(SFDR_CFG, th & 0x3ff);
132286 +}
132287 +
132288 +static int qm_init_pfdr(struct qman *qm, u32 pfdr_start, u32 num)
132289 +{
132290 + u8 rslt = MCR_get_rslt(qm_in(MCR));
132291 +
132292 + DPA_ASSERT(pfdr_start && !(pfdr_start & 7) && !(num & 7) && num);
132293 + /* Make sure the command interface is 'idle' */
132294 + if (!MCR_rslt_idle(rslt))
132295 + panic("QMAN_MCR isn't idle");
132296 +
132297 + /* Write the MCR command params then the verb */
132298 + qm_out(MCP(0), pfdr_start);
132299 + /* TODO: remove this - it's a workaround for a model bug that is
132300 + * corrected in more recent versions. We use the workaround until
132301 + * everyone has upgraded. */
132302 + qm_out(MCP(1), (pfdr_start + num - 16));
132303 + lwsync();
132304 + qm_out(MCR, MCR_INIT_PFDR);
132305 + /* Poll for the result */
132306 + do {
132307 + rslt = MCR_get_rslt(qm_in(MCR));
132308 + } while (!MCR_rslt_idle(rslt));
132309 + if (MCR_rslt_ok(rslt))
132310 + return 0;
132311 + if (MCR_rslt_eaccess(rslt))
132312 + return -EACCES;
132313 + if (MCR_rslt_inval(rslt))
132314 + return -EINVAL;
132315 + pr_crit("Unexpected result from MCR_INIT_PFDR: %02x\n", rslt);
132316 + return -ENOSYS;
132317 +}
132318 +
132319 +/*****************/
132320 +/* Config driver */
132321 +/*****************/
132322 +
132323 +#define DEFAULT_FQD_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ)
132324 +#define DEFAULT_PFDR_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_PFDR_SZ)
132325 +
132326 +/* We support only one of these */
132327 +static struct qman *qm;
132328 +static struct device_node *qm_node;
132329 +
132330 +/* And this state belongs to 'qm'. It is set during fsl_qman_init(), but used
132331 + * during qman_init_ccsr(). */
132332 +static dma_addr_t fqd_a, pfdr_a;
132333 +static size_t fqd_sz = DEFAULT_FQD_SZ, pfdr_sz = DEFAULT_PFDR_SZ;
132334 +
132335 +static int qman_fqd(struct reserved_mem *rmem)
132336 +{
132337 + fqd_a = rmem->base;
132338 + fqd_sz = rmem->size;
132339 +
132340 + WARN_ON(!(fqd_a && fqd_sz));
132341 +
132342 + return 0;
132343 +}
132344 +RESERVEDMEM_OF_DECLARE(qman_fqd, "fsl,qman-fqd", qman_fqd);
132345 +
132346 +static int qman_pfdr(struct reserved_mem *rmem)
132347 +{
132348 + pfdr_a = rmem->base;
132349 + pfdr_sz = rmem->size;
132350 +
132351 + WARN_ON(!(pfdr_a && pfdr_sz));
132352 +
132353 + return 0;
132354 +}
132355 +RESERVEDMEM_OF_DECLARE(qman_fbpr, "fsl,qman-pfdr", qman_pfdr);
132356 +
132357 +size_t get_qman_fqd_size()
132358 +{
132359 + return fqd_sz;
132360 +}
132361 +
132362 +/* Parse the <name> property to extract the memory location and size and
132363 + * memblock_reserve() it. If it isn't supplied, memblock_alloc() the default
132364 + * size. Also flush this memory range from data cache so that QMAN originated
132365 + * transactions for this memory region could be marked non-coherent.
132366 + */
132367 +static __init int parse_mem_property(struct device_node *node, const char *name,
132368 + dma_addr_t *addr, size_t *sz, int zero)
132369 +{
132370 + int ret;
132371 +
132372 + /* If using a "zero-pma", don't try to zero it, even if you asked */
132373 + if (zero && of_find_property(node, "zero-pma", &ret)) {
132374 + pr_info(" it's a 'zero-pma', not zeroing from s/w\n");
132375 + zero = 0;
132376 + }
132377 +
132378 + if (zero) {
132379 + /* map as cacheable, non-guarded */
132380 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
132381 + void __iomem *tmpp = ioremap_cache(*addr, *sz);
132382 +#else
132383 + void __iomem *tmpp = ioremap(*addr, *sz);
132384 +#endif
132385 +
132386 + if (!tmpp)
132387 + return -ENOMEM;
132388 + memset_io(tmpp, 0, *sz);
132389 + flush_dcache_range((unsigned long)tmpp,
132390 + (unsigned long)tmpp + *sz);
132391 + iounmap(tmpp);
132392 + }
132393 +
132394 + return 0;
132395 +}
132396 +
132397 +/* TODO:
132398 + * - there is obviously no handling of errors,
132399 + * - the calls to qm_set_memory() hard-code the priority and CPC-stashing for
132400 + * both memory resources to zero.
132401 + */
132402 +static int __init fsl_qman_init(struct device_node *node)
132403 +{
132404 + struct resource res;
132405 + resource_size_t len;
132406 + u32 __iomem *regs;
132407 + const char *s;
132408 + int ret, standby = 0;
132409 + u16 id;
132410 + u8 major, minor, cfg;
132411 + ret = of_address_to_resource(node, 0, &res);
132412 + if (ret) {
132413 + pr_err("Can't get %s property '%s'\n", node->full_name, "reg");
132414 + return ret;
132415 + }
132416 + s = of_get_property(node, "fsl,hv-claimable", &ret);
132417 + if (s && !strcmp(s, "standby"))
132418 + standby = 1;
132419 + if (!standby) {
132420 + ret = parse_mem_property(node, "fsl,qman-fqd",
132421 + &fqd_a, &fqd_sz, 1);
132422 + pr_info("qman-fqd addr %pad size 0x%zx\n", &fqd_a, fqd_sz);
132423 + BUG_ON(ret);
132424 + ret = parse_mem_property(node, "fsl,qman-pfdr",
132425 + &pfdr_a, &pfdr_sz, 0);
132426 + pr_info("qman-pfdr addr %pad size 0x%zx\n", &pfdr_a, pfdr_sz);
132427 + BUG_ON(ret);
132428 + }
132429 + /* Global configuration */
132430 + len = resource_size(&res);
132431 + if (len != (unsigned long)len)
132432 + return -EINVAL;
132433 + regs = ioremap(res.start, (unsigned long)len);
132434 + qm = qm_create(regs);
132435 + qm_node = node;
132436 + qm_get_version(qm, &id, &major, &minor, &cfg);
132437 + pr_info("Qman ver:%04x,%02x,%02x,%02x\n", id, major, minor, cfg);
132438 + if (!qman_ip_rev) {
132439 + if ((major == 1) && (minor == 0)) {
132440 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
132441 + iounmap(regs);
132442 + return -ENODEV;
132443 + } else if ((major == 1) && (minor == 1))
132444 + qman_ip_rev = QMAN_REV11;
132445 + else if ((major == 1) && (minor == 2))
132446 + qman_ip_rev = QMAN_REV12;
132447 + else if ((major == 2) && (minor == 0))
132448 + qman_ip_rev = QMAN_REV20;
132449 + else if ((major == 3) && (minor == 0))
132450 + qman_ip_rev = QMAN_REV30;
132451 + else if ((major == 3) && (minor == 1))
132452 + qman_ip_rev = QMAN_REV31;
132453 + else if ((major == 3) && (minor == 2))
132454 + qman_ip_rev = QMAN_REV32;
132455 + else {
132456 + pr_warn("unknown Qman version, default to rev1.1\n");
132457 + qman_ip_rev = QMAN_REV11;
132458 + }
132459 + qman_ip_cfg = cfg;
132460 + }
132461 +
132462 + if (standby) {
132463 + pr_info(" -> in standby mode\n");
132464 + return 0;
132465 + }
132466 + return 0;
132467 +}
132468 +
132469 +int qman_have_ccsr(void)
132470 +{
132471 + return qm ? 1 : 0;
132472 +}
132473 +
132474 +__init int qman_init_early(void)
132475 +{
132476 + struct device_node *dn;
132477 + int ret;
132478 +
132479 + for_each_compatible_node(dn, NULL, "fsl,qman") {
132480 + if (qm)
132481 + pr_err("%s: only one 'fsl,qman' allowed\n",
132482 + dn->full_name);
132483 + else {
132484 + if (!of_device_is_available(dn))
132485 + continue;
132486 +
132487 + ret = fsl_qman_init(dn);
132488 + BUG_ON(ret);
132489 + }
132490 + }
132491 + return 0;
132492 +}
132493 +postcore_initcall_sync(qman_init_early);
132494 +
132495 +static void log_edata_bits(u32 bit_count)
132496 +{
132497 + u32 i, j, mask = 0xffffffff;
132498 +
132499 + pr_warn("Qman ErrInt, EDATA:\n");
132500 + i = bit_count/32;
132501 + if (bit_count%32) {
132502 + i++;
132503 + mask = ~(mask << bit_count%32);
132504 + }
132505 + j = 16-i;
132506 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)) & mask);
132507 + j++;
132508 + for (; j < 16; j++)
132509 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)));
132510 +}
132511 +
132512 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
132513 +{
132514 + union qman_ecir ecir_val;
132515 + union qman_eadr eadr_val;
132516 +
132517 + ecir_val.ecir_raw = qm_in(ECIR);
132518 + /* Is portal info valid */
132519 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
132520 + union qman_ecir2 ecir2_val;
132521 + ecir2_val.ecir2_raw = qm_in(ECIR2);
132522 + if (ecsr_val & PORTAL_ECSR_ERR) {
132523 + pr_warn("Qman ErrInt: %s id %d\n",
132524 + (ecir2_val.info.portal_type) ?
132525 + "DCP" : "SWP", ecir2_val.info.portal_num);
132526 + }
132527 + if (ecsr_val & (FQID_ECSR_ERR | QM_EIRQ_IECE)) {
132528 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
132529 + ecir_val.info.fqid);
132530 + }
132531 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
132532 + eadr_val.eadr_raw = qm_in(EADR);
132533 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
132534 + error_mdata[eadr_val.info_rev3.memid].txt,
132535 + error_mdata[eadr_val.info_rev3.memid].addr_mask
132536 + & eadr_val.info_rev3.eadr);
132537 + log_edata_bits(
132538 + error_mdata[eadr_val.info_rev3.memid].bits);
132539 + }
132540 + } else {
132541 + if (ecsr_val & PORTAL_ECSR_ERR) {
132542 + pr_warn("Qman ErrInt: %s id %d\n",
132543 + (ecir_val.info.portal_type) ?
132544 + "DCP" : "SWP", ecir_val.info.portal_num);
132545 + }
132546 + if (ecsr_val & FQID_ECSR_ERR) {
132547 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
132548 + ecir_val.info.fqid);
132549 + }
132550 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
132551 + eadr_val.eadr_raw = qm_in(EADR);
132552 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
132553 + error_mdata[eadr_val.info.memid].txt,
132554 + error_mdata[eadr_val.info.memid].addr_mask
132555 + & eadr_val.info.eadr);
132556 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
132557 + }
132558 + }
132559 +}
132560 +
132561 +/* Qman interrupt handler */
132562 +static irqreturn_t qman_isr(int irq, void *ptr)
132563 +{
132564 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
132565 +
132566 + ier_val = qm_err_isr_enable_read(qm);
132567 + isr_val = qm_err_isr_status_read(qm);
132568 + ecsr_val = qm_in(ECSR);
132569 + isr_mask = isr_val & ier_val;
132570 +
132571 + if (!isr_mask)
132572 + return IRQ_NONE;
132573 + for (i = 0; i < QMAN_HWE_COUNT; i++) {
132574 + if (qman_hwerr_txts[i].mask & isr_mask) {
132575 + pr_warn("Qman ErrInt: %s\n", qman_hwerr_txts[i].txt);
132576 + if (qman_hwerr_txts[i].mask & ecsr_val) {
132577 + log_additional_error_info(isr_mask, ecsr_val);
132578 + /* Re-arm error capture registers */
132579 + qm_out(ECSR, ecsr_val);
132580 + }
132581 + if (qman_hwerr_txts[i].mask & QMAN_ERRS_TO_UNENABLE) {
132582 + pr_devel("Qman un-enabling error 0x%x\n",
132583 + qman_hwerr_txts[i].mask);
132584 + ier_val &= ~qman_hwerr_txts[i].mask;
132585 + qm_err_isr_enable_write(qm, ier_val);
132586 + }
132587 + }
132588 + }
132589 + qm_err_isr_status_clear(qm, isr_val);
132590 + return IRQ_HANDLED;
132591 +}
132592 +
132593 +static int __bind_irq(void)
132594 +{
132595 + int ret, err_irq;
132596 +
132597 + err_irq = of_irq_to_resource(qm_node, 0, NULL);
132598 + if (err_irq == 0) {
132599 + pr_info("Can't get %s property '%s'\n", qm_node->full_name,
132600 + "interrupts");
132601 + return -ENODEV;
132602 + }
132603 + ret = request_irq(err_irq, qman_isr, IRQF_SHARED, "qman-err", qm_node);
132604 + if (ret) {
132605 + pr_err("request_irq() failed %d for '%s'\n", ret,
132606 + qm_node->full_name);
132607 + return -ENODEV;
132608 + }
132609 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
132610 + * to resource allocation during driver init). */
132611 + qm_err_isr_status_clear(qm, 0xffffffff);
132612 + /* Enable Error Interrupts */
132613 + qm_err_isr_enable_write(qm, 0xffffffff);
132614 + return 0;
132615 +}
132616 +
132617 +int qman_init_ccsr(struct device_node *node)
132618 +{
132619 + int ret;
132620 + if (!qman_have_ccsr())
132621 + return 0;
132622 + if (node != qm_node)
132623 + return -EINVAL;
132624 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
132625 + /* TEMP for LS1043 : should be done in uboot */
132626 + qm_out(QCSP_BARE, 0x5);
132627 + qm_out(QCSP_BAR, 0x0);
132628 +#endif
132629 + /* FQD memory */
132630 + qm_set_memory(qm, qm_memory_fqd, fqd_a, 1, 0, 0, fqd_sz);
132631 + /* PFDR memory */
132632 + qm_set_memory(qm, qm_memory_pfdr, pfdr_a, 1, 0, 0, pfdr_sz);
132633 + qm_init_pfdr(qm, 8, pfdr_sz / 64 - 8);
132634 + /* thresholds */
132635 + qm_set_pfdr_threshold(qm, 512, 64);
132636 + qm_set_sfdr_threshold(qm, 128);
132637 + /* clear stale PEBI bit from interrupt status register */
132638 + qm_err_isr_status_clear(qm, QM_EIRQ_PEBI);
132639 + /* corenet initiator settings */
132640 + qm_set_corenet_initiator(qm);
132641 + /* HID settings */
132642 + qm_set_hid(qm);
132643 + /* Set scheduling weights to defaults */
132644 + for (ret = qm_wq_first; ret <= qm_wq_last; ret++)
132645 + qm_set_wq_scheduling(qm, ret, 0, 0, 0, 0, 0, 0, 0);
132646 + /* We are not prepared to accept ERNs for hardware enqueues */
132647 + qm_set_dc(qm, qm_dc_portal_fman0, 1, 0);
132648 + qm_set_dc(qm, qm_dc_portal_fman1, 1, 0);
132649 + /* Initialise Error Interrupt Handler */
132650 + ret = __bind_irq();
132651 + if (ret)
132652 + return ret;
132653 + return 0;
132654 +}
132655 +
132656 +#define LIO_CFG_LIODN_MASK 0x0fff0000
132657 +void qman_liodn_fixup(u16 channel)
132658 +{
132659 + static int done;
132660 + static u32 liodn_offset;
132661 + u32 before, after;
132662 + int idx = channel - QM_CHANNEL_SWPORTAL0;
132663 +
132664 + if (!qman_have_ccsr())
132665 + return;
132666 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132667 + before = qm_in(REV3_QCSP_LIO_CFG(idx));
132668 + else
132669 + before = qm_in(QCSP_LIO_CFG(idx));
132670 + if (!done) {
132671 + liodn_offset = before & LIO_CFG_LIODN_MASK;
132672 + done = 1;
132673 + return;
132674 + }
132675 + after = (before & (~LIO_CFG_LIODN_MASK)) | liodn_offset;
132676 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132677 + qm_out(REV3_QCSP_LIO_CFG(idx), after);
132678 + else
132679 + qm_out(QCSP_LIO_CFG(idx), after);
132680 +}
132681 +
132682 +#define IO_CFG_SDEST_MASK 0x00ff0000
132683 +int qman_set_sdest(u16 channel, unsigned int cpu_idx)
132684 +{
132685 + int idx = channel - QM_CHANNEL_SWPORTAL0;
132686 + u32 before, after;
132687 +
132688 + if (!qman_have_ccsr())
132689 + return -ENODEV;
132690 + if ((qman_ip_rev & 0xFF00) == QMAN_REV31) {
132691 + /* LS1043A - only one L2 cache */
132692 + cpu_idx = 0;
132693 + }
132694 +
132695 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
132696 + before = qm_in(REV3_QCSP_IO_CFG(idx));
132697 + /* Each pair of vcpu share the same SRQ(SDEST) */
132698 + cpu_idx /= 2;
132699 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
132700 + qm_out(REV3_QCSP_IO_CFG(idx), after);
132701 + } else {
132702 + before = qm_in(QCSP_IO_CFG(idx));
132703 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
132704 + qm_out(QCSP_IO_CFG(idx), after);
132705 + }
132706 + return 0;
132707 +}
132708 +
132709 +#define MISC_CFG_WPM_MASK 0x00000002
132710 +int qm_set_wpm(int wpm)
132711 +{
132712 + u32 before;
132713 + u32 after;
132714 +
132715 + if (!qman_have_ccsr())
132716 + return -ENODEV;
132717 +
132718 + before = qm_in(MISC_CFG);
132719 + after = (before & (~MISC_CFG_WPM_MASK)) | (wpm << 1);
132720 + qm_out(MISC_CFG, after);
132721 + return 0;
132722 +}
132723 +
132724 +int qm_get_wpm(int *wpm)
132725 +{
132726 + u32 before;
132727 +
132728 + if (!qman_have_ccsr())
132729 + return -ENODEV;
132730 +
132731 + before = qm_in(MISC_CFG);
132732 + *wpm = (before & MISC_CFG_WPM_MASK) >> 1;
132733 + return 0;
132734 +}
132735 +
132736 +/* CEETM_CFG_PRES register has PRES field which is calculated by:
132737 + * PRES = (2^22 / credit update reference period) * QMan clock period
132738 + * = (2^22 * 10^9)/ CONFIG_QMAN_CEETM_UPDATE_PERIOD) / qman_clk
132739 + */
132740 +
132741 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal)
132742 +{
132743 + u64 temp;
132744 + u16 pres;
132745 +
132746 + if (!qman_have_ccsr())
132747 + return -ENODEV;
132748 +
132749 + temp = 0x400000 * 100;
132750 + do_div(temp, CONFIG_QMAN_CEETM_UPDATE_PERIOD);
132751 + temp *= 10000000;
132752 + do_div(temp, qman_clk);
132753 + pres = (u16) temp;
132754 + qm_out(CEETM_CFG_IDX, portal);
132755 + qm_out(CEETM_CFG_PRES, pres);
132756 + return 0;
132757 +}
132758 +
132759 +int qman_ceetm_get_prescaler(u16 *pres)
132760 +{
132761 + if (!qman_have_ccsr())
132762 + return -ENODEV;
132763 + *pres = (u16)qm_in(CEETM_CFG_PRES);
132764 + return 0;
132765 +}
132766 +
132767 +#define DCP_CFG_CEETME_MASK 0xFFFF0000
132768 +#define QM_SP_ENABLE_CEETM(n) (0x80000000 >> (n))
132769 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
132770 +{
132771 + u32 dcp_cfg;
132772 +
132773 + if (!qman_have_ccsr())
132774 + return -ENODEV;
132775 +
132776 + dcp_cfg = qm_in(DCP_CFG(portal));
132777 + dcp_cfg |= QM_SP_ENABLE_CEETM(sub_portal);
132778 + qm_out(DCP_CFG(portal), dcp_cfg);
132779 + return 0;
132780 +}
132781 +
132782 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
132783 +{
132784 + u32 dcp_cfg;
132785 +
132786 + if (!qman_have_ccsr())
132787 + return -ENODEV;
132788 + dcp_cfg = qm_in(DCP_CFG(portal));
132789 + dcp_cfg &= ~(QM_SP_ENABLE_CEETM(sub_portal));
132790 + qm_out(DCP_CFG(portal), dcp_cfg);
132791 + return 0;
132792 +}
132793 +
132794 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num)
132795 +{
132796 + if (!qman_have_ccsr())
132797 + return -ENODEV;
132798 + *num = qm_in(CEETM_XSFDR_IN_USE);
132799 + return 0;
132800 +}
132801 +EXPORT_SYMBOL(qman_ceetm_get_xsfdr);
132802 +
132803 +#ifdef CONFIG_SYSFS
132804 +
132805 +#define DRV_NAME "fsl-qman"
132806 +#define DCP_MAX_ID 3
132807 +#define DCP_MIN_ID 0
132808 +
132809 +static ssize_t show_pfdr_fpc(struct device *dev,
132810 + struct device_attribute *dev_attr, char *buf)
132811 +{
132812 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_FPC));
132813 +};
132814 +
132815 +static ssize_t show_dlm_avg(struct device *dev,
132816 + struct device_attribute *dev_attr, char *buf)
132817 +{
132818 + u32 data;
132819 + int i;
132820 +
132821 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
132822 + return -EINVAL;
132823 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
132824 + return -EINVAL;
132825 + data = qm_in(DCP_DLM_AVG(i));
132826 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
132827 + (data & 0x000000ff)*390625);
132828 +};
132829 +
132830 +static ssize_t set_dlm_avg(struct device *dev,
132831 + struct device_attribute *dev_attr, const char *buf, size_t count)
132832 +{
132833 + unsigned long val;
132834 + int i;
132835 +
132836 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
132837 + return -EINVAL;
132838 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
132839 + return -EINVAL;
132840 + if (kstrtoul(buf, 0, &val)) {
132841 + dev_dbg(dev, "invalid input %s\n", buf);
132842 + return -EINVAL;
132843 + }
132844 + qm_out(DCP_DLM_AVG(i), val);
132845 + return count;
132846 +};
132847 +
132848 +static ssize_t show_pfdr_cfg(struct device *dev,
132849 + struct device_attribute *dev_attr, char *buf)
132850 +{
132851 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_CFG));
132852 +};
132853 +
132854 +static ssize_t set_pfdr_cfg(struct device *dev,
132855 + struct device_attribute *dev_attr, const char *buf, size_t count)
132856 +{
132857 + unsigned long val;
132858 +
132859 + if (kstrtoul(buf, 0, &val)) {
132860 + dev_dbg(dev, "invalid input %s\n", buf);
132861 + return -EINVAL;
132862 + }
132863 + qm_out(PFDR_CFG, val);
132864 + return count;
132865 +};
132866 +
132867 +static ssize_t show_sfdr_in_use(struct device *dev,
132868 + struct device_attribute *dev_attr, char *buf)
132869 +{
132870 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SFDR_IN_USE));
132871 +};
132872 +
132873 +static ssize_t show_idle_stat(struct device *dev,
132874 + struct device_attribute *dev_attr, char *buf)
132875 +{
132876 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(IDLE_STAT));
132877 +};
132878 +
132879 +static ssize_t show_ci_rlm_avg(struct device *dev,
132880 + struct device_attribute *dev_attr, char *buf)
132881 +{
132882 + u32 data = qm_in(CI_RLM_AVG);
132883 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
132884 + (data & 0x000000ff)*390625);
132885 +};
132886 +
132887 +static ssize_t set_ci_rlm_avg(struct device *dev,
132888 + struct device_attribute *dev_attr, const char *buf, size_t count)
132889 +{
132890 + unsigned long val;
132891 +
132892 + if (kstrtoul(buf, 0, &val)) {
132893 + dev_dbg(dev, "invalid input %s\n", buf);
132894 + return -EINVAL;
132895 + }
132896 + qm_out(CI_RLM_AVG, val);
132897 + return count;
132898 +};
132899 +
132900 +static ssize_t show_err_isr(struct device *dev,
132901 + struct device_attribute *dev_attr, char *buf)
132902 +{
132903 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", qm_in(ERR_ISR));
132904 +};
132905 +
132906 +#define SBEC_MAX_ID 14
132907 +#define SBEC_MIN_ID 0
132908 +
132909 +static ssize_t show_sbec(struct device *dev,
132910 + struct device_attribute *dev_attr, char *buf)
132911 +{
132912 + int i;
132913 +
132914 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
132915 + return -EINVAL;
132916 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
132917 + return -EINVAL;
132918 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SBEC(i)));
132919 +};
132920 +
132921 +static DEVICE_ATTR(pfdr_fpc, S_IRUSR, show_pfdr_fpc, NULL);
132922 +static DEVICE_ATTR(pfdr_cfg, S_IRUSR, show_pfdr_cfg, set_pfdr_cfg);
132923 +static DEVICE_ATTR(idle_stat, S_IRUSR, show_idle_stat, NULL);
132924 +static DEVICE_ATTR(ci_rlm_avg, (S_IRUSR|S_IWUSR),
132925 + show_ci_rlm_avg, set_ci_rlm_avg);
132926 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
132927 +static DEVICE_ATTR(sfdr_in_use, S_IRUSR, show_sfdr_in_use, NULL);
132928 +
132929 +static DEVICE_ATTR(dcp0_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132930 +static DEVICE_ATTR(dcp1_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132931 +static DEVICE_ATTR(dcp2_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132932 +static DEVICE_ATTR(dcp3_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132933 +
132934 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
132935 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
132936 +static DEVICE_ATTR(sbec_2, S_IRUSR, show_sbec, NULL);
132937 +static DEVICE_ATTR(sbec_3, S_IRUSR, show_sbec, NULL);
132938 +static DEVICE_ATTR(sbec_4, S_IRUSR, show_sbec, NULL);
132939 +static DEVICE_ATTR(sbec_5, S_IRUSR, show_sbec, NULL);
132940 +static DEVICE_ATTR(sbec_6, S_IRUSR, show_sbec, NULL);
132941 +static DEVICE_ATTR(sbec_7, S_IRUSR, show_sbec, NULL);
132942 +static DEVICE_ATTR(sbec_8, S_IRUSR, show_sbec, NULL);
132943 +static DEVICE_ATTR(sbec_9, S_IRUSR, show_sbec, NULL);
132944 +static DEVICE_ATTR(sbec_10, S_IRUSR, show_sbec, NULL);
132945 +static DEVICE_ATTR(sbec_11, S_IRUSR, show_sbec, NULL);
132946 +static DEVICE_ATTR(sbec_12, S_IRUSR, show_sbec, NULL);
132947 +static DEVICE_ATTR(sbec_13, S_IRUSR, show_sbec, NULL);
132948 +static DEVICE_ATTR(sbec_14, S_IRUSR, show_sbec, NULL);
132949 +
132950 +static struct attribute *qman_dev_attributes[] = {
132951 + &dev_attr_pfdr_fpc.attr,
132952 + &dev_attr_pfdr_cfg.attr,
132953 + &dev_attr_idle_stat.attr,
132954 + &dev_attr_ci_rlm_avg.attr,
132955 + &dev_attr_err_isr.attr,
132956 + &dev_attr_dcp0_dlm_avg.attr,
132957 + &dev_attr_dcp1_dlm_avg.attr,
132958 + &dev_attr_dcp2_dlm_avg.attr,
132959 + &dev_attr_dcp3_dlm_avg.attr,
132960 + /* sfdr_in_use will be added if necessary */
132961 + NULL
132962 +};
132963 +
132964 +static struct attribute *qman_dev_ecr_attributes[] = {
132965 + &dev_attr_sbec_0.attr,
132966 + &dev_attr_sbec_1.attr,
132967 + &dev_attr_sbec_2.attr,
132968 + &dev_attr_sbec_3.attr,
132969 + &dev_attr_sbec_4.attr,
132970 + &dev_attr_sbec_5.attr,
132971 + &dev_attr_sbec_6.attr,
132972 + &dev_attr_sbec_7.attr,
132973 + &dev_attr_sbec_8.attr,
132974 + &dev_attr_sbec_9.attr,
132975 + &dev_attr_sbec_10.attr,
132976 + &dev_attr_sbec_11.attr,
132977 + &dev_attr_sbec_12.attr,
132978 + &dev_attr_sbec_13.attr,
132979 + &dev_attr_sbec_14.attr,
132980 + NULL
132981 +};
132982 +
132983 +/* root level */
132984 +static const struct attribute_group qman_dev_attr_grp = {
132985 + .name = NULL,
132986 + .attrs = qman_dev_attributes
132987 +};
132988 +static const struct attribute_group qman_dev_ecr_grp = {
132989 + .name = "error_capture",
132990 + .attrs = qman_dev_ecr_attributes
132991 +};
132992 +
132993 +static int of_fsl_qman_remove(struct platform_device *ofdev)
132994 +{
132995 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
132996 + return 0;
132997 +};
132998 +
132999 +static int of_fsl_qman_probe(struct platform_device *ofdev)
133000 +{
133001 + int ret;
133002 +
133003 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133004 + if (ret)
133005 + goto done;
133006 + ret = sysfs_add_file_to_group(&ofdev->dev.kobj,
133007 + &dev_attr_sfdr_in_use.attr, qman_dev_attr_grp.name);
133008 + if (ret)
133009 + goto del_group_0;
133010 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_ecr_grp);
133011 + if (ret)
133012 + goto del_group_0;
133013 +
133014 + goto done;
133015 +
133016 +del_group_0:
133017 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133018 +done:
133019 + if (ret)
133020 + dev_err(&ofdev->dev,
133021 + "Cannot create dev attributes ret=%d\n", ret);
133022 + return ret;
133023 +};
133024 +
133025 +static struct of_device_id of_fsl_qman_ids[] = {
133026 + {
133027 + .compatible = "fsl,qman",
133028 + },
133029 + {}
133030 +};
133031 +MODULE_DEVICE_TABLE(of, of_fsl_qman_ids);
133032 +
133033 +#ifdef CONFIG_SUSPEND
133034 +
133035 +static u32 saved_isdr;
133036 +static int qman_pm_suspend_noirq(struct device *dev)
133037 +{
133038 + uint32_t idle_state;
133039 +
133040 + suspend_unused_qportal();
133041 + /* save isdr, disable all, clear isr */
133042 + saved_isdr = qm_err_isr_disable_read(qm);
133043 + qm_err_isr_disable_write(qm, 0xffffffff);
133044 + qm_err_isr_status_clear(qm, 0xffffffff);
133045 + idle_state = qm_in(IDLE_STAT);
133046 + if (!(idle_state & 0x1)) {
133047 + pr_err("Qman not idle 0x%x aborting\n", idle_state);
133048 + qm_err_isr_disable_write(qm, saved_isdr);
133049 + resume_unused_qportal();
133050 + return -EBUSY;
133051 + }
133052 +#ifdef CONFIG_PM_DEBUG
133053 + pr_info("Qman suspend code, IDLE_STAT = 0x%x\n", idle_state);
133054 +#endif
133055 + return 0;
133056 +}
133057 +
133058 +static int qman_pm_resume_noirq(struct device *dev)
133059 +{
133060 + /* restore isdr */
133061 + qm_err_isr_disable_write(qm, saved_isdr);
133062 + resume_unused_qportal();
133063 + return 0;
133064 +}
133065 +#else
133066 +#define qman_pm_suspend_noirq NULL
133067 +#define qman_pm_resume_noirq NULL
133068 +#endif
133069 +
133070 +static const struct dev_pm_ops qman_pm_ops = {
133071 + .suspend_noirq = qman_pm_suspend_noirq,
133072 + .resume_noirq = qman_pm_resume_noirq,
133073 +};
133074 +
133075 +static struct platform_driver of_fsl_qman_driver = {
133076 + .driver = {
133077 + .owner = THIS_MODULE,
133078 + .name = DRV_NAME,
133079 + .of_match_table = of_fsl_qman_ids,
133080 + .pm = &qman_pm_ops,
133081 + },
133082 + .probe = of_fsl_qman_probe,
133083 + .remove = of_fsl_qman_remove,
133084 +};
133085 +
133086 +static int qman_ctrl_init(void)
133087 +{
133088 + return platform_driver_register(&of_fsl_qman_driver);
133089 +}
133090 +
133091 +static void qman_ctrl_exit(void)
133092 +{
133093 + platform_driver_unregister(&of_fsl_qman_driver);
133094 +}
133095 +
133096 +module_init(qman_ctrl_init);
133097 +module_exit(qman_ctrl_exit);
133098 +
133099 +#endif /* CONFIG_SYSFS */
133100 --- /dev/null
133101 +++ b/drivers/staging/fsl_qbman/qman_debugfs.c
133102 @@ -0,0 +1,1594 @@
133103 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
133104 + *
133105 + * Redistribution and use in source and binary forms, with or without
133106 + * modification, are permitted provided that the following conditions are met:
133107 + * * Redistributions of source code must retain the above copyright
133108 + * notice, this list of conditions and the following disclaimer.
133109 + * * Redistributions in binary form must reproduce the above copyright
133110 + * notice, this list of conditions and the following disclaimer in the
133111 + * documentation and/or other materials provided with the distribution.
133112 + * * Neither the name of Freescale Semiconductor nor the
133113 + * names of its contributors may be used to endorse or promote products
133114 + * derived from this software without specific prior written permission.
133115 + *
133116 + *
133117 + * ALTERNATIVELY, this software may be distributed under the terms of the
133118 + * GNU General Public License ("GPL") as published by the Free Software
133119 + * Foundation, either version 2 of that License or (at your option) any
133120 + * later version.
133121 + *
133122 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
133123 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
133124 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
133125 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
133126 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
133127 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
133128 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
133129 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
133130 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
133131 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133132 + */
133133 +#include "qman_private.h"
133134 +
133135 +#define MAX_FQID (0x00ffffff)
133136 +#define QM_FQD_BLOCK_SIZE 64
133137 +#define QM_FQD_AR (0xC10)
133138 +
133139 +static u32 fqid_max;
133140 +static u64 qman_ccsr_start;
133141 +static u64 qman_ccsr_size;
133142 +
133143 +static const char * const state_txt[] = {
133144 + "Out of Service",
133145 + "Retired",
133146 + "Tentatively Scheduled",
133147 + "Truly Scheduled",
133148 + "Parked",
133149 + "Active, Active Held or Held Suspended",
133150 + "Unknown State 6",
133151 + "Unknown State 7",
133152 + NULL,
133153 +};
133154 +
133155 +static const u8 fqd_states[] = {
133156 + QM_MCR_NP_STATE_OOS, QM_MCR_NP_STATE_RETIRED, QM_MCR_NP_STATE_TEN_SCHED,
133157 + QM_MCR_NP_STATE_TRU_SCHED, QM_MCR_NP_STATE_PARKED,
133158 + QM_MCR_NP_STATE_ACTIVE};
133159 +
133160 +struct mask_to_text {
133161 + u16 mask;
133162 + const char *txt;
133163 +};
133164 +
133165 +struct mask_filter_s {
133166 + u16 mask;
133167 + u8 filter;
133168 +};
133169 +
133170 +static const struct mask_filter_s mask_filter[] = {
133171 + {QM_FQCTRL_PREFERINCACHE, 0},
133172 + {QM_FQCTRL_PREFERINCACHE, 1},
133173 + {QM_FQCTRL_HOLDACTIVE, 0},
133174 + {QM_FQCTRL_HOLDACTIVE, 1},
133175 + {QM_FQCTRL_AVOIDBLOCK, 0},
133176 + {QM_FQCTRL_AVOIDBLOCK, 1},
133177 + {QM_FQCTRL_FORCESFDR, 0},
133178 + {QM_FQCTRL_FORCESFDR, 1},
133179 + {QM_FQCTRL_CPCSTASH, 0},
133180 + {QM_FQCTRL_CPCSTASH, 1},
133181 + {QM_FQCTRL_CTXASTASHING, 0},
133182 + {QM_FQCTRL_CTXASTASHING, 1},
133183 + {QM_FQCTRL_ORP, 0},
133184 + {QM_FQCTRL_ORP, 1},
133185 + {QM_FQCTRL_TDE, 0},
133186 + {QM_FQCTRL_TDE, 1},
133187 + {QM_FQCTRL_CGE, 0},
133188 + {QM_FQCTRL_CGE, 1}
133189 +};
133190 +
133191 +static const struct mask_to_text fq_ctrl_text_list[] = {
133192 + {
133193 + .mask = QM_FQCTRL_PREFERINCACHE,
133194 + .txt = "Prefer in cache",
133195 + },
133196 + {
133197 + .mask = QM_FQCTRL_HOLDACTIVE,
133198 + .txt = "Hold active in portal",
133199 + },
133200 + {
133201 + .mask = QM_FQCTRL_AVOIDBLOCK,
133202 + .txt = "Avoid Blocking",
133203 + },
133204 + {
133205 + .mask = QM_FQCTRL_FORCESFDR,
133206 + .txt = "High-priority SFDRs",
133207 + },
133208 + {
133209 + .mask = QM_FQCTRL_CPCSTASH,
133210 + .txt = "CPC Stash Enable",
133211 + },
133212 + {
133213 + .mask = QM_FQCTRL_CTXASTASHING,
133214 + .txt = "Context-A stashing",
133215 + },
133216 + {
133217 + .mask = QM_FQCTRL_ORP,
133218 + .txt = "ORP Enable",
133219 + },
133220 + {
133221 + .mask = QM_FQCTRL_TDE,
133222 + .txt = "Tail-Drop Enable",
133223 + },
133224 + {
133225 + .mask = QM_FQCTRL_CGE,
133226 + .txt = "Congestion Group Enable",
133227 + },
133228 + {
133229 + .mask = 0,
133230 + .txt = NULL,
133231 + }
133232 +};
133233 +
133234 +static const char *get_fqd_ctrl_text(u16 mask)
133235 +{
133236 + int i = 0;
133237 +
133238 + while (fq_ctrl_text_list[i].txt != NULL) {
133239 + if (fq_ctrl_text_list[i].mask == mask)
133240 + return fq_ctrl_text_list[i].txt;
133241 + i++;
133242 + }
133243 + return NULL;
133244 +}
133245 +
133246 +static const struct mask_to_text stashing_text_list[] = {
133247 + {
133248 + .mask = QM_STASHING_EXCL_CTX,
133249 + .txt = "FQ Ctx Stash"
133250 + },
133251 + {
133252 + .mask = QM_STASHING_EXCL_DATA,
133253 + .txt = "Frame Data Stash",
133254 + },
133255 + {
133256 + .mask = QM_STASHING_EXCL_ANNOTATION,
133257 + .txt = "Frame Annotation Stash",
133258 + },
133259 + {
133260 + .mask = 0,
133261 + .txt = NULL,
133262 + },
133263 +};
133264 +
133265 +static int user_input_convert(const char __user *user_buf, size_t count,
133266 + unsigned long *val)
133267 +{
133268 + char buf[12];
133269 +
133270 + if (count > sizeof(buf) - 1)
133271 + return -EINVAL;
133272 + if (copy_from_user(buf, user_buf, count))
133273 + return -EFAULT;
133274 + buf[count] = '\0';
133275 + if (kstrtoul(buf, 0, val))
133276 + return -EINVAL;
133277 + return 0;
133278 +}
133279 +
133280 +struct line_buffer_fq {
133281 + u32 buf[8];
133282 + u32 buf_cnt;
133283 + int line_cnt;
133284 +};
133285 +
133286 +static void add_to_line_buffer(struct line_buffer_fq *line_buf, u32 fqid,
133287 + struct seq_file *file)
133288 +{
133289 + line_buf->buf[line_buf->buf_cnt] = fqid;
133290 + line_buf->buf_cnt++;
133291 + if (line_buf->buf_cnt == 8) {
133292 + /* Buffer is full, flush it */
133293 + if (line_buf->line_cnt != 0)
133294 + seq_puts(file, ",\n");
133295 + seq_printf(file, "0x%06x,0x%06x,0x%06x,0x%06x,0x%06x,"
133296 + "0x%06x,0x%06x,0x%06x",
133297 + line_buf->buf[0], line_buf->buf[1], line_buf->buf[2],
133298 + line_buf->buf[3], line_buf->buf[4], line_buf->buf[5],
133299 + line_buf->buf[6], line_buf->buf[7]);
133300 + line_buf->buf_cnt = 0;
133301 + line_buf->line_cnt++;
133302 + }
133303 +}
133304 +
133305 +static void flush_line_buffer(struct line_buffer_fq *line_buf,
133306 + struct seq_file *file)
133307 +{
133308 + if (line_buf->buf_cnt) {
133309 + int y = 0;
133310 + if (line_buf->line_cnt != 0)
133311 + seq_puts(file, ",\n");
133312 + while (y != line_buf->buf_cnt) {
133313 + if (y+1 == line_buf->buf_cnt)
133314 + seq_printf(file, "0x%06x", line_buf->buf[y]);
133315 + else
133316 + seq_printf(file, "0x%06x,", line_buf->buf[y]);
133317 + y++;
133318 + }
133319 + line_buf->line_cnt++;
133320 + }
133321 + if (line_buf->line_cnt)
133322 + seq_putc(file, '\n');
133323 +}
133324 +
133325 +static struct dentry *dfs_root; /* debugfs root directory */
133326 +
133327 +/*******************************************************************************
133328 + * Query Frame Queue Non Programmable Fields
133329 + ******************************************************************************/
133330 +struct query_fq_np_fields_data_s {
133331 + u32 fqid;
133332 +};
133333 +static struct query_fq_np_fields_data_s query_fq_np_fields_data = {
133334 + .fqid = 1,
133335 +};
133336 +
133337 +static int query_fq_np_fields_show(struct seq_file *file, void *offset)
133338 +{
133339 + int ret;
133340 + struct qm_mcr_queryfq_np np;
133341 + struct qman_fq fq;
133342 +
133343 + fq.fqid = query_fq_np_fields_data.fqid;
133344 + ret = qman_query_fq_np(&fq, &np);
133345 + if (ret)
133346 + return ret;
133347 + /* Print state */
133348 + seq_printf(file, "Query FQ Non Programmable Fields Result fqid 0x%x\n",
133349 + fq.fqid);
133350 + seq_printf(file, " force eligible pending: %s\n",
133351 + (np.state & QM_MCR_NP_STATE_FE) ? "yes" : "no");
133352 + seq_printf(file, " retirement pending: %s\n",
133353 + (np.state & QM_MCR_NP_STATE_R) ? "yes" : "no");
133354 + seq_printf(file, " state: %s\n",
133355 + state_txt[np.state & QM_MCR_NP_STATE_MASK]);
133356 + seq_printf(file, " fq_link: 0x%x\n", np.fqd_link);
133357 + seq_printf(file, " odp_seq: %u\n", np.odp_seq);
133358 + seq_printf(file, " orp_nesn: %u\n", np.orp_nesn);
133359 + seq_printf(file, " orp_ea_hseq: %u\n", np.orp_ea_hseq);
133360 + seq_printf(file, " orp_ea_tseq: %u\n", np.orp_ea_tseq);
133361 + seq_printf(file, " orp_ea_hptr: 0x%x\n", np.orp_ea_hptr);
133362 + seq_printf(file, " orp_ea_tptr: 0x%x\n", np.orp_ea_tptr);
133363 + seq_printf(file, " pfdr_hptr: 0x%x\n", np.pfdr_hptr);
133364 + seq_printf(file, " pfdr_tptr: 0x%x\n", np.pfdr_tptr);
133365 + seq_printf(file, " is: ics_surp contains a %s\n",
133366 + (np.is) ? "deficit" : "surplus");
133367 + seq_printf(file, " ics_surp: %u\n", np.ics_surp);
133368 + seq_printf(file, " byte_cnt: %u\n", np.byte_cnt);
133369 + seq_printf(file, " frm_cnt: %u\n", np.frm_cnt);
133370 + seq_printf(file, " ra1_sfdr: 0x%x\n", np.ra1_sfdr);
133371 + seq_printf(file, " ra2_sfdr: 0x%x\n", np.ra2_sfdr);
133372 + seq_printf(file, " od1_sfdr: 0x%x\n", np.od1_sfdr);
133373 + seq_printf(file, " od2_sfdr: 0x%x\n", np.od2_sfdr);
133374 + seq_printf(file, " od3_sfdr: 0x%x\n", np.od3_sfdr);
133375 + return 0;
133376 +}
133377 +
133378 +static int query_fq_np_fields_open(struct inode *inode,
133379 + struct file *file)
133380 +{
133381 + return single_open(file, query_fq_np_fields_show, NULL);
133382 +}
133383 +
133384 +static ssize_t query_fq_np_fields_write(struct file *f,
133385 + const char __user *buf, size_t count, loff_t *off)
133386 +{
133387 + int ret;
133388 + unsigned long val;
133389 +
133390 + ret = user_input_convert(buf, count, &val);
133391 + if (ret)
133392 + return ret;
133393 + if (val > MAX_FQID)
133394 + return -EINVAL;
133395 + query_fq_np_fields_data.fqid = (u32)val;
133396 + return count;
133397 +}
133398 +
133399 +static const struct file_operations query_fq_np_fields_fops = {
133400 + .owner = THIS_MODULE,
133401 + .open = query_fq_np_fields_open,
133402 + .read = seq_read,
133403 + .write = query_fq_np_fields_write,
133404 + .release = single_release,
133405 +};
133406 +
133407 +/*******************************************************************************
133408 + * Frame Queue Programmable Fields
133409 + ******************************************************************************/
133410 +struct query_fq_fields_data_s {
133411 + u32 fqid;
133412 +};
133413 +
133414 +static struct query_fq_fields_data_s query_fq_fields_data = {
133415 + .fqid = 1,
133416 +};
133417 +
133418 +static int query_fq_fields_show(struct seq_file *file, void *offset)
133419 +{
133420 + int ret;
133421 + struct qm_fqd fqd;
133422 + struct qman_fq fq;
133423 + int i = 0;
133424 +
133425 + memset(&fqd, 0, sizeof(struct qm_fqd));
133426 + fq.fqid = query_fq_fields_data.fqid;
133427 + ret = qman_query_fq(&fq, &fqd);
133428 + if (ret)
133429 + return ret;
133430 + seq_printf(file, "Query FQ Programmable Fields Result fqid 0x%x\n",
133431 + fq.fqid);
133432 + seq_printf(file, " orprws: %u\n", fqd.orprws);
133433 + seq_printf(file, " oa: %u\n", fqd.oa);
133434 + seq_printf(file, " olws: %u\n", fqd.olws);
133435 +
133436 + seq_printf(file, " cgid: %u\n", fqd.cgid);
133437 +
133438 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) == 0)
133439 + seq_puts(file, " fq_ctrl: None\n");
133440 + else {
133441 + i = 0;
133442 + seq_puts(file, " fq_ctrl:\n");
133443 + while (fq_ctrl_text_list[i].txt != NULL) {
133444 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
133445 + fq_ctrl_text_list[i].mask)
133446 + seq_printf(file, " %s\n",
133447 + fq_ctrl_text_list[i].txt);
133448 + i++;
133449 + }
133450 + }
133451 + seq_printf(file, " dest_channel: %u\n", fqd.dest.channel);
133452 + seq_printf(file, " dest_wq: %u\n", fqd.dest.wq);
133453 + seq_printf(file, " ics_cred: %u\n", fqd.ics_cred);
133454 + seq_printf(file, " td_mant: %u\n", fqd.td.mant);
133455 + seq_printf(file, " td_exp: %u\n", fqd.td.exp);
133456 +
133457 + seq_printf(file, " ctx_b: 0x%x\n", fqd.context_b);
133458 +
133459 + seq_printf(file, " ctx_a: 0x%llx\n", qm_fqd_stashing_get64(&fqd));
133460 + /* Any stashing configured */
133461 + if ((fqd.context_a.stashing.exclusive & 0x7) == 0)
133462 + seq_puts(file, " ctx_a_stash_exclusive: None\n");
133463 + else {
133464 + seq_puts(file, " ctx_a_stash_exclusive:\n");
133465 + i = 0;
133466 + while (stashing_text_list[i].txt != NULL) {
133467 + if ((fqd.fq_ctrl & 0x7) & stashing_text_list[i].mask)
133468 + seq_printf(file, " %s\n",
133469 + stashing_text_list[i].txt);
133470 + i++;
133471 + }
133472 + }
133473 + seq_printf(file, " ctx_a_stash_annotation_cl: %u\n",
133474 + fqd.context_a.stashing.annotation_cl);
133475 + seq_printf(file, " ctx_a_stash_data_cl: %u\n",
133476 + fqd.context_a.stashing.data_cl);
133477 + seq_printf(file, " ctx_a_stash_context_cl: %u\n",
133478 + fqd.context_a.stashing.context_cl);
133479 + return 0;
133480 +}
133481 +
133482 +static int query_fq_fields_open(struct inode *inode,
133483 + struct file *file)
133484 +{
133485 + return single_open(file, query_fq_fields_show, NULL);
133486 +}
133487 +
133488 +static ssize_t query_fq_fields_write(struct file *f,
133489 + const char __user *buf, size_t count, loff_t *off)
133490 +{
133491 + int ret;
133492 + unsigned long val;
133493 +
133494 + ret = user_input_convert(buf, count, &val);
133495 + if (ret)
133496 + return ret;
133497 + if (val > MAX_FQID)
133498 + return -EINVAL;
133499 + query_fq_fields_data.fqid = (u32)val;
133500 + return count;
133501 +}
133502 +
133503 +static const struct file_operations query_fq_fields_fops = {
133504 + .owner = THIS_MODULE,
133505 + .open = query_fq_fields_open,
133506 + .read = seq_read,
133507 + .write = query_fq_fields_write,
133508 + .release = single_release,
133509 +};
133510 +
133511 +/*******************************************************************************
133512 + * Query WQ lengths
133513 + ******************************************************************************/
133514 +struct query_wq_lengths_data_s {
133515 + union {
133516 + u16 channel_wq; /* ignores wq (3 lsbits) */
133517 + struct {
133518 + u16 id:13; /* qm_channel */
133519 + u16 __reserved:3;
133520 + } __packed channel;
133521 + };
133522 +};
133523 +static struct query_wq_lengths_data_s query_wq_lengths_data;
133524 +static int query_wq_lengths_show(struct seq_file *file, void *offset)
133525 +{
133526 + int ret;
133527 + struct qm_mcr_querywq wq;
133528 + int i;
133529 +
133530 + memset(&wq, 0, sizeof(struct qm_mcr_querywq));
133531 + wq.channel.id = query_wq_lengths_data.channel.id;
133532 + ret = qman_query_wq(0, &wq);
133533 + if (ret)
133534 + return ret;
133535 + seq_printf(file, "Query Result For Channel: 0x%x\n", wq.channel.id);
133536 + for (i = 0; i < 8; i++)
133537 + /* mask out upper 4 bits since they are not part of length */
133538 + seq_printf(file, " wq%d_len : %u\n", i, wq.wq_len[i] & 0x0fff);
133539 + return 0;
133540 +}
133541 +
133542 +static int query_wq_lengths_open(struct inode *inode,
133543 + struct file *file)
133544 +{
133545 + return single_open(file, query_wq_lengths_show, NULL);
133546 +}
133547 +
133548 +static ssize_t query_wq_lengths_write(struct file *f,
133549 + const char __user *buf, size_t count, loff_t *off)
133550 +{
133551 + int ret;
133552 + unsigned long val;
133553 +
133554 + ret = user_input_convert(buf, count, &val);
133555 + if (ret)
133556 + return ret;
133557 + if (val > 0xfff8)
133558 + return -EINVAL;
133559 + query_wq_lengths_data.channel.id = (u16)val;
133560 + return count;
133561 +}
133562 +
133563 +static const struct file_operations query_wq_lengths_fops = {
133564 + .owner = THIS_MODULE,
133565 + .open = query_wq_lengths_open,
133566 + .read = seq_read,
133567 + .write = query_wq_lengths_write,
133568 + .release = single_release,
133569 +};
133570 +
133571 +/*******************************************************************************
133572 + * Query CGR
133573 + ******************************************************************************/
133574 +struct query_cgr_s {
133575 + u8 cgid;
133576 +};
133577 +static struct query_cgr_s query_cgr_data;
133578 +
133579 +static int query_cgr_show(struct seq_file *file, void *offset)
133580 +{
133581 + int ret;
133582 + struct qm_mcr_querycgr cgrd;
133583 + struct qman_cgr cgr;
133584 + int i, j;
133585 + u32 mask;
133586 +
133587 + memset(&cgr, 0, sizeof(cgr));
133588 + memset(&cgrd, 0, sizeof(cgrd));
133589 + cgr.cgrid = query_cgr_data.cgid;
133590 + ret = qman_query_cgr(&cgr, &cgrd);
133591 + if (ret)
133592 + return ret;
133593 + seq_printf(file, "Query CGR id 0x%x\n", cgr.cgrid);
133594 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133595 + cgrd.cgr.wr_parm_g.MA, cgrd.cgr.wr_parm_g.Mn,
133596 + cgrd.cgr.wr_parm_g.SA, cgrd.cgr.wr_parm_g.Sn,
133597 + cgrd.cgr.wr_parm_g.Pn);
133598 +
133599 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133600 + cgrd.cgr.wr_parm_y.MA, cgrd.cgr.wr_parm_y.Mn,
133601 + cgrd.cgr.wr_parm_y.SA, cgrd.cgr.wr_parm_y.Sn,
133602 + cgrd.cgr.wr_parm_y.Pn);
133603 +
133604 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133605 + cgrd.cgr.wr_parm_r.MA, cgrd.cgr.wr_parm_r.Mn,
133606 + cgrd.cgr.wr_parm_r.SA, cgrd.cgr.wr_parm_r.Sn,
133607 + cgrd.cgr.wr_parm_r.Pn);
133608 +
133609 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
133610 + cgrd.cgr.wr_en_g, cgrd.cgr.wr_en_y, cgrd.cgr.wr_en_r);
133611 +
133612 + seq_printf(file, " cscn_en: %u\n", cgrd.cgr.cscn_en);
133613 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
133614 + seq_puts(file, " cscn_targ_dcp:\n");
133615 + mask = 0x80000000;
133616 + for (i = 0; i < 32; i++) {
133617 + if (cgrd.cgr.cscn_targ & mask)
133618 + seq_printf(file, " send CSCN to dcp %u\n",
133619 + (31 - i));
133620 + mask >>= 1;
133621 + }
133622 +
133623 + seq_puts(file, " cscn_targ_swp:\n");
133624 + for (i = 0; i < 4; i++) {
133625 + mask = 0x80000000;
133626 + for (j = 0; j < 32; j++) {
133627 + if (cgrd.cscn_targ_swp[i] & mask)
133628 + seq_printf(file, " send CSCN to swp"
133629 + " %u\n", (127 - (i * 32) - j));
133630 + mask >>= 1;
133631 + }
133632 + }
133633 + } else {
133634 + seq_printf(file, " cscn_targ: %u\n", cgrd.cgr.cscn_targ);
133635 + }
133636 + seq_printf(file, " cstd_en: %u\n", cgrd.cgr.cstd_en);
133637 + seq_printf(file, " cs: %u\n", cgrd.cgr.cs);
133638 +
133639 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
133640 + cgrd.cgr.cs_thres.TA, cgrd.cgr.cs_thres.Tn);
133641 +
133642 + seq_printf(file, " mode: %s\n",
133643 + (cgrd.cgr.mode & QMAN_CGR_MODE_FRAME) ?
133644 + "frame count" : "byte count");
133645 + seq_printf(file, " i_bcnt: %llu\n", qm_mcr_querycgr_i_get64(&cgrd));
133646 + seq_printf(file, " a_bcnt: %llu\n", qm_mcr_querycgr_a_get64(&cgrd));
133647 +
133648 + return 0;
133649 +}
133650 +
133651 +static int query_cgr_open(struct inode *inode, struct file *file)
133652 +{
133653 + return single_open(file, query_cgr_show, NULL);
133654 +}
133655 +
133656 +static ssize_t query_cgr_write(struct file *f, const char __user *buf,
133657 + size_t count, loff_t *off)
133658 +{
133659 + int ret;
133660 + unsigned long val;
133661 +
133662 + ret = user_input_convert(buf, count, &val);
133663 + if (ret)
133664 + return ret;
133665 + if (val > 0xff)
133666 + return -EINVAL;
133667 + query_cgr_data.cgid = (u8)val;
133668 + return count;
133669 +}
133670 +
133671 +static const struct file_operations query_cgr_fops = {
133672 + .owner = THIS_MODULE,
133673 + .open = query_cgr_open,
133674 + .read = seq_read,
133675 + .write = query_cgr_write,
133676 + .release = single_release,
133677 +};
133678 +
133679 +/*******************************************************************************
133680 + * Test Write CGR
133681 + ******************************************************************************/
133682 +struct test_write_cgr_s {
133683 + u64 i_bcnt;
133684 + u8 cgid;
133685 +};
133686 +static struct test_write_cgr_s test_write_cgr_data;
133687 +
133688 +static int testwrite_cgr_show(struct seq_file *file, void *offset)
133689 +{
133690 + int ret;
133691 + struct qm_mcr_cgrtestwrite result;
133692 + struct qman_cgr cgr;
133693 + u64 i_bcnt;
133694 +
133695 + memset(&cgr, 0, sizeof(struct qman_cgr));
133696 + memset(&result, 0, sizeof(struct qm_mcr_cgrtestwrite));
133697 + cgr.cgrid = test_write_cgr_data.cgid;
133698 + i_bcnt = test_write_cgr_data.i_bcnt;
133699 + ret = qman_testwrite_cgr(&cgr, i_bcnt, &result);
133700 + if (ret)
133701 + return ret;
133702 + seq_printf(file, "CGR Test Write CGR id 0x%x\n", cgr.cgrid);
133703 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133704 + result.cgr.wr_parm_g.MA, result.cgr.wr_parm_g.Mn,
133705 + result.cgr.wr_parm_g.SA, result.cgr.wr_parm_g.Sn,
133706 + result.cgr.wr_parm_g.Pn);
133707 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133708 + result.cgr.wr_parm_y.MA, result.cgr.wr_parm_y.Mn,
133709 + result.cgr.wr_parm_y.SA, result.cgr.wr_parm_y.Sn,
133710 + result.cgr.wr_parm_y.Pn);
133711 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133712 + result.cgr.wr_parm_r.MA, result.cgr.wr_parm_r.Mn,
133713 + result.cgr.wr_parm_r.SA, result.cgr.wr_parm_r.Sn,
133714 + result.cgr.wr_parm_r.Pn);
133715 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
133716 + result.cgr.wr_en_g, result.cgr.wr_en_y, result.cgr.wr_en_r);
133717 + seq_printf(file, " cscn_en: %u\n", result.cgr.cscn_en);
133718 + seq_printf(file, " cscn_targ: %u\n", result.cgr.cscn_targ);
133719 + seq_printf(file, " cstd_en: %u\n", result.cgr.cstd_en);
133720 + seq_printf(file, " cs: %u\n", result.cgr.cs);
133721 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
133722 + result.cgr.cs_thres.TA, result.cgr.cs_thres.Tn);
133723 +
133724 + /* Add Mode for Si 2 */
133725 + seq_printf(file, " mode: %s\n",
133726 + (result.cgr.mode & QMAN_CGR_MODE_FRAME) ?
133727 + "frame count" : "byte count");
133728 +
133729 + seq_printf(file, " i_bcnt: %llu\n",
133730 + qm_mcr_cgrtestwrite_i_get64(&result));
133731 + seq_printf(file, " a_bcnt: %llu\n",
133732 + qm_mcr_cgrtestwrite_a_get64(&result));
133733 + seq_printf(file, " wr_prob_g: %u\n", result.wr_prob_g);
133734 + seq_printf(file, " wr_prob_y: %u\n", result.wr_prob_y);
133735 + seq_printf(file, " wr_prob_r: %u\n", result.wr_prob_r);
133736 + return 0;
133737 +}
133738 +
133739 +static int testwrite_cgr_open(struct inode *inode, struct file *file)
133740 +{
133741 + return single_open(file, testwrite_cgr_show, NULL);
133742 +}
133743 +
133744 +static const struct file_operations testwrite_cgr_fops = {
133745 + .owner = THIS_MODULE,
133746 + .open = testwrite_cgr_open,
133747 + .read = seq_read,
133748 + .release = single_release,
133749 +};
133750 +
133751 +
133752 +static int testwrite_cgr_ibcnt_show(struct seq_file *file, void *offset)
133753 +{
133754 + seq_printf(file, "i_bcnt: %llu\n", test_write_cgr_data.i_bcnt);
133755 + return 0;
133756 +}
133757 +static int testwrite_cgr_ibcnt_open(struct inode *inode, struct file *file)
133758 +{
133759 + return single_open(file, testwrite_cgr_ibcnt_show, NULL);
133760 +}
133761 +
133762 +static ssize_t testwrite_cgr_ibcnt_write(struct file *f, const char __user *buf,
133763 + size_t count, loff_t *off)
133764 +{
133765 + int ret;
133766 + unsigned long val;
133767 +
133768 + ret = user_input_convert(buf, count, &val);
133769 + if (ret)
133770 + return ret;
133771 + test_write_cgr_data.i_bcnt = val;
133772 + return count;
133773 +}
133774 +
133775 +static const struct file_operations teswrite_cgr_ibcnt_fops = {
133776 + .owner = THIS_MODULE,
133777 + .open = testwrite_cgr_ibcnt_open,
133778 + .read = seq_read,
133779 + .write = testwrite_cgr_ibcnt_write,
133780 + .release = single_release,
133781 +};
133782 +
133783 +static int testwrite_cgr_cgrid_show(struct seq_file *file, void *offset)
133784 +{
133785 + seq_printf(file, "cgrid: %u\n", (u32)test_write_cgr_data.cgid);
133786 + return 0;
133787 +}
133788 +static int testwrite_cgr_cgrid_open(struct inode *inode, struct file *file)
133789 +{
133790 + return single_open(file, testwrite_cgr_cgrid_show, NULL);
133791 +}
133792 +
133793 +static ssize_t testwrite_cgr_cgrid_write(struct file *f, const char __user *buf,
133794 + size_t count, loff_t *off)
133795 +{
133796 + int ret;
133797 + unsigned long val;
133798 +
133799 + ret = user_input_convert(buf, count, &val);
133800 + if (ret)
133801 + return ret;
133802 + if (val > 0xff)
133803 + return -EINVAL;
133804 + test_write_cgr_data.cgid = (u8)val;
133805 + return count;
133806 +}
133807 +
133808 +static const struct file_operations teswrite_cgr_cgrid_fops = {
133809 + .owner = THIS_MODULE,
133810 + .open = testwrite_cgr_cgrid_open,
133811 + .read = seq_read,
133812 + .write = testwrite_cgr_cgrid_write,
133813 + .release = single_release,
133814 +};
133815 +
133816 +/*******************************************************************************
133817 + * Query Congestion State
133818 + ******************************************************************************/
133819 +static int query_congestion_show(struct seq_file *file, void *offset)
133820 +{
133821 + int ret;
133822 + struct qm_mcr_querycongestion cs;
133823 + int i, j, in_cong = 0;
133824 + u32 mask;
133825 +
133826 + memset(&cs, 0, sizeof(struct qm_mcr_querycongestion));
133827 + ret = qman_query_congestion(&cs);
133828 + if (ret)
133829 + return ret;
133830 + seq_puts(file, "Query Congestion Result\n");
133831 + for (i = 0; i < 8; i++) {
133832 + mask = 0x80000000;
133833 + for (j = 0; j < 32; j++) {
133834 + if (cs.state.__state[i] & mask) {
133835 + in_cong = 1;
133836 + seq_printf(file, " cg %u: %s\n", (i*32)+j,
133837 + "in congestion");
133838 + }
133839 + mask >>= 1;
133840 + }
133841 + }
133842 + if (!in_cong)
133843 + seq_puts(file, " All congestion groups not congested.\n");
133844 + return 0;
133845 +}
133846 +
133847 +static int query_congestion_open(struct inode *inode, struct file *file)
133848 +{
133849 + return single_open(file, query_congestion_show, NULL);
133850 +}
133851 +
133852 +static const struct file_operations query_congestion_fops = {
133853 + .owner = THIS_MODULE,
133854 + .open = query_congestion_open,
133855 + .read = seq_read,
133856 + .release = single_release,
133857 +};
133858 +
133859 +/*******************************************************************************
133860 + * Query CCGR
133861 + ******************************************************************************/
133862 +struct query_ccgr_s {
133863 + u32 ccgid;
133864 +};
133865 +static struct query_ccgr_s query_ccgr_data;
133866 +
133867 +static int query_ccgr_show(struct seq_file *file, void *offset)
133868 +{
133869 + int ret;
133870 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
133871 + struct qm_mcc_ceetm_ccgr_query query_opts;
133872 + int i, j;
133873 + u32 mask;
133874 +
133875 + memset(&ccgr_query, 0, sizeof(struct qm_mcr_ceetm_ccgr_query));
133876 + memset(&query_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_query));
133877 +
133878 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
133879 + return -EINVAL;
133880 +
133881 + seq_printf(file, "Query CCGID %x\n", query_ccgr_data.ccgid);
133882 + query_opts.dcpid = ((query_ccgr_data.ccgid & 0xFF000000) >> 24);
133883 + query_opts.ccgrid = query_ccgr_data.ccgid & 0x000001FF;
133884 + ret = qman_ceetm_query_ccgr(&query_opts, &ccgr_query);
133885 + if (ret)
133886 + return ret;
133887 + seq_printf(file, "Query CCGR id %x in DCP %d\n", query_opts.ccgrid,
133888 + query_opts.dcpid);
133889 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133890 + ccgr_query.cm_query.wr_parm_g.MA,
133891 + ccgr_query.cm_query.wr_parm_g.Mn,
133892 + ccgr_query.cm_query.wr_parm_g.SA,
133893 + ccgr_query.cm_query.wr_parm_g.Sn,
133894 + ccgr_query.cm_query.wr_parm_g.Pn);
133895 +
133896 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133897 + ccgr_query.cm_query.wr_parm_y.MA,
133898 + ccgr_query.cm_query.wr_parm_y.Mn,
133899 + ccgr_query.cm_query.wr_parm_y.SA,
133900 + ccgr_query.cm_query.wr_parm_y.Sn,
133901 + ccgr_query.cm_query.wr_parm_y.Pn);
133902 +
133903 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133904 + ccgr_query.cm_query.wr_parm_r.MA,
133905 + ccgr_query.cm_query.wr_parm_r.Mn,
133906 + ccgr_query.cm_query.wr_parm_r.SA,
133907 + ccgr_query.cm_query.wr_parm_r.Sn,
133908 + ccgr_query.cm_query.wr_parm_r.Pn);
133909 +
133910 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
133911 + ccgr_query.cm_query.ctl_wr_en_g,
133912 + ccgr_query.cm_query.ctl_wr_en_y,
133913 + ccgr_query.cm_query.ctl_wr_en_r);
133914 +
133915 + seq_printf(file, " cscn_en: %u\n", ccgr_query.cm_query.ctl_cscn_en);
133916 + seq_puts(file, " cscn_targ_dcp:\n");
133917 + mask = 0x80000000;
133918 + for (i = 0; i < 32; i++) {
133919 + if (ccgr_query.cm_query.cscn_targ_dcp & mask)
133920 + seq_printf(file, " send CSCN to dcp %u\n", (31 - i));
133921 + mask >>= 1;
133922 + }
133923 +
133924 + seq_puts(file, " cscn_targ_swp:\n");
133925 + for (i = 0; i < 4; i++) {
133926 + mask = 0x80000000;
133927 + for (j = 0; j < 32; j++) {
133928 + if (ccgr_query.cm_query.cscn_targ_swp[i] & mask)
133929 + seq_printf(file, " send CSCN to swp"
133930 + "%u\n", (127 - (i * 32) - j));
133931 + mask >>= 1;
133932 + }
133933 + }
133934 +
133935 + seq_printf(file, " td_en: %u\n", ccgr_query.cm_query.ctl_td_en);
133936 +
133937 + seq_printf(file, " cs_thresh_in_TA: %u, cs_thresh_in_Tn: %u\n",
133938 + ccgr_query.cm_query.cs_thres.TA,
133939 + ccgr_query.cm_query.cs_thres.Tn);
133940 +
133941 + seq_printf(file, " cs_thresh_out_TA: %u, cs_thresh_out_Tn: %u\n",
133942 + ccgr_query.cm_query.cs_thres_x.TA,
133943 + ccgr_query.cm_query.cs_thres_x.Tn);
133944 +
133945 + seq_printf(file, " td_thresh_TA: %u, td_thresh_Tn: %u\n",
133946 + ccgr_query.cm_query.td_thres.TA,
133947 + ccgr_query.cm_query.td_thres.Tn);
133948 +
133949 + seq_printf(file, " mode: %s\n",
133950 + (ccgr_query.cm_query.ctl_mode &
133951 + QMAN_CGR_MODE_FRAME) ?
133952 + "frame count" : "byte count");
133953 + seq_printf(file, " i_cnt: %llu\n", (u64)ccgr_query.cm_query.i_cnt);
133954 + seq_printf(file, " a_cnt: %llu\n", (u64)ccgr_query.cm_query.a_cnt);
133955 +
133956 + return 0;
133957 +}
133958 +
133959 +static int query_ccgr_open(struct inode *inode, struct file *file)
133960 +{
133961 + return single_open(file, query_ccgr_show, NULL);
133962 +}
133963 +
133964 +static ssize_t query_ccgr_write(struct file *f, const char __user *buf,
133965 + size_t count, loff_t *off)
133966 +{
133967 + int ret;
133968 + unsigned long val;
133969 +
133970 + ret = user_input_convert(buf, count, &val);
133971 + if (ret)
133972 + return ret;
133973 + query_ccgr_data.ccgid = val;
133974 + return count;
133975 +}
133976 +
133977 +static const struct file_operations query_ccgr_fops = {
133978 + .owner = THIS_MODULE,
133979 + .open = query_ccgr_open,
133980 + .read = seq_read,
133981 + .write = query_ccgr_write,
133982 + .release = single_release,
133983 +};
133984 +/*******************************************************************************
133985 + * QMan register
133986 + ******************************************************************************/
133987 +struct qman_register_s {
133988 + u32 val;
133989 +};
133990 +static struct qman_register_s qman_register_data;
133991 +
133992 +static void init_ccsrmempeek(void)
133993 +{
133994 + struct device_node *dn;
133995 + const u32 *regaddr_p;
133996 +
133997 + dn = of_find_compatible_node(NULL, NULL, "fsl,qman");
133998 + if (!dn) {
133999 + pr_info("No fsl,qman node\n");
134000 + return;
134001 + }
134002 + regaddr_p = of_get_address(dn, 0, &qman_ccsr_size, NULL);
134003 + if (!regaddr_p) {
134004 + of_node_put(dn);
134005 + return;
134006 + }
134007 + qman_ccsr_start = of_translate_address(dn, regaddr_p);
134008 + of_node_put(dn);
134009 +}
134010 +/* This function provides access to QMan ccsr memory map */
134011 +static int qman_ccsrmempeek(u32 *val, u32 offset)
134012 +{
134013 + void __iomem *addr;
134014 + u64 phys_addr;
134015 +
134016 + if (!qman_ccsr_start)
134017 + return -EINVAL;
134018 +
134019 + if (offset > (qman_ccsr_size - sizeof(u32)))
134020 + return -EINVAL;
134021 +
134022 + phys_addr = qman_ccsr_start + offset;
134023 + addr = ioremap(phys_addr, sizeof(u32));
134024 + if (!addr) {
134025 + pr_err("ccsrmempeek, ioremap failed\n");
134026 + return -EINVAL;
134027 + }
134028 + *val = in_be32(addr);
134029 + iounmap(addr);
134030 + return 0;
134031 +}
134032 +
134033 +static int qman_ccsrmempeek_show(struct seq_file *file, void *offset)
134034 +{
134035 + u32 b;
134036 +
134037 + qman_ccsrmempeek(&b, qman_register_data.val);
134038 + seq_printf(file, "QMan register offset = 0x%x\n",
134039 + qman_register_data.val);
134040 + seq_printf(file, "value = 0x%08x\n", b);
134041 +
134042 + return 0;
134043 +}
134044 +
134045 +static int qman_ccsrmempeek_open(struct inode *inode, struct file *file)
134046 +{
134047 + return single_open(file, qman_ccsrmempeek_show, NULL);
134048 +}
134049 +
134050 +static ssize_t qman_ccsrmempeek_write(struct file *f, const char __user *buf,
134051 + size_t count, loff_t *off)
134052 +{
134053 + int ret;
134054 + unsigned long val;
134055 +
134056 + ret = user_input_convert(buf, count, &val);
134057 + if (ret)
134058 + return ret;
134059 + /* multiple of 4 */
134060 + if (val > (qman_ccsr_size - sizeof(u32))) {
134061 + pr_info("Input 0x%lx > 0x%llx\n",
134062 + val, (qman_ccsr_size - sizeof(u32)));
134063 + return -EINVAL;
134064 + }
134065 + if (val & 0x3) {
134066 + pr_info("Input 0x%lx not multiple of 4\n", val);
134067 + return -EINVAL;
134068 + }
134069 + qman_register_data.val = val;
134070 + return count;
134071 +}
134072 +
134073 +static const struct file_operations qman_ccsrmempeek_fops = {
134074 + .owner = THIS_MODULE,
134075 + .open = qman_ccsrmempeek_open,
134076 + .read = seq_read,
134077 + .write = qman_ccsrmempeek_write,
134078 +};
134079 +
134080 +/*******************************************************************************
134081 + * QMan state
134082 + ******************************************************************************/
134083 +static int qman_fqd_state_show(struct seq_file *file, void *offset)
134084 +{
134085 + struct qm_mcr_queryfq_np np;
134086 + struct qman_fq fq;
134087 + struct line_buffer_fq line_buf;
134088 + int ret, i;
134089 + u8 *state = file->private;
134090 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
134091 +
134092 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
134093 + memset(&line_buf, 0, sizeof(line_buf));
134094 +
134095 + seq_printf(file, "List of fq ids in state: %s\n", state_txt[*state]);
134096 +
134097 + for (i = 1; i < fqid_max; i++) {
134098 + fq.fqid = i;
134099 + ret = qman_query_fq_np(&fq, &np);
134100 + if (ret)
134101 + return ret;
134102 + if (*state == (np.state & QM_MCR_NP_STATE_MASK))
134103 + add_to_line_buffer(&line_buf, fq.fqid, file);
134104 + /* Keep a summary count of all states */
134105 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
134106 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
134107 + }
134108 + flush_line_buffer(&line_buf, file);
134109 +
134110 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
134111 + seq_printf(file, "%s count = %u\n", state_txt[i],
134112 + qm_fq_state_cnt[i]);
134113 + }
134114 + return 0;
134115 +}
134116 +
134117 +static int qman_fqd_state_open(struct inode *inode, struct file *file)
134118 +{
134119 + return single_open(file, qman_fqd_state_show, inode->i_private);
134120 +}
134121 +
134122 +static const struct file_operations qman_fqd_state_fops = {
134123 + .owner = THIS_MODULE,
134124 + .open = qman_fqd_state_open,
134125 + .read = seq_read,
134126 +};
134127 +
134128 +static int qman_fqd_ctrl_show(struct seq_file *file, void *offset)
134129 +{
134130 + struct qm_fqd fqd;
134131 + struct qman_fq fq;
134132 + u32 fq_en_cnt = 0, fq_di_cnt = 0;
134133 + int ret, i;
134134 + struct mask_filter_s *data = file->private;
134135 + const char *ctrl_txt = get_fqd_ctrl_text(data->mask);
134136 + struct line_buffer_fq line_buf;
134137 +
134138 + memset(&line_buf, 0, sizeof(line_buf));
134139 + seq_printf(file, "List of fq ids with: %s :%s\n",
134140 + ctrl_txt, (data->filter) ? "enabled" : "disabled");
134141 + for (i = 1; i < fqid_max; i++) {
134142 + fq.fqid = i;
134143 + memset(&fqd, 0, sizeof(struct qm_fqd));
134144 + ret = qman_query_fq(&fq, &fqd);
134145 + if (ret)
134146 + return ret;
134147 + if (data->filter) {
134148 + if (fqd.fq_ctrl & data->mask)
134149 + add_to_line_buffer(&line_buf, fq.fqid, file);
134150 + } else {
134151 + if (!(fqd.fq_ctrl & data->mask))
134152 + add_to_line_buffer(&line_buf, fq.fqid, file);
134153 + }
134154 + if (fqd.fq_ctrl & data->mask)
134155 + fq_en_cnt++;
134156 + else
134157 + fq_di_cnt++;
134158 + }
134159 + flush_line_buffer(&line_buf, file);
134160 +
134161 + seq_printf(file, "Total FQD with: %s : enabled = %u\n",
134162 + ctrl_txt, fq_en_cnt);
134163 + seq_printf(file, "Total FQD with: %s : disabled = %u\n",
134164 + ctrl_txt, fq_di_cnt);
134165 + return 0;
134166 +}
134167 +
134168 +/*******************************************************************************
134169 + * QMan ctrl CGE, TDE, ORP, CTX, CPC, SFDR, BLOCK, HOLD, CACHE
134170 + ******************************************************************************/
134171 +static int qman_fqd_ctrl_open(struct inode *inode, struct file *file)
134172 +{
134173 + return single_open(file, qman_fqd_ctrl_show, inode->i_private);
134174 +}
134175 +
134176 +static const struct file_operations qman_fqd_ctrl_fops = {
134177 + .owner = THIS_MODULE,
134178 + .open = qman_fqd_ctrl_open,
134179 + .read = seq_read,
134180 +};
134181 +
134182 +/*******************************************************************************
134183 + * QMan ctrl summary
134184 + ******************************************************************************/
134185 +/*******************************************************************************
134186 + * QMan summary state
134187 + ******************************************************************************/
134188 +static int qman_fqd_non_prog_summary_show(struct seq_file *file, void *offset)
134189 +{
134190 + struct qm_mcr_queryfq_np np;
134191 + struct qman_fq fq;
134192 + int ret, i;
134193 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
134194 +
134195 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
134196 +
134197 + for (i = 1; i < fqid_max; i++) {
134198 + fq.fqid = i;
134199 + ret = qman_query_fq_np(&fq, &np);
134200 + if (ret)
134201 + return ret;
134202 + /* Keep a summary count of all states */
134203 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
134204 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
134205 + }
134206 +
134207 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
134208 + seq_printf(file, "%s count = %u\n", state_txt[i],
134209 + qm_fq_state_cnt[i]);
134210 + }
134211 + return 0;
134212 +}
134213 +
134214 +static int qman_fqd_prog_summary_show(struct seq_file *file, void *offset)
134215 +{
134216 + struct qm_fqd fqd;
134217 + struct qman_fq fq;
134218 + int ret, i , j;
134219 + u32 qm_prog_cnt[ARRAY_SIZE(mask_filter)/2];
134220 +
134221 + memset(qm_prog_cnt, 0, sizeof(qm_prog_cnt));
134222 +
134223 + for (i = 1; i < fqid_max; i++) {
134224 + memset(&fqd, 0, sizeof(struct qm_fqd));
134225 + fq.fqid = i;
134226 + ret = qman_query_fq(&fq, &fqd);
134227 + if (ret)
134228 + return ret;
134229 + /* Keep a summary count of all states */
134230 + for (j = 0; j < ARRAY_SIZE(mask_filter); j += 2)
134231 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
134232 + mask_filter[j].mask)
134233 + qm_prog_cnt[j/2]++;
134234 + }
134235 + for (i = 0; i < ARRAY_SIZE(mask_filter) / 2; i++) {
134236 + seq_printf(file, "%s count = %u\n",
134237 + get_fqd_ctrl_text(mask_filter[i*2].mask),
134238 + qm_prog_cnt[i]);
134239 + }
134240 + return 0;
134241 +}
134242 +
134243 +static int qman_fqd_summary_show(struct seq_file *file, void *offset)
134244 +{
134245 + int ret;
134246 +
134247 + /* Display summary of non programmable fields */
134248 + ret = qman_fqd_non_prog_summary_show(file, offset);
134249 + if (ret)
134250 + return ret;
134251 + seq_puts(file, "-----------------------------------------\n");
134252 + /* Display programmable fields */
134253 + ret = qman_fqd_prog_summary_show(file, offset);
134254 + if (ret)
134255 + return ret;
134256 + return 0;
134257 +}
134258 +
134259 +static int qman_fqd_summary_open(struct inode *inode, struct file *file)
134260 +{
134261 + return single_open(file, qman_fqd_summary_show, NULL);
134262 +}
134263 +
134264 +static const struct file_operations qman_fqd_summary_fops = {
134265 + .owner = THIS_MODULE,
134266 + .open = qman_fqd_summary_open,
134267 + .read = seq_read,
134268 +};
134269 +
134270 +/*******************************************************************************
134271 + * QMan destination work queue
134272 + ******************************************************************************/
134273 +struct qman_dest_wq_s {
134274 + u16 wq_id;
134275 +};
134276 +static struct qman_dest_wq_s qman_dest_wq_data = {
134277 + .wq_id = 0,
134278 +};
134279 +
134280 +static int qman_fqd_dest_wq_show(struct seq_file *file, void *offset)
134281 +{
134282 + struct qm_fqd fqd;
134283 + struct qman_fq fq;
134284 + int ret, i;
134285 + u16 *wq, wq_id = qman_dest_wq_data.wq_id;
134286 + struct line_buffer_fq line_buf;
134287 +
134288 + memset(&line_buf, 0, sizeof(line_buf));
134289 + /* use vmalloc : need to allocate large memory region and don't
134290 + * require the memory to be physically contiguous. */
134291 + wq = vzalloc(sizeof(u16) * (0xFFFF+1));
134292 + if (!wq)
134293 + return -ENOMEM;
134294 +
134295 + seq_printf(file, "List of fq ids with destination work queue id"
134296 + " = 0x%x\n", wq_id);
134297 +
134298 + for (i = 1; i < fqid_max; i++) {
134299 + fq.fqid = i;
134300 + memset(&fqd, 0, sizeof(struct qm_fqd));
134301 + ret = qman_query_fq(&fq, &fqd);
134302 + if (ret) {
134303 + vfree(wq);
134304 + return ret;
134305 + }
134306 + if (wq_id == fqd.dest_wq)
134307 + add_to_line_buffer(&line_buf, fq.fqid, file);
134308 + wq[fqd.dest_wq]++;
134309 + }
134310 + flush_line_buffer(&line_buf, file);
134311 +
134312 + seq_puts(file, "Summary of all FQD destination work queue values\n");
134313 + for (i = 0; i < 0xFFFF; i++) {
134314 + if (wq[i])
134315 + seq_printf(file, "Channel: 0x%x WQ: 0x%x WQ_ID: 0x%x, "
134316 + "count = %u\n", i >> 3, i & 0x3, i, wq[i]);
134317 + }
134318 + vfree(wq);
134319 + return 0;
134320 +}
134321 +
134322 +static ssize_t qman_fqd_dest_wq_write(struct file *f, const char __user *buf,
134323 + size_t count, loff_t *off)
134324 +{
134325 + int ret;
134326 + unsigned long val;
134327 +
134328 + ret = user_input_convert(buf, count, &val);
134329 + if (ret)
134330 + return ret;
134331 + if (val > 0xFFFF)
134332 + return -EINVAL;
134333 + qman_dest_wq_data.wq_id = val;
134334 + return count;
134335 +}
134336 +
134337 +static int qman_fqd_dest_wq_open(struct inode *inode, struct file *file)
134338 +{
134339 + return single_open(file, qman_fqd_dest_wq_show, NULL);
134340 +}
134341 +
134342 +static const struct file_operations qman_fqd_dest_wq_fops = {
134343 + .owner = THIS_MODULE,
134344 + .open = qman_fqd_dest_wq_open,
134345 + .read = seq_read,
134346 + .write = qman_fqd_dest_wq_write,
134347 +};
134348 +
134349 +/*******************************************************************************
134350 + * QMan Intra-Class Scheduling Credit
134351 + ******************************************************************************/
134352 +static int qman_fqd_cred_show(struct seq_file *file, void *offset)
134353 +{
134354 + struct qm_fqd fqd;
134355 + struct qman_fq fq;
134356 + int ret, i;
134357 + u32 fq_cnt = 0;
134358 + struct line_buffer_fq line_buf;
134359 +
134360 + memset(&line_buf, 0, sizeof(line_buf));
134361 + seq_puts(file, "List of fq ids with Intra-Class Scheduling Credit > 0"
134362 + "\n");
134363 +
134364 + for (i = 1; i < fqid_max; i++) {
134365 + fq.fqid = i;
134366 + memset(&fqd, 0, sizeof(struct qm_fqd));
134367 + ret = qman_query_fq(&fq, &fqd);
134368 + if (ret)
134369 + return ret;
134370 + if (fqd.ics_cred > 0) {
134371 + add_to_line_buffer(&line_buf, fq.fqid, file);
134372 + fq_cnt++;
134373 + }
134374 + }
134375 + flush_line_buffer(&line_buf, file);
134376 +
134377 + seq_printf(file, "Total FQD with ics_cred > 0 = %d\n", fq_cnt);
134378 + return 0;
134379 +}
134380 +
134381 +static int qman_fqd_cred_open(struct inode *inode, struct file *file)
134382 +{
134383 + return single_open(file, qman_fqd_cred_show, NULL);
134384 +}
134385 +
134386 +static const struct file_operations qman_fqd_cred_fops = {
134387 + .owner = THIS_MODULE,
134388 + .open = qman_fqd_cred_open,
134389 + .read = seq_read,
134390 +};
134391 +
134392 +/*******************************************************************************
134393 + * Class Queue Fields
134394 + ******************************************************************************/
134395 +struct query_cq_fields_data_s {
134396 + u32 cqid;
134397 +};
134398 +
134399 +static struct query_cq_fields_data_s query_cq_fields_data = {
134400 + .cqid = 1,
134401 +};
134402 +
134403 +static int query_cq_fields_show(struct seq_file *file, void *offset)
134404 +{
134405 + int ret;
134406 + struct qm_mcr_ceetm_cq_query query_result;
134407 + unsigned int cqid;
134408 + unsigned int portal;
134409 +
134410 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
134411 + return -EINVAL;
134412 +
134413 + cqid = query_cq_fields_data.cqid & 0x00FFFFFF;
134414 + portal = query_cq_fields_data.cqid >> 24;
134415 + if (portal > qm_dc_portal_fman1)
134416 + return -EINVAL;
134417 +
134418 + ret = qman_ceetm_query_cq(cqid, portal, &query_result);
134419 + if (ret)
134420 + return ret;
134421 + seq_printf(file, "Query CQ Fields Result cqid 0x%x on DCP %d\n",
134422 + cqid, portal);
134423 + seq_printf(file, " ccgid: %u\n", query_result.ccgid);
134424 + seq_printf(file, " state: %u\n", query_result.state);
134425 + seq_printf(file, " pfdr_hptr: %u\n", query_result.pfdr_hptr);
134426 + seq_printf(file, " pfdr_tptr: %u\n", query_result.pfdr_tptr);
134427 + seq_printf(file, " od1_xsfdr: %u\n", query_result.od1_xsfdr);
134428 + seq_printf(file, " od2_xsfdr: %u\n", query_result.od2_xsfdr);
134429 + seq_printf(file, " od3_xsfdr: %u\n", query_result.od3_xsfdr);
134430 + seq_printf(file, " od4_xsfdr: %u\n", query_result.od4_xsfdr);
134431 + seq_printf(file, " od5_xsfdr: %u\n", query_result.od5_xsfdr);
134432 + seq_printf(file, " od6_xsfdr: %u\n", query_result.od6_xsfdr);
134433 + seq_printf(file, " ra1_xsfdr: %u\n", query_result.ra1_xsfdr);
134434 + seq_printf(file, " ra2_xsfdr: %u\n", query_result.ra2_xsfdr);
134435 + seq_printf(file, " frame_count: %u\n", query_result.frm_cnt);
134436 +
134437 + return 0;
134438 +}
134439 +
134440 +static int query_cq_fields_open(struct inode *inode,
134441 + struct file *file)
134442 +{
134443 + return single_open(file, query_cq_fields_show, NULL);
134444 +}
134445 +
134446 +static ssize_t query_cq_fields_write(struct file *f,
134447 + const char __user *buf, size_t count, loff_t *off)
134448 +{
134449 + int ret;
134450 + unsigned long val;
134451 +
134452 + ret = user_input_convert(buf, count, &val);
134453 + if (ret)
134454 + return ret;
134455 + query_cq_fields_data.cqid = (u32)val;
134456 + return count;
134457 +}
134458 +
134459 +static const struct file_operations query_cq_fields_fops = {
134460 + .owner = THIS_MODULE,
134461 + .open = query_cq_fields_open,
134462 + .read = seq_read,
134463 + .write = query_cq_fields_write,
134464 + .release = single_release,
134465 +};
134466 +
134467 +/*******************************************************************************
134468 + * READ CEETM_XSFDR_IN_USE
134469 + ******************************************************************************/
134470 +struct query_ceetm_xsfdr_data_s {
134471 + enum qm_dc_portal dcp_portal;
134472 +};
134473 +
134474 +static struct query_ceetm_xsfdr_data_s query_ceetm_xsfdr_data;
134475 +
134476 +static int query_ceetm_xsfdr_show(struct seq_file *file, void *offset)
134477 +{
134478 + int ret;
134479 + unsigned int xsfdr_in_use;
134480 + enum qm_dc_portal portal;
134481 +
134482 +
134483 + if (qman_ip_rev < QMAN_REV31)
134484 + return -EINVAL;
134485 +
134486 + portal = query_ceetm_xsfdr_data.dcp_portal;
134487 + ret = qman_ceetm_get_xsfdr(portal, &xsfdr_in_use);
134488 + if (ret) {
134489 + seq_printf(file, "Read CEETM_XSFDR_IN_USE on DCP %d failed\n",
134490 + portal);
134491 + return ret;
134492 + }
134493 +
134494 + seq_printf(file, "DCP%d: CEETM_XSFDR_IN_USE number is %u\n", portal,
134495 + (xsfdr_in_use & 0x1FFF));
134496 + return 0;
134497 +}
134498 +
134499 +static int query_ceetm_xsfdr_open(struct inode *inode,
134500 + struct file *file)
134501 +{
134502 + return single_open(file, query_ceetm_xsfdr_show, NULL);
134503 +}
134504 +
134505 +static ssize_t query_ceetm_xsfdr_write(struct file *f,
134506 + const char __user *buf, size_t count, loff_t *off)
134507 +{
134508 + int ret;
134509 + unsigned long val;
134510 +
134511 + ret = user_input_convert(buf, count, &val);
134512 + if (ret)
134513 + return ret;
134514 + if (val > qm_dc_portal_fman1)
134515 + return -EINVAL;
134516 + query_ceetm_xsfdr_data.dcp_portal = (u32)val;
134517 + return count;
134518 +}
134519 +
134520 +static const struct file_operations query_ceetm_xsfdr_fops = {
134521 + .owner = THIS_MODULE,
134522 + .open = query_ceetm_xsfdr_open,
134523 + .read = seq_read,
134524 + .write = query_ceetm_xsfdr_write,
134525 + .release = single_release,
134526 +};
134527 +
134528 +/* helper macros used in qman_debugfs_module_init */
134529 +#define QMAN_DBGFS_ENTRY(name, mode, parent, data, fops) \
134530 + do { \
134531 + d = debugfs_create_file(name, \
134532 + mode, parent, \
134533 + data, \
134534 + fops); \
134535 + if (d == NULL) { \
134536 + ret = -ENOMEM; \
134537 + goto _return; \
134538 + } \
134539 + } while (0)
134540 +
134541 +/* dfs_root as parent */
134542 +#define QMAN_DBGFS_ENTRY_ROOT(name, mode, data, fops) \
134543 + QMAN_DBGFS_ENTRY(name, mode, dfs_root, data, fops)
134544 +
134545 +/* fqd_root as parent */
134546 +#define QMAN_DBGFS_ENTRY_FQDROOT(name, mode, data, fops) \
134547 + QMAN_DBGFS_ENTRY(name, mode, fqd_root, data, fops)
134548 +
134549 +/* fqd state */
134550 +#define QMAN_DBGFS_ENTRY_FQDSTATE(name, index) \
134551 + QMAN_DBGFS_ENTRY_FQDROOT(name, S_IRUGO, \
134552 + (void *)&mask_filter[index], &qman_fqd_ctrl_fops)
134553 +
134554 +static int __init qman_debugfs_module_init(void)
134555 +{
134556 + int ret = 0;
134557 + struct dentry *d, *fqd_root;
134558 + u32 reg;
134559 +
134560 + fqid_max = 0;
134561 + init_ccsrmempeek();
134562 + if (qman_ccsr_start) {
134563 + if (!qman_ccsrmempeek(&reg, QM_FQD_AR)) {
134564 + /* extract the size of the FQD window */
134565 + reg = reg & 0x3f;
134566 + /* calculate valid frame queue descriptor range */
134567 + fqid_max = (1 << (reg + 1)) / QM_FQD_BLOCK_SIZE;
134568 + }
134569 + }
134570 + dfs_root = debugfs_create_dir("qman", NULL);
134571 + fqd_root = debugfs_create_dir("fqd", dfs_root);
134572 + if (dfs_root == NULL || fqd_root == NULL) {
134573 + ret = -ENOMEM;
134574 + pr_err("Cannot create qman/fqd debugfs dir\n");
134575 + goto _return;
134576 + }
134577 + if (fqid_max) {
134578 + QMAN_DBGFS_ENTRY_ROOT("ccsrmempeek", S_IRUGO | S_IWUGO,
134579 + NULL, &qman_ccsrmempeek_fops);
134580 + }
134581 + QMAN_DBGFS_ENTRY_ROOT("query_fq_np_fields", S_IRUGO | S_IWUGO,
134582 + &query_fq_np_fields_data, &query_fq_np_fields_fops);
134583 +
134584 + QMAN_DBGFS_ENTRY_ROOT("query_fq_fields", S_IRUGO | S_IWUGO,
134585 + &query_fq_fields_data, &query_fq_fields_fops);
134586 +
134587 + QMAN_DBGFS_ENTRY_ROOT("query_wq_lengths", S_IRUGO | S_IWUGO,
134588 + &query_wq_lengths_data, &query_wq_lengths_fops);
134589 +
134590 + QMAN_DBGFS_ENTRY_ROOT("query_cgr", S_IRUGO | S_IWUGO,
134591 + &query_cgr_data, &query_cgr_fops);
134592 +
134593 + QMAN_DBGFS_ENTRY_ROOT("query_congestion", S_IRUGO,
134594 + NULL, &query_congestion_fops);
134595 +
134596 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr", S_IRUGO,
134597 + NULL, &testwrite_cgr_fops);
134598 +
134599 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_cgrid", S_IRUGO | S_IWUGO,
134600 + NULL, &teswrite_cgr_cgrid_fops);
134601 +
134602 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_ibcnt", S_IRUGO | S_IWUGO,
134603 + NULL, &teswrite_cgr_ibcnt_fops);
134604 +
134605 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_ccgr", S_IRUGO | S_IWUGO,
134606 + &query_ccgr_data, &query_ccgr_fops);
134607 + /* Create files with fqd_root as parent */
134608 +
134609 + QMAN_DBGFS_ENTRY_FQDROOT("stateoos", S_IRUGO,
134610 + (void *)&fqd_states[QM_MCR_NP_STATE_OOS], &qman_fqd_state_fops);
134611 +
134612 + QMAN_DBGFS_ENTRY_FQDROOT("state_retired", S_IRUGO,
134613 + (void *)&fqd_states[QM_MCR_NP_STATE_RETIRED],
134614 + &qman_fqd_state_fops);
134615 +
134616 + QMAN_DBGFS_ENTRY_FQDROOT("state_tentatively_sched", S_IRUGO,
134617 + (void *)&fqd_states[QM_MCR_NP_STATE_TEN_SCHED],
134618 + &qman_fqd_state_fops);
134619 +
134620 + QMAN_DBGFS_ENTRY_FQDROOT("state_truly_sched", S_IRUGO,
134621 + (void *)&fqd_states[QM_MCR_NP_STATE_TRU_SCHED],
134622 + &qman_fqd_state_fops);
134623 +
134624 + QMAN_DBGFS_ENTRY_FQDROOT("state_parked", S_IRUGO,
134625 + (void *)&fqd_states[QM_MCR_NP_STATE_PARKED],
134626 + &qman_fqd_state_fops);
134627 +
134628 + QMAN_DBGFS_ENTRY_FQDROOT("state_active", S_IRUGO,
134629 + (void *)&fqd_states[QM_MCR_NP_STATE_ACTIVE],
134630 + &qman_fqd_state_fops);
134631 + QMAN_DBGFS_ENTRY_ROOT("query_cq_fields", S_IRUGO | S_IWUGO,
134632 + &query_cq_fields_data, &query_cq_fields_fops);
134633 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_xsfdr_in_use", S_IRUGO | S_IWUGO,
134634 + &query_ceetm_xsfdr_data, &query_ceetm_xsfdr_fops);
134635 +
134636 +
134637 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_enable", 17);
134638 +
134639 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_disable", 16);
134640 +
134641 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_enable", 15);
134642 +
134643 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_disable", 14);
134644 +
134645 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_enable", 13);
134646 +
134647 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_disable", 12);
134648 +
134649 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_enable", 11);
134650 +
134651 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_disable", 10);
134652 +
134653 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_enable", 9);
134654 +
134655 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_disable", 8);
134656 +
134657 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_enable", 7);
134658 +
134659 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_disable", 6);
134660 +
134661 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_enable", 5);
134662 +
134663 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_disable", 4);
134664 +
134665 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_enable", 3);
134666 +
134667 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_disable", 2);
134668 +
134669 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_enable", 1);
134670 +
134671 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_disable", 0);
134672 +
134673 + QMAN_DBGFS_ENTRY_FQDROOT("summary", S_IRUGO,
134674 + NULL, &qman_fqd_summary_fops);
134675 +
134676 + QMAN_DBGFS_ENTRY_FQDROOT("wq", S_IRUGO | S_IWUGO,
134677 + NULL, &qman_fqd_dest_wq_fops);
134678 +
134679 + QMAN_DBGFS_ENTRY_FQDROOT("cred", S_IRUGO,
134680 + NULL, &qman_fqd_cred_fops);
134681 +
134682 + return 0;
134683 +
134684 +_return:
134685 + debugfs_remove_recursive(dfs_root);
134686 + return ret;
134687 +}
134688 +
134689 +static void __exit qman_debugfs_module_exit(void)
134690 +{
134691 + debugfs_remove_recursive(dfs_root);
134692 +}
134693 +
134694 +module_init(qman_debugfs_module_init);
134695 +module_exit(qman_debugfs_module_exit);
134696 +MODULE_LICENSE("Dual BSD/GPL");
134697 --- /dev/null
134698 +++ b/drivers/staging/fsl_qbman/qman_driver.c
134699 @@ -0,0 +1,977 @@
134700 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
134701 + *
134702 + * Redistribution and use in source and binary forms, with or without
134703 + * modification, are permitted provided that the following conditions are met:
134704 + * * Redistributions of source code must retain the above copyright
134705 + * notice, this list of conditions and the following disclaimer.
134706 + * * Redistributions in binary form must reproduce the above copyright
134707 + * notice, this list of conditions and the following disclaimer in the
134708 + * documentation and/or other materials provided with the distribution.
134709 + * * Neither the name of Freescale Semiconductor nor the
134710 + * names of its contributors may be used to endorse or promote products
134711 + * derived from this software without specific prior written permission.
134712 + *
134713 + *
134714 + * ALTERNATIVELY, this software may be distributed under the terms of the
134715 + * GNU General Public License ("GPL") as published by the Free Software
134716 + * Foundation, either version 2 of that License or (at your option) any
134717 + * later version.
134718 + *
134719 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
134720 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
134721 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
134722 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
134723 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
134724 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
134725 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
134726 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
134727 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
134728 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
134729 + */
134730 +
134731 +#include "qman_private.h"
134732 +
134733 +#include <asm/smp.h> /* hard_smp_processor_id() if !CONFIG_SMP */
134734 +#ifdef CONFIG_HOTPLUG_CPU
134735 +#include <linux/cpu.h>
134736 +#endif
134737 +
134738 +/* Global variable containing revision id (even on non-control plane systems
134739 + * where CCSR isn't available) */
134740 +u16 qman_ip_rev;
134741 +EXPORT_SYMBOL(qman_ip_rev);
134742 +u8 qman_ip_cfg;
134743 +EXPORT_SYMBOL(qman_ip_cfg);
134744 +u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1;
134745 +EXPORT_SYMBOL(qm_channel_pool1);
134746 +u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
134747 +EXPORT_SYMBOL(qm_channel_caam);
134748 +u16 qm_channel_pme = QMAN_CHANNEL_PME;
134749 +EXPORT_SYMBOL(qm_channel_pme);
134750 +u16 qm_channel_dce = QMAN_CHANNEL_DCE;
134751 +EXPORT_SYMBOL(qm_channel_dce);
134752 +u16 qman_portal_max;
134753 +EXPORT_SYMBOL(qman_portal_max);
134754 +
134755 +u32 qman_clk;
134756 +struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
134757 +/* the qman ceetm instances on the given SoC */
134758 +u8 num_ceetms;
134759 +
134760 +/* For these variables, and the portal-initialisation logic, the
134761 + * comments in bman_driver.c apply here so won't be repeated. */
134762 +static struct qman_portal *shared_portals[NR_CPUS];
134763 +static int num_shared_portals;
134764 +static int shared_portals_idx;
134765 +static LIST_HEAD(unused_pcfgs);
134766 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
134767 +
134768 +/* A SDQCR mask comprising all the available/visible pool channels */
134769 +static u32 pools_sdqcr;
134770 +
134771 +#define STR_ERR_NOPROP "No '%s' property in node %s\n"
134772 +#define STR_ERR_CELL "'%s' is not a %d-cell range in node %s\n"
134773 +#define STR_FQID_RANGE "fsl,fqid-range"
134774 +#define STR_POOL_CHAN_RANGE "fsl,pool-channel-range"
134775 +#define STR_CGRID_RANGE "fsl,cgrid-range"
134776 +
134777 +/* A "fsl,fqid-range" node; release the given range to the allocator */
134778 +static __init int fsl_fqid_range_init(struct device_node *node)
134779 +{
134780 + int ret;
134781 + const u32 *range = of_get_property(node, STR_FQID_RANGE, &ret);
134782 + if (!range) {
134783 + pr_err(STR_ERR_NOPROP, STR_FQID_RANGE, node->full_name);
134784 + return -EINVAL;
134785 + }
134786 + if (ret != 8) {
134787 + pr_err(STR_ERR_CELL, STR_FQID_RANGE, 2, node->full_name);
134788 + return -EINVAL;
134789 + }
134790 + qman_seed_fqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134791 + pr_info("Qman: FQID allocator includes range %d:%d\n",
134792 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134793 + return 0;
134794 +}
134795 +
134796 +/* A "fsl,pool-channel-range" node; add to the SDQCR mask only */
134797 +static __init int fsl_pool_channel_range_sdqcr(struct device_node *node)
134798 +{
134799 + int ret;
134800 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
134801 + if (!chanid) {
134802 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
134803 + return -EINVAL;
134804 + }
134805 + if (ret != 8) {
134806 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
134807 + return -EINVAL;
134808 + }
134809 + for (ret = 0; ret < be32_to_cpu(chanid[1]); ret++)
134810 + pools_sdqcr |= QM_SDQCR_CHANNELS_POOL_CONV(be32_to_cpu(chanid[0]) + ret);
134811 + return 0;
134812 +}
134813 +
134814 +/* A "fsl,pool-channel-range" node; release the given range to the allocator */
134815 +static __init int fsl_pool_channel_range_init(struct device_node *node)
134816 +{
134817 + int ret;
134818 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
134819 + if (!chanid) {
134820 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
134821 + return -EINVAL;
134822 + }
134823 + if (ret != 8) {
134824 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
134825 + return -EINVAL;
134826 + }
134827 + qman_seed_pool_range(be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
134828 + pr_info("Qman: pool channel allocator includes range %d:%d\n",
134829 + be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
134830 + return 0;
134831 +}
134832 +
134833 +/* A "fsl,cgrid-range" node; release the given range to the allocator */
134834 +static __init int fsl_cgrid_range_init(struct device_node *node)
134835 +{
134836 + struct qman_cgr cgr;
134837 + int ret, errors = 0;
134838 + const u32 *range = of_get_property(node, STR_CGRID_RANGE, &ret);
134839 + if (!range) {
134840 + pr_err(STR_ERR_NOPROP, STR_CGRID_RANGE, node->full_name);
134841 + return -EINVAL;
134842 + }
134843 + if (ret != 8) {
134844 + pr_err(STR_ERR_CELL, STR_CGRID_RANGE, 2, node->full_name);
134845 + return -EINVAL;
134846 + }
134847 + qman_seed_cgrid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134848 + pr_info("Qman: CGRID allocator includes range %d:%d\n",
134849 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134850 + for (cgr.cgrid = 0; cgr.cgrid < __CGR_NUM; cgr.cgrid++) {
134851 + ret = qman_modify_cgr(&cgr, QMAN_CGR_FLAG_USE_INIT, NULL);
134852 + if (ret)
134853 + errors++;
134854 + }
134855 + if (errors)
134856 + pr_err("Warning: %d error%s while initialising CGRs %d:%d\n",
134857 + errors, (errors > 1) ? "s" : "", range[0], range[1]);
134858 + return 0;
134859 +}
134860 +
134861 +static __init int fsl_ceetm_init(struct device_node *node)
134862 +{
134863 + enum qm_dc_portal dcp_portal;
134864 + struct qm_ceetm_sp *sp;
134865 + struct qm_ceetm_lni *lni;
134866 + int ret, i;
134867 + const u32 *range;
134868 +
134869 + /* Find LFQID range */
134870 + range = of_get_property(node, "fsl,ceetm-lfqid-range", &ret);
134871 + if (!range) {
134872 + pr_err("No fsl,ceetm-lfqid-range in node %s\n",
134873 + node->full_name);
134874 + return -EINVAL;
134875 + }
134876 + if (ret != 8) {
134877 + pr_err("fsl,ceetm-lfqid-range is not a 2-cell range in node"
134878 + " %s\n", node->full_name);
134879 + return -EINVAL;
134880 + }
134881 +
134882 + dcp_portal = (be32_to_cpu(range[0]) & 0x0F0000) >> 16;
134883 + if (dcp_portal > qm_dc_portal_fman1) {
134884 + pr_err("The DCP portal %d doesn't support CEETM\n", dcp_portal);
134885 + return -EINVAL;
134886 + }
134887 +
134888 + if (dcp_portal == qm_dc_portal_fman0)
134889 + qman_seed_ceetm0_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134890 + if (dcp_portal == qm_dc_portal_fman1)
134891 + qman_seed_ceetm1_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134892 + pr_debug("Qman: The lfqid allocator of CEETM %d includes range"
134893 + " 0x%x:0x%x\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134894 +
134895 + qman_ceetms[dcp_portal].idx = dcp_portal;
134896 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].sub_portals);
134897 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].lnis);
134898 +
134899 + /* Find Sub-portal range */
134900 + range = of_get_property(node, "fsl,ceetm-sp-range", &ret);
134901 + if (!range) {
134902 + pr_err("No fsl,ceetm-sp-range in node %s\n", node->full_name);
134903 + return -EINVAL;
134904 + }
134905 + if (ret != 8) {
134906 + pr_err("fsl,ceetm-sp-range is not a 2-cell range in node %s\n",
134907 + node->full_name);
134908 + return -EINVAL;
134909 + }
134910 +
134911 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
134912 + sp = kzalloc(sizeof(*sp), GFP_KERNEL);
134913 + if (!sp) {
134914 + pr_err("Can't alloc memory for sub-portal %d\n",
134915 + range[0] + i);
134916 + return -ENOMEM;
134917 + }
134918 + sp->idx = be32_to_cpu(range[0]) + i;
134919 + sp->dcp_idx = dcp_portal;
134920 + sp->is_claimed = 0;
134921 + list_add_tail(&sp->node, &qman_ceetms[dcp_portal].sub_portals);
134922 + sp++;
134923 + }
134924 + pr_debug("Qman: Reserve sub-portal %d:%d for CEETM %d\n",
134925 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
134926 + qman_ceetms[dcp_portal].sp_range[0] = be32_to_cpu(range[0]);
134927 + qman_ceetms[dcp_portal].sp_range[1] = be32_to_cpu(range[1]);
134928 +
134929 + /* Find LNI range */
134930 + range = of_get_property(node, "fsl,ceetm-lni-range", &ret);
134931 + if (!range) {
134932 + pr_err("No fsl,ceetm-lni-range in node %s\n", node->full_name);
134933 + return -EINVAL;
134934 + }
134935 + if (ret != 8) {
134936 + pr_err("fsl,ceetm-lni-range is not a 2-cell range in node %s\n",
134937 + node->full_name);
134938 + return -EINVAL;
134939 + }
134940 +
134941 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
134942 + lni = kzalloc(sizeof(*lni), GFP_KERNEL);
134943 + if (!lni) {
134944 + pr_err("Can't alloc memory for LNI %d\n",
134945 + range[0] + i);
134946 + return -ENOMEM;
134947 + }
134948 + lni->idx = be32_to_cpu(range[0]) + i;
134949 + lni->dcp_idx = dcp_portal;
134950 + lni->is_claimed = 0;
134951 + INIT_LIST_HEAD(&lni->channels);
134952 + list_add_tail(&lni->node, &qman_ceetms[dcp_portal].lnis);
134953 + lni++;
134954 + }
134955 + pr_debug("Qman: Reserve LNI %d:%d for CEETM %d\n",
134956 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
134957 + qman_ceetms[dcp_portal].lni_range[0] = be32_to_cpu(range[0]);
134958 + qman_ceetms[dcp_portal].lni_range[1] = be32_to_cpu(range[1]);
134959 +
134960 + /* Find CEETM channel range */
134961 + range = of_get_property(node, "fsl,ceetm-channel-range", &ret);
134962 + if (!range) {
134963 + pr_err("No fsl,ceetm-channel-range in node %s\n",
134964 + node->full_name);
134965 + return -EINVAL;
134966 + }
134967 + if (ret != 8) {
134968 + pr_err("fsl,ceetm-channel-range is not a 2-cell range in node"
134969 + "%s\n", node->full_name);
134970 + return -EINVAL;
134971 + }
134972 +
134973 + if (dcp_portal == qm_dc_portal_fman0)
134974 + qman_seed_ceetm0_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134975 + if (dcp_portal == qm_dc_portal_fman1)
134976 + qman_seed_ceetm1_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134977 + pr_debug("Qman: The channel allocator of CEETM %d includes"
134978 + " range %d:%d\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134979 +
134980 + /* Set CEETM PRES register */
134981 + ret = qman_ceetm_set_prescaler(dcp_portal);
134982 + if (ret)
134983 + return ret;
134984 + return 0;
134985 +}
134986 +
134987 +static void qman_get_ip_revision(struct device_node *dn)
134988 +{
134989 + u16 ip_rev = 0;
134990 + u8 ip_cfg = QMAN_REV_CFG_0;
134991 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
134992 + if (!of_device_is_available(dn))
134993 + continue;
134994 + if (of_device_is_compatible(dn, "fsl,qman-portal-1.0") ||
134995 + of_device_is_compatible(dn, "fsl,qman-portal-1.0.0")) {
134996 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
134997 + BUG_ON(1);
134998 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.1") ||
134999 + of_device_is_compatible(dn, "fsl,qman-portal-1.1.0")) {
135000 + ip_rev = QMAN_REV11;
135001 + qman_portal_max = 10;
135002 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.2") ||
135003 + of_device_is_compatible(dn, "fsl,qman-portal-1.2.0")) {
135004 + ip_rev = QMAN_REV12;
135005 + qman_portal_max = 10;
135006 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-2.0") ||
135007 + of_device_is_compatible(dn, "fsl,qman-portal-2.0.0")) {
135008 + ip_rev = QMAN_REV20;
135009 + qman_portal_max = 3;
135010 + } else if (of_device_is_compatible(dn,
135011 + "fsl,qman-portal-3.0.0")) {
135012 + ip_rev = QMAN_REV30;
135013 + qman_portal_max = 50;
135014 + } else if (of_device_is_compatible(dn,
135015 + "fsl,qman-portal-3.0.1")) {
135016 + ip_rev = QMAN_REV30;
135017 + qman_portal_max = 25;
135018 + ip_cfg = QMAN_REV_CFG_1;
135019 + } else if (of_device_is_compatible(dn,
135020 + "fsl,qman-portal-3.1.0")) {
135021 + ip_rev = QMAN_REV31;
135022 + qman_portal_max = 50;
135023 + } else if (of_device_is_compatible(dn,
135024 + "fsl,qman-portal-3.1.1")) {
135025 + ip_rev = QMAN_REV31;
135026 + qman_portal_max = 25;
135027 + ip_cfg = QMAN_REV_CFG_1;
135028 + } else if (of_device_is_compatible(dn,
135029 + "fsl,qman-portal-3.1.2")) {
135030 + ip_rev = QMAN_REV31;
135031 + qman_portal_max = 18;
135032 + ip_cfg = QMAN_REV_CFG_2;
135033 + } else if (of_device_is_compatible(dn,
135034 + "fsl,qman-portal-3.1.3")) {
135035 + ip_rev = QMAN_REV31;
135036 + qman_portal_max = 10;
135037 + ip_cfg = QMAN_REV_CFG_3;
135038 + } else if (of_device_is_compatible(dn,
135039 + "fsl,qman-portal-3.2.0")) {
135040 + ip_rev = QMAN_REV32;
135041 + qman_portal_max = 10;
135042 + ip_cfg = QMAN_REV_CFG_3; // TODO: Verify for ls1043
135043 + } else if (of_device_is_compatible(dn,
135044 + "fsl,qman-portal-3.2.1")) {
135045 + ip_rev = QMAN_REV32;
135046 + qman_portal_max = 10;
135047 + ip_cfg = QMAN_REV_CFG_3;
135048 + } else {
135049 + pr_warn("unknown QMan version in portal node,"
135050 + "default to rev1.1\n");
135051 + ip_rev = QMAN_REV11;
135052 + qman_portal_max = 10;
135053 + }
135054 +
135055 + if (!qman_ip_rev) {
135056 + if (ip_rev) {
135057 + qman_ip_rev = ip_rev;
135058 + qman_ip_cfg = ip_cfg;
135059 + } else {
135060 + pr_warn("unknown Qman version,"
135061 + " default to rev1.1\n");
135062 + qman_ip_rev = QMAN_REV11;
135063 + qman_ip_cfg = QMAN_REV_CFG_0;
135064 + }
135065 + } else if (ip_rev && (qman_ip_rev != ip_rev))
135066 + pr_warn("Revision=0x%04x, but portal '%s' has"
135067 + " 0x%04x\n",
135068 + qman_ip_rev, dn->full_name, ip_rev);
135069 + if (qman_ip_rev == ip_rev)
135070 + break;
135071 + }
135072 +}
135073 +
135074 +/* Parse a portal node, perform generic mapping duties and return the config. It
135075 + * is not known at this stage for what purpose (or even if) the portal will be
135076 + * used. */
135077 +static struct qm_portal_config * __init parse_pcfg(struct device_node *node)
135078 +{
135079 + struct qm_portal_config *pcfg;
135080 + const u32 *index_p;
135081 + u32 index, channel;
135082 + int irq, ret;
135083 + resource_size_t len;
135084 +
135085 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
135086 + if (!pcfg) {
135087 + pr_err("can't allocate portal config");
135088 + return NULL;
135089 + }
135090 +
135091 + /*
135092 + * This is a *horrible hack*, but the IOMMU/PAMU driver needs a
135093 + * 'struct device' in order to get the PAMU stashing setup and the QMan
135094 + * portal [driver] won't function at all without ring stashing
135095 + *
135096 + * Making the QMan portal driver nice and proper is part of the
135097 + * upstreaming effort
135098 + */
135099 + pcfg->dev.bus = &platform_bus_type;
135100 + pcfg->dev.of_node = node;
135101 +#ifdef CONFIG_FSL_PAMU
135102 + pcfg->dev.archdata.iommu_domain = NULL;
135103 +#endif
135104 +
135105 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
135106 + &pcfg->addr_phys[DPA_PORTAL_CE]);
135107 + if (ret) {
135108 + pr_err("Can't get %s property '%s'\n", node->full_name,
135109 + "reg::CE");
135110 + goto err;
135111 + }
135112 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
135113 + &pcfg->addr_phys[DPA_PORTAL_CI]);
135114 + if (ret) {
135115 + pr_err("Can't get %s property '%s'\n", node->full_name,
135116 + "reg::CI");
135117 + goto err;
135118 + }
135119 + index_p = of_get_property(node, "cell-index", &ret);
135120 + if (!index_p || (ret != 4)) {
135121 + pr_err("Can't get %s property '%s'\n", node->full_name,
135122 + "cell-index");
135123 + goto err;
135124 + }
135125 + index = be32_to_cpu(*index_p);
135126 + if (index >= qman_portal_max) {
135127 + pr_err("QMan portal index %d is beyond max (%d)\n",
135128 + index, qman_portal_max);
135129 + goto err;
135130 + }
135131 +
135132 + channel = index + QM_CHANNEL_SWPORTAL0;
135133 + pcfg->public_cfg.channel = channel;
135134 + pcfg->public_cfg.cpu = -1;
135135 + irq = irq_of_parse_and_map(node, 0);
135136 + if (irq == 0) {
135137 + pr_err("Can't get %s property '%s'\n", node->full_name,
135138 + "interrupts");
135139 + goto err;
135140 + }
135141 + pcfg->public_cfg.irq = irq;
135142 + pcfg->public_cfg.index = index;
135143 +#ifdef CONFIG_FSL_QMAN_CONFIG
135144 + /* We need the same LIODN offset for all portals */
135145 + qman_liodn_fixup(pcfg->public_cfg.channel);
135146 +#endif
135147 +
135148 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
135149 + if (len != (unsigned long)len)
135150 + goto err;
135151 +
135152 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
135153 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
135154 + pcfg->addr_phys[DPA_PORTAL_CE].start,
135155 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
135156 +
135157 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
135158 + pcfg->addr_phys[DPA_PORTAL_CI].start,
135159 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
135160 +#else
135161 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
135162 + pcfg->addr_phys[DPA_PORTAL_CE].start,
135163 + (unsigned long)len,
135164 + 0);
135165 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
135166 + pcfg->addr_phys[DPA_PORTAL_CI].start,
135167 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
135168 + _PAGE_GUARDED | _PAGE_NO_CACHE);
135169 +#endif
135170 + return pcfg;
135171 +err:
135172 + kfree(pcfg);
135173 + return NULL;
135174 +}
135175 +
135176 +static struct qm_portal_config *get_pcfg(struct list_head *list)
135177 +{
135178 + struct qm_portal_config *pcfg;
135179 + if (list_empty(list))
135180 + return NULL;
135181 + pcfg = list_entry(list->prev, struct qm_portal_config, list);
135182 + list_del(&pcfg->list);
135183 + return pcfg;
135184 +}
135185 +
135186 +static struct qm_portal_config *get_pcfg_idx(struct list_head *list, u32 idx)
135187 +{
135188 + struct qm_portal_config *pcfg;
135189 + if (list_empty(list))
135190 + return NULL;
135191 + list_for_each_entry(pcfg, list, list) {
135192 + if (pcfg->public_cfg.index == idx) {
135193 + list_del(&pcfg->list);
135194 + return pcfg;
135195 + }
135196 + }
135197 + return NULL;
135198 +}
135199 +
135200 +static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu)
135201 +{
135202 +#ifdef CONFIG_FSL_PAMU
135203 + int ret;
135204 + int window_count = 1;
135205 + struct iommu_domain_geometry geom_attr;
135206 + struct pamu_stash_attribute stash_attr;
135207 +
135208 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
135209 + if (!pcfg->iommu_domain) {
135210 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
135211 + __func__);
135212 + goto _no_iommu;
135213 + }
135214 + geom_attr.aperture_start = 0;
135215 + geom_attr.aperture_end =
135216 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
135217 + geom_attr.force_aperture = true;
135218 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
135219 + &geom_attr);
135220 + if (ret < 0) {
135221 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135222 + __func__, ret);
135223 + goto _iommu_domain_free;
135224 + }
135225 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
135226 + &window_count);
135227 + if (ret < 0) {
135228 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135229 + __func__, ret);
135230 + goto _iommu_domain_free;
135231 + }
135232 + stash_attr.cpu = cpu;
135233 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
135234 + /* set stash information for the window */
135235 + stash_attr.window = 0;
135236 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135237 + DOMAIN_ATTR_FSL_PAMU_STASH,
135238 + &stash_attr);
135239 + if (ret < 0) {
135240 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135241 + __func__, ret);
135242 + goto _iommu_domain_free;
135243 + }
135244 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
135245 + IOMMU_READ | IOMMU_WRITE);
135246 + if (ret < 0) {
135247 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
135248 + __func__, ret);
135249 + goto _iommu_domain_free;
135250 + }
135251 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
135252 + if (ret < 0) {
135253 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
135254 + __func__, ret);
135255 + goto _iommu_domain_free;
135256 + }
135257 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135258 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
135259 + &window_count);
135260 + if (ret < 0) {
135261 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135262 + __func__, ret);
135263 + goto _iommu_detach_device;
135264 + }
135265 +
135266 +_no_iommu:
135267 +#endif
135268 +#ifdef CONFIG_FSL_QMAN_CONFIG
135269 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
135270 +#endif
135271 + pr_warn("Failed to set QMan portal's stash request queue\n");
135272 +
135273 + return;
135274 +
135275 +#ifdef CONFIG_FSL_PAMU
135276 +_iommu_detach_device:
135277 + iommu_detach_device(pcfg->iommu_domain, NULL);
135278 +_iommu_domain_free:
135279 + iommu_domain_free(pcfg->iommu_domain);
135280 +#endif
135281 +}
135282 +
135283 +struct qm_portal_config *qm_get_unused_portal_idx(u32 idx)
135284 +{
135285 + struct qm_portal_config *ret;
135286 + spin_lock(&unused_pcfgs_lock);
135287 + if (idx == QBMAN_ANY_PORTAL_IDX)
135288 + ret = get_pcfg(&unused_pcfgs);
135289 + else
135290 + ret = get_pcfg_idx(&unused_pcfgs, idx);
135291 + spin_unlock(&unused_pcfgs_lock);
135292 + /* Bind stashing LIODNs to the CPU we are currently executing on, and
135293 + * set the portal to use the stashing request queue corresonding to the
135294 + * cpu as well. The user-space driver assumption is that the pthread has
135295 + * to already be affine to one cpu only before opening a portal. If that
135296 + * check is circumvented, the only risk is a performance degradation -
135297 + * stashing will go to whatever cpu they happened to be running on when
135298 + * opening the device file, and if that isn't the cpu they subsequently
135299 + * bind to and do their polling on, tough. */
135300 + if (ret)
135301 + portal_set_cpu(ret, hard_smp_processor_id());
135302 + return ret;
135303 +}
135304 +
135305 +struct qm_portal_config *qm_get_unused_portal(void)
135306 +{
135307 + return qm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
135308 +}
135309 +
135310 +void qm_put_unused_portal(struct qm_portal_config *pcfg)
135311 +{
135312 + spin_lock(&unused_pcfgs_lock);
135313 + list_add(&pcfg->list, &unused_pcfgs);
135314 + spin_unlock(&unused_pcfgs_lock);
135315 +}
135316 +
135317 +static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg)
135318 +{
135319 + struct qman_portal *p;
135320 +
135321 + pcfg->iommu_domain = NULL;
135322 + portal_set_cpu(pcfg, pcfg->public_cfg.cpu);
135323 + p = qman_create_affine_portal(pcfg, NULL);
135324 + if (p) {
135325 + u32 irq_sources = 0;
135326 + /* Determine what should be interrupt-vs-poll driven */
135327 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
135328 + irq_sources |= QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI |
135329 + QM_PIRQ_CSCI | QM_PIRQ_CCSCI;
135330 +#endif
135331 +#ifdef CONFIG_FSL_DPA_PIRQ_FAST
135332 + irq_sources |= QM_PIRQ_DQRI;
135333 +#endif
135334 + qman_p_irqsource_add(p, irq_sources);
135335 + pr_info("Qman portal %sinitialised, cpu %d\n",
135336 + pcfg->public_cfg.is_shared ? "(shared) " : "",
135337 + pcfg->public_cfg.cpu);
135338 + } else
135339 + pr_crit("Qman portal failure on cpu %d\n",
135340 + pcfg->public_cfg.cpu);
135341 + return p;
135342 +}
135343 +
135344 +static void init_slave(int cpu)
135345 +{
135346 + struct qman_portal *p;
135347 + struct cpumask oldmask = current->cpus_allowed;
135348 + set_cpus_allowed_ptr(current, get_cpu_mask(cpu));
135349 + p = qman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
135350 + if (!p)
135351 + pr_err("Qman slave portal failure on cpu %d\n", cpu);
135352 + else
135353 + pr_info("Qman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
135354 + set_cpus_allowed_ptr(current, &oldmask);
135355 + if (shared_portals_idx >= num_shared_portals)
135356 + shared_portals_idx = 0;
135357 +}
135358 +
135359 +static struct cpumask want_unshared __initdata;
135360 +static struct cpumask want_shared __initdata;
135361 +
135362 +static int __init parse_qportals(char *str)
135363 +{
135364 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
135365 + "qportals");
135366 +}
135367 +__setup("qportals=", parse_qportals);
135368 +
135369 +static void qman_portal_update_sdest(const struct qm_portal_config *pcfg,
135370 + unsigned int cpu)
135371 +{
135372 +#ifdef CONFIG_FSL_PAMU
135373 + struct pamu_stash_attribute stash_attr;
135374 + int ret;
135375 +
135376 + if (pcfg->iommu_domain) {
135377 + stash_attr.cpu = cpu;
135378 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
135379 + /* set stash information for the window */
135380 + stash_attr.window = 0;
135381 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135382 + DOMAIN_ATTR_FSL_PAMU_STASH, &stash_attr);
135383 + if (ret < 0) {
135384 + pr_err("Failed to update pamu stash setting\n");
135385 + return;
135386 + }
135387 + }
135388 +#endif
135389 +#ifdef CONFIG_FSL_QMAN_CONFIG
135390 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
135391 + pr_warn("Failed to update portal's stash request queue\n");
135392 +#endif
135393 +}
135394 +
135395 +static int qman_offline_cpu(unsigned int cpu)
135396 +{
135397 + struct qman_portal *p;
135398 + const struct qm_portal_config *pcfg;
135399 + p = (struct qman_portal *)affine_portals[cpu];
135400 + if (p) {
135401 + pcfg = qman_get_qm_portal_config(p);
135402 + if (pcfg) {
135403 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
135404 + qman_portal_update_sdest(pcfg, 0);
135405 + }
135406 + }
135407 + return 0;
135408 +}
135409 +
135410 +#ifdef CONFIG_HOTPLUG_CPU
135411 +static int qman_online_cpu(unsigned int cpu)
135412 +{
135413 + struct qman_portal *p;
135414 + const struct qm_portal_config *pcfg;
135415 + p = (struct qman_portal *)affine_portals[cpu];
135416 + if (p) {
135417 + pcfg = qman_get_qm_portal_config(p);
135418 + if (pcfg) {
135419 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
135420 + qman_portal_update_sdest(pcfg, cpu);
135421 + }
135422 + }
135423 + return 0;
135424 +}
135425 +
135426 +static int qman_hotplug_cpu_callback(struct notifier_block *nfb,
135427 + unsigned long action, void *hcpu)
135428 +{
135429 + unsigned int cpu = (unsigned long)hcpu;
135430 +
135431 + switch (action) {
135432 + case CPU_ONLINE:
135433 + case CPU_ONLINE_FROZEN:
135434 + qman_online_cpu(cpu);
135435 + break;
135436 + case CPU_DOWN_PREPARE:
135437 + case CPU_DOWN_PREPARE_FROZEN:
135438 + qman_offline_cpu(cpu);
135439 + default:
135440 + break;
135441 + }
135442 + return NOTIFY_OK;
135443 +}
135444 +
135445 +static struct notifier_block qman_hotplug_cpu_notifier = {
135446 + .notifier_call = qman_hotplug_cpu_callback,
135447 +};
135448 +#endif /* CONFIG_HOTPLUG_CPU */
135449 +
135450 +__init int qman_init(void)
135451 +{
135452 + struct cpumask slave_cpus;
135453 + struct cpumask unshared_cpus = *cpu_none_mask;
135454 + struct cpumask shared_cpus = *cpu_none_mask;
135455 + LIST_HEAD(unshared_pcfgs);
135456 + LIST_HEAD(shared_pcfgs);
135457 + struct device_node *dn;
135458 + struct qm_portal_config *pcfg;
135459 + struct qman_portal *p;
135460 + int cpu, ret;
135461 + const u32 *clk;
135462 + struct cpumask offline_cpus;
135463 +
135464 + /* Initialise the Qman (CCSR) device */
135465 + for_each_compatible_node(dn, NULL, "fsl,qman") {
135466 + if (!qman_init_ccsr(dn))
135467 + pr_info("Qman err interrupt handler present\n");
135468 + else
135469 + pr_err("Qman CCSR setup failed\n");
135470 +
135471 + clk = of_get_property(dn, "clock-frequency", NULL);
135472 + if (!clk)
135473 + pr_warn("Can't find Qman clock frequency\n");
135474 + else
135475 + qman_clk = be32_to_cpu(*clk);
135476 + }
135477 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
135478 + /* Setup lookup table for FQ demux */
135479 + ret = qman_setup_fq_lookup_table(get_qman_fqd_size()/64);
135480 + if (ret)
135481 + return ret;
135482 +#endif
135483 +
135484 + /* Get qman ip revision */
135485 + qman_get_ip_revision(dn);
135486 + if ((qman_ip_rev & 0xff00) >= QMAN_REV30) {
135487 + qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3;
135488 + qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
135489 + qm_channel_pme = QMAN_CHANNEL_PME_REV3;
135490 + }
135491 +
135492 + if ((qman_ip_rev == QMAN_REV31) && (qman_ip_cfg == QMAN_REV_CFG_2))
135493 + qm_channel_dce = QMAN_CHANNEL_DCE_QMANREV312;
135494 +
135495 + /*
135496 + * Parse the ceetm node to get how many ceetm instances are supported
135497 + * on the current silicon. num_ceetms must be confirmed before portals
135498 + * are intiailized.
135499 + */
135500 + num_ceetms = 0;
135501 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm")
135502 + num_ceetms++;
135503 +
135504 + /* Parse pool channels into the SDQCR mask. (Must happen before portals
135505 + * are initialised.) */
135506 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
135507 + ret = fsl_pool_channel_range_sdqcr(dn);
135508 + if (ret)
135509 + return ret;
135510 + }
135511 +
135512 + memset(affine_portals, 0, sizeof(void *) * num_possible_cpus());
135513 + /* Initialise portals. See bman_driver.c for comments */
135514 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
135515 + if (!of_device_is_available(dn))
135516 + continue;
135517 + pcfg = parse_pcfg(dn);
135518 + if (pcfg) {
135519 + pcfg->public_cfg.pools = pools_sdqcr;
135520 + list_add_tail(&pcfg->list, &unused_pcfgs);
135521 + }
135522 + }
135523 + for_each_possible_cpu(cpu) {
135524 + if (cpumask_test_cpu(cpu, &want_shared)) {
135525 + pcfg = get_pcfg(&unused_pcfgs);
135526 + if (!pcfg)
135527 + break;
135528 + pcfg->public_cfg.cpu = cpu;
135529 + list_add_tail(&pcfg->list, &shared_pcfgs);
135530 + cpumask_set_cpu(cpu, &shared_cpus);
135531 + }
135532 + if (cpumask_test_cpu(cpu, &want_unshared)) {
135533 + if (cpumask_test_cpu(cpu, &shared_cpus))
135534 + continue;
135535 + pcfg = get_pcfg(&unused_pcfgs);
135536 + if (!pcfg)
135537 + break;
135538 + pcfg->public_cfg.cpu = cpu;
135539 + list_add_tail(&pcfg->list, &unshared_pcfgs);
135540 + cpumask_set_cpu(cpu, &unshared_cpus);
135541 + }
135542 + }
135543 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
135544 + for_each_online_cpu(cpu) {
135545 + pcfg = get_pcfg(&unused_pcfgs);
135546 + if (!pcfg)
135547 + break;
135548 + pcfg->public_cfg.cpu = cpu;
135549 + list_add_tail(&pcfg->list, &unshared_pcfgs);
135550 + cpumask_set_cpu(cpu, &unshared_cpus);
135551 + }
135552 + }
135553 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
135554 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
135555 + if (cpumask_empty(&slave_cpus)) {
135556 + if (!list_empty(&shared_pcfgs)) {
135557 + cpumask_or(&unshared_cpus, &unshared_cpus,
135558 + &shared_cpus);
135559 + cpumask_clear(&shared_cpus);
135560 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
135561 + INIT_LIST_HEAD(&shared_pcfgs);
135562 + }
135563 + } else {
135564 + if (list_empty(&shared_pcfgs)) {
135565 + pcfg = get_pcfg(&unshared_pcfgs);
135566 + if (!pcfg) {
135567 + pr_crit("No QMan portals available!\n");
135568 + return 0;
135569 + }
135570 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
135571 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
135572 + list_add_tail(&pcfg->list, &shared_pcfgs);
135573 + }
135574 + }
135575 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
135576 + pcfg->public_cfg.is_shared = 0;
135577 + p = init_pcfg(pcfg);
135578 + if (!p) {
135579 + pr_crit("Unable to configure portals\n");
135580 + return 0;
135581 + }
135582 + }
135583 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
135584 + pcfg->public_cfg.is_shared = 1;
135585 + p = init_pcfg(pcfg);
135586 + if (p)
135587 + shared_portals[num_shared_portals++] = p;
135588 + }
135589 + if (!cpumask_empty(&slave_cpus))
135590 + for_each_cpu(cpu, &slave_cpus)
135591 + init_slave(cpu);
135592 + pr_info("Qman portals initialised\n");
135593 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
135594 + for_each_cpu(cpu, &offline_cpus)
135595 + qman_offline_cpu(cpu);
135596 +#ifdef CONFIG_HOTPLUG_CPU
135597 + register_hotcpu_notifier(&qman_hotplug_cpu_notifier);
135598 +#endif
135599 + return 0;
135600 +}
135601 +
135602 +__init int qman_resource_init(void)
135603 +{
135604 + struct device_node *dn;
135605 + int ret;
135606 +
135607 + /* Initialise FQID allocation ranges */
135608 + for_each_compatible_node(dn, NULL, "fsl,fqid-range") {
135609 + ret = fsl_fqid_range_init(dn);
135610 + if (ret)
135611 + return ret;
135612 + }
135613 + /* Initialise CGRID allocation ranges */
135614 + for_each_compatible_node(dn, NULL, "fsl,cgrid-range") {
135615 + ret = fsl_cgrid_range_init(dn);
135616 + if (ret)
135617 + return ret;
135618 + }
135619 + /* Parse pool channels into the allocator. (Must happen after portals
135620 + * are initialised.) */
135621 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
135622 + ret = fsl_pool_channel_range_init(dn);
135623 + if (ret)
135624 + return ret;
135625 + }
135626 +
135627 + /* Parse CEETM */
135628 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm") {
135629 + ret = fsl_ceetm_init(dn);
135630 + if (ret)
135631 + return ret;
135632 + }
135633 + return 0;
135634 +}
135635 +
135636 +#ifdef CONFIG_SUSPEND
135637 +void suspend_unused_qportal(void)
135638 +{
135639 + struct qm_portal_config *pcfg;
135640 +
135641 + if (list_empty(&unused_pcfgs))
135642 + return;
135643 +
135644 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
135645 +#ifdef CONFIG_PM_DEBUG
135646 + pr_info("Need to save qportal %d\n", pcfg->public_cfg.index);
135647 +#endif
135648 + /* save isdr, disable all via isdr, clear isr */
135649 + pcfg->saved_isdr =
135650 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
135651 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
135652 + 0xe08);
135653 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
135654 + 0xe00);
135655 + }
135656 + return;
135657 +}
135658 +
135659 +void resume_unused_qportal(void)
135660 +{
135661 + struct qm_portal_config *pcfg;
135662 +
135663 + if (list_empty(&unused_pcfgs))
135664 + return;
135665 +
135666 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
135667 +#ifdef CONFIG_PM_DEBUG
135668 + pr_info("Need to resume qportal %d\n", pcfg->public_cfg.index);
135669 +#endif
135670 + /* restore isdr */
135671 + __raw_writel(pcfg->saved_isdr,
135672 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
135673 + }
135674 + return;
135675 +}
135676 +#endif
135677 --- /dev/null
135678 +++ b/drivers/staging/fsl_qbman/qman_high.c
135679 @@ -0,0 +1,5669 @@
135680 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
135681 + *
135682 + * Redistribution and use in source and binary forms, with or without
135683 + * modification, are permitted provided that the following conditions are met:
135684 + * * Redistributions of source code must retain the above copyright
135685 + * notice, this list of conditions and the following disclaimer.
135686 + * * Redistributions in binary form must reproduce the above copyright
135687 + * notice, this list of conditions and the following disclaimer in the
135688 + * documentation and/or other materials provided with the distribution.
135689 + * * Neither the name of Freescale Semiconductor nor the
135690 + * names of its contributors may be used to endorse or promote products
135691 + * derived from this software without specific prior written permission.
135692 + *
135693 + *
135694 + * ALTERNATIVELY, this software may be distributed under the terms of the
135695 + * GNU General Public License ("GPL") as published by the Free Software
135696 + * Foundation, either version 2 of that License or (at your option) any
135697 + * later version.
135698 + *
135699 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
135700 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
135701 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
135702 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
135703 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
135704 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
135705 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
135706 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
135707 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
135708 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
135709 + */
135710 +
135711 +#include "qman_low.h"
135712 +
135713 +/* Compilation constants */
135714 +#define DQRR_MAXFILL 15
135715 +#define EQCR_ITHRESH 4 /* if EQCR congests, interrupt threshold */
135716 +#define IRQNAME "QMan portal %d"
135717 +#define MAX_IRQNAME 16 /* big enough for "QMan portal %d" */
135718 +
135719 +/* Divide 'n' by 'd', rounding down if 'r' is negative, rounding up if it's
135720 + * positive, and rounding to the closest value if it's zero. NB, this macro
135721 + * implicitly upgrades parameters to unsigned 64-bit, so feed it with types
135722 + * that are compatible with this. NB, these arguments should not be expressions
135723 + * unless it is safe for them to be evaluated multiple times. Eg. do not pass
135724 + * in "some_value++" as a parameter to the macro! */
135725 +#define ROUNDING(n, d, r) \
135726 + (((r) < 0) ? div64_u64((n), (d)) : \
135727 + (((r) > 0) ? div64_u64(((n) + (d) - 1), (d)) : \
135728 + div64_u64(((n) + ((d) / 2)), (d))))
135729 +
135730 +/* Lock/unlock frame queues, subject to the "LOCKED" flag. This is about
135731 + * inter-processor locking only. Note, FQLOCK() is always called either under a
135732 + * local_irq_save() or from interrupt context - hence there's no need for irq
135733 + * protection (and indeed, attempting to nest irq-protection doesn't work, as
135734 + * the "irq en/disable" machinery isn't recursive...). */
135735 +#define FQLOCK(fq) \
135736 + do { \
135737 + struct qman_fq *__fq478 = (fq); \
135738 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
135739 + spin_lock(&__fq478->fqlock); \
135740 + } while (0)
135741 +#define FQUNLOCK(fq) \
135742 + do { \
135743 + struct qman_fq *__fq478 = (fq); \
135744 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
135745 + spin_unlock(&__fq478->fqlock); \
135746 + } while (0)
135747 +
135748 +static inline void fq_set(struct qman_fq *fq, u32 mask)
135749 +{
135750 + set_bits(mask, &fq->flags);
135751 +}
135752 +static inline void fq_clear(struct qman_fq *fq, u32 mask)
135753 +{
135754 + clear_bits(mask, &fq->flags);
135755 +}
135756 +static inline int fq_isset(struct qman_fq *fq, u32 mask)
135757 +{
135758 + return fq->flags & mask;
135759 +}
135760 +static inline int fq_isclear(struct qman_fq *fq, u32 mask)
135761 +{
135762 + return !(fq->flags & mask);
135763 +}
135764 +
135765 +struct qman_portal {
135766 + struct qm_portal p;
135767 + unsigned long bits; /* PORTAL_BITS_*** - dynamic, strictly internal */
135768 + unsigned long irq_sources;
135769 + u32 use_eqcr_ci_stashing;
135770 + u32 slowpoll; /* only used when interrupts are off */
135771 + struct qman_fq *vdqcr_owned; /* only 1 volatile dequeue at a time */
135772 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
135773 + struct qman_fq *eqci_owned; /* only 1 enqueue WAIT_SYNC at a time */
135774 +#endif
135775 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
135776 + raw_spinlock_t sharing_lock; /* only used if is_shared */
135777 + int is_shared;
135778 + struct qman_portal *sharing_redirect;
135779 +#endif
135780 + u32 sdqcr;
135781 + int dqrr_disable_ref;
135782 + /* A portal-specific handler for DCP ERNs. If this is NULL, the global
135783 + * handler is called instead. */
135784 + qman_cb_dc_ern cb_dc_ern;
135785 + /* When the cpu-affine portal is activated, this is non-NULL */
135786 + const struct qm_portal_config *config;
135787 + /* This is needed for providing a non-NULL device to dma_map_***() */
135788 + struct platform_device *pdev;
135789 + struct dpa_rbtree retire_table;
135790 + char irqname[MAX_IRQNAME];
135791 + /* 2-element array. cgrs[0] is mask, cgrs[1] is snapshot. */
135792 + struct qman_cgrs *cgrs;
135793 + /* linked-list of CSCN handlers. */
135794 + struct list_head cgr_cbs;
135795 + /* list lock */
135796 + spinlock_t cgr_lock;
135797 + /* 2-element array. ccgrs[0] is mask, ccgrs[1] is snapshot. */
135798 + struct qman_ccgrs *ccgrs[QMAN_CEETM_MAX];
135799 + /* 256-element array, each is a linked-list of CCSCN handlers. */
135800 + struct list_head ccgr_cbs[QMAN_CEETM_MAX];
135801 + /* list lock */
135802 + spinlock_t ccgr_lock;
135803 + /* track if memory was allocated by the driver */
135804 + u8 alloced;
135805 + /* power management data */
135806 + u32 save_isdr;
135807 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
135808 + /* Keep a shadow copy of the DQRR on LE systems as the SW needs to
135809 + * do byte swaps of DQRR read only memory. First entry must be aligned
135810 + * to 2 ** 10 to ensure DQRR index calculations based shadow copy
135811 + * address (6 bits for address shift + 4 bits for the DQRR size).
135812 + */
135813 + struct qm_dqrr_entry shadow_dqrr[QM_DQRR_SIZE] __aligned(1024);
135814 +#endif
135815 +};
135816 +
135817 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
135818 +#define PORTAL_IRQ_LOCK(p, irqflags) \
135819 + do { \
135820 + if ((p)->is_shared) \
135821 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
135822 + else \
135823 + local_irq_save(irqflags); \
135824 + } while (0)
135825 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
135826 + do { \
135827 + if ((p)->is_shared) \
135828 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
135829 + irqflags); \
135830 + else \
135831 + local_irq_restore(irqflags); \
135832 + } while (0)
135833 +#else
135834 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
135835 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
135836 +#endif
135837 +
135838 +/* Global handler for DCP ERNs. Used when the portal receiving the message does
135839 + * not have a portal-specific handler. */
135840 +static qman_cb_dc_ern cb_dc_ern;
135841 +
135842 +static cpumask_t affine_mask;
135843 +static DEFINE_SPINLOCK(affine_mask_lock);
135844 +static u16 affine_channels[NR_CPUS];
135845 +static DEFINE_PER_CPU(struct qman_portal, qman_affine_portal);
135846 +void *affine_portals[NR_CPUS];
135847 +
135848 +/* "raw" gets the cpu-local struct whether it's a redirect or not. */
135849 +static inline struct qman_portal *get_raw_affine_portal(void)
135850 +{
135851 + return &get_cpu_var(qman_affine_portal);
135852 +}
135853 +/* For ops that can redirect, this obtains the portal to use */
135854 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
135855 +static inline struct qman_portal *get_affine_portal(void)
135856 +{
135857 + struct qman_portal *p = get_raw_affine_portal();
135858 + if (p->sharing_redirect)
135859 + return p->sharing_redirect;
135860 + return p;
135861 +}
135862 +#else
135863 +#define get_affine_portal() get_raw_affine_portal()
135864 +#endif
135865 +/* For every "get", there must be a "put" */
135866 +static inline void put_affine_portal(void)
135867 +{
135868 + put_cpu_var(qman_affine_portal);
135869 +}
135870 +/* Exception: poll functions assume the caller is cpu-affine and in no risk of
135871 + * re-entrance, which are the two reasons we usually use the get/put_cpu_var()
135872 + * semantic - ie. to disable pre-emption. Some use-cases expect the execution
135873 + * context to remain as non-atomic during poll-triggered callbacks as it was
135874 + * when the poll API was first called (eg. NAPI), so we go out of our way in
135875 + * this case to not disable pre-emption. */
135876 +static inline struct qman_portal *get_poll_portal(void)
135877 +{
135878 + return &get_cpu_var(qman_affine_portal);
135879 +}
135880 +#define put_poll_portal()
135881 +
135882 +/* This gives a FQID->FQ lookup to cover the fact that we can't directly demux
135883 + * retirement notifications (the fact they are sometimes h/w-consumed means that
135884 + * contextB isn't always a s/w demux - and as we can't know which case it is
135885 + * when looking at the notification, we have to use the slow lookup for all of
135886 + * them). NB, it's possible to have multiple FQ objects refer to the same FQID
135887 + * (though at most one of them should be the consumer), so this table isn't for
135888 + * all FQs - FQs are added when retirement commands are issued, and removed when
135889 + * they complete, which also massively reduces the size of this table. */
135890 +IMPLEMENT_DPA_RBTREE(fqtree, struct qman_fq, node, fqid);
135891 +
135892 +/* This is what everything can wait on, even if it migrates to a different cpu
135893 + * to the one whose affine portal it is waiting on. */
135894 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
135895 +
135896 +static inline int table_push_fq(struct qman_portal *p, struct qman_fq *fq)
135897 +{
135898 + int ret = fqtree_push(&p->retire_table, fq);
135899 + if (ret)
135900 + pr_err("ERROR: double FQ-retirement %d\n", fq->fqid);
135901 + return ret;
135902 +}
135903 +
135904 +static inline void table_del_fq(struct qman_portal *p, struct qman_fq *fq)
135905 +{
135906 + fqtree_del(&p->retire_table, fq);
135907 +}
135908 +
135909 +static inline struct qman_fq *table_find_fq(struct qman_portal *p, u32 fqid)
135910 +{
135911 + return fqtree_find(&p->retire_table, fqid);
135912 +}
135913 +
135914 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
135915 +static void **qman_fq_lookup_table;
135916 +static size_t qman_fq_lookup_table_size;
135917 +
135918 +int qman_setup_fq_lookup_table(size_t num_entries)
135919 +{
135920 + num_entries++;
135921 + /* Allocate 1 more entry since the first entry is not used */
135922 + qman_fq_lookup_table = vzalloc((num_entries * sizeof(void *)));
135923 + if (!qman_fq_lookup_table) {
135924 + pr_err("QMan: Could not allocate fq lookup table\n");
135925 + return -ENOMEM;
135926 + }
135927 + qman_fq_lookup_table_size = num_entries;
135928 + pr_info("QMan: Allocated lookup table at %p, entry count %lu\n",
135929 + qman_fq_lookup_table,
135930 + (unsigned long)qman_fq_lookup_table_size);
135931 + return 0;
135932 +}
135933 +
135934 +/* global structure that maintains fq object mapping */
135935 +static DEFINE_SPINLOCK(fq_hash_table_lock);
135936 +
135937 +static int find_empty_fq_table_entry(u32 *entry, struct qman_fq *fq)
135938 +{
135939 + u32 i;
135940 +
135941 + spin_lock(&fq_hash_table_lock);
135942 + /* Can't use index zero because this has special meaning
135943 + * in context_b field. */
135944 + for (i = 1; i < qman_fq_lookup_table_size; i++) {
135945 + if (qman_fq_lookup_table[i] == NULL) {
135946 + *entry = i;
135947 + qman_fq_lookup_table[i] = fq;
135948 + spin_unlock(&fq_hash_table_lock);
135949 + return 0;
135950 + }
135951 + }
135952 + spin_unlock(&fq_hash_table_lock);
135953 + return -ENOMEM;
135954 +}
135955 +
135956 +static void clear_fq_table_entry(u32 entry)
135957 +{
135958 + spin_lock(&fq_hash_table_lock);
135959 + BUG_ON(entry >= qman_fq_lookup_table_size);
135960 + qman_fq_lookup_table[entry] = NULL;
135961 + spin_unlock(&fq_hash_table_lock);
135962 +}
135963 +
135964 +static inline struct qman_fq *get_fq_table_entry(u32 entry)
135965 +{
135966 + BUG_ON(entry >= qman_fq_lookup_table_size);
135967 + return qman_fq_lookup_table[entry];
135968 +}
135969 +#endif
135970 +
135971 +static inline void cpu_to_hw_fqd(struct qm_fqd *fqd)
135972 +{
135973 + /* Byteswap the FQD to HW format */
135974 + fqd->fq_ctrl = cpu_to_be16(fqd->fq_ctrl);
135975 + fqd->dest_wq = cpu_to_be16(fqd->dest_wq);
135976 + fqd->ics_cred = cpu_to_be16(fqd->ics_cred);
135977 + fqd->context_b = cpu_to_be32(fqd->context_b);
135978 + fqd->context_a.opaque = cpu_to_be64(fqd->context_a.opaque);
135979 +}
135980 +
135981 +static inline void hw_fqd_to_cpu(struct qm_fqd *fqd)
135982 +{
135983 + /* Byteswap the FQD to CPU format */
135984 + fqd->fq_ctrl = be16_to_cpu(fqd->fq_ctrl);
135985 + fqd->dest_wq = be16_to_cpu(fqd->dest_wq);
135986 + fqd->ics_cred = be16_to_cpu(fqd->ics_cred);
135987 + fqd->context_b = be32_to_cpu(fqd->context_b);
135988 + fqd->context_a.opaque = be64_to_cpu(fqd->context_a.opaque);
135989 +}
135990 +
135991 +/* Swap a 40 bit address */
135992 +static inline u64 cpu_to_be40(u64 in)
135993 +{
135994 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
135995 + return in;
135996 +#else
135997 + u64 out = 0;
135998 + u8 *p = (u8 *) &out;
135999 + p[0] = in >> 32;
136000 + p[1] = in >> 24;
136001 + p[2] = in >> 16;
136002 + p[3] = in >> 8;
136003 + p[4] = in >> 0;
136004 + return out;
136005 +#endif
136006 +}
136007 +static inline u64 be40_to_cpu(u64 in)
136008 +{
136009 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136010 + return in;
136011 +#else
136012 + u64 out = 0;
136013 + u8 *pout = (u8 *) &out;
136014 + u8 *pin = (u8 *) &in;
136015 + pout[0] = pin[4];
136016 + pout[1] = pin[3];
136017 + pout[2] = pin[2];
136018 + pout[3] = pin[1];
136019 + pout[4] = pin[0];
136020 + return out;
136021 +#endif
136022 +}
136023 +
136024 +/* Swap a 24 bit value */
136025 +static inline u32 cpu_to_be24(u32 in)
136026 +{
136027 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136028 + return in;
136029 +#else
136030 + u32 out = 0;
136031 + u8 *p = (u8 *) &out;
136032 + p[0] = in >> 16;
136033 + p[1] = in >> 8;
136034 + p[2] = in >> 0;
136035 + return out;
136036 +#endif
136037 +}
136038 +
136039 +static inline u32 be24_to_cpu(u32 in)
136040 +{
136041 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136042 + return in;
136043 +#else
136044 + u32 out = 0;
136045 + u8 *pout = (u8 *) &out;
136046 + u8 *pin = (u8 *) &in;
136047 + pout[0] = pin[2];
136048 + pout[1] = pin[1];
136049 + pout[2] = pin[0];
136050 + return out;
136051 +#endif
136052 +}
136053 +
136054 +static inline u64 be48_to_cpu(u64 in)
136055 +{
136056 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136057 + return in;
136058 +#else
136059 + u64 out = 0;
136060 + u8 *pout = (u8 *) &out;
136061 + u8 *pin = (u8 *) &in;
136062 +
136063 + pout[0] = pin[5];
136064 + pout[1] = pin[4];
136065 + pout[2] = pin[3];
136066 + pout[3] = pin[2];
136067 + pout[4] = pin[1];
136068 + pout[5] = pin[0];
136069 + return out;
136070 +#endif
136071 +}
136072 +static inline void cpu_to_hw_fd(struct qm_fd *fd)
136073 +{
136074 + fd->opaque_addr = cpu_to_be64(fd->opaque_addr);
136075 + fd->status = cpu_to_be32(fd->status);
136076 + fd->opaque = cpu_to_be32(fd->opaque);
136077 +}
136078 +
136079 +static inline void hw_fd_to_cpu(struct qm_fd *fd)
136080 +{
136081 + fd->opaque_addr = be64_to_cpu(fd->opaque_addr);
136082 + fd->status = be32_to_cpu(fd->status);
136083 + fd->opaque = be32_to_cpu(fd->opaque);
136084 +}
136085 +
136086 +static inline void hw_cq_query_to_cpu(struct qm_mcr_ceetm_cq_query *cq_query)
136087 +{
136088 + cq_query->ccgid = be16_to_cpu(cq_query->ccgid);
136089 + cq_query->state = be16_to_cpu(cq_query->state);
136090 + cq_query->pfdr_hptr = be24_to_cpu(cq_query->pfdr_hptr);
136091 + cq_query->pfdr_tptr = be24_to_cpu(cq_query->pfdr_tptr);
136092 + cq_query->od1_xsfdr = be16_to_cpu(cq_query->od1_xsfdr);
136093 + cq_query->od2_xsfdr = be16_to_cpu(cq_query->od2_xsfdr);
136094 + cq_query->od3_xsfdr = be16_to_cpu(cq_query->od3_xsfdr);
136095 + cq_query->od4_xsfdr = be16_to_cpu(cq_query->od4_xsfdr);
136096 + cq_query->od5_xsfdr = be16_to_cpu(cq_query->od5_xsfdr);
136097 + cq_query->od6_xsfdr = be16_to_cpu(cq_query->od6_xsfdr);
136098 + cq_query->ra1_xsfdr = be16_to_cpu(cq_query->ra1_xsfdr);
136099 + cq_query->ra2_xsfdr = be16_to_cpu(cq_query->ra2_xsfdr);
136100 + cq_query->frm_cnt = be24_to_cpu(cq_query->frm_cnt);
136101 +}
136102 +
136103 +static inline void hw_ccgr_query_to_cpu(struct qm_mcr_ceetm_ccgr_query *ccgr_q)
136104 +{
136105 + int i;
136106 +
136107 + ccgr_q->cm_query.cs_thres.hword =
136108 + be16_to_cpu(ccgr_q->cm_query.cs_thres.hword);
136109 + ccgr_q->cm_query.cs_thres_x.hword =
136110 + be16_to_cpu(ccgr_q->cm_query.cs_thres_x.hword);
136111 + ccgr_q->cm_query.td_thres.hword =
136112 + be16_to_cpu(ccgr_q->cm_query.td_thres.hword);
136113 + ccgr_q->cm_query.wr_parm_g.word =
136114 + be32_to_cpu(ccgr_q->cm_query.wr_parm_g.word);
136115 + ccgr_q->cm_query.wr_parm_y.word =
136116 + be32_to_cpu(ccgr_q->cm_query.wr_parm_y.word);
136117 + ccgr_q->cm_query.wr_parm_r.word =
136118 + be32_to_cpu(ccgr_q->cm_query.wr_parm_r.word);
136119 + ccgr_q->cm_query.cscn_targ_dcp =
136120 + be16_to_cpu(ccgr_q->cm_query.cscn_targ_dcp);
136121 + ccgr_q->cm_query.i_cnt = be40_to_cpu(ccgr_q->cm_query.i_cnt);
136122 + ccgr_q->cm_query.a_cnt = be40_to_cpu(ccgr_q->cm_query.a_cnt);
136123 + for (i = 0; i < ARRAY_SIZE(ccgr_q->cm_query.cscn_targ_swp); i++)
136124 + ccgr_q->cm_query.cscn_targ_swp[i] =
136125 + be32_to_cpu(ccgr_q->cm_query.cscn_targ_swp[i]);
136126 +}
136127 +
136128 +/* In the case that slow- and fast-path handling are both done by qman_poll()
136129 + * (ie. because there is no interrupt handling), we ought to balance how often
136130 + * we do the fast-path poll versus the slow-path poll. We'll use two decrementer
136131 + * sources, so we call the fast poll 'n' times before calling the slow poll
136132 + * once. The idle decrementer constant is used when the last slow-poll detected
136133 + * no work to do, and the busy decrementer constant when the last slow-poll had
136134 + * work to do. */
136135 +#define SLOW_POLL_IDLE 1000
136136 +#define SLOW_POLL_BUSY 10
136137 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is);
136138 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
136139 + unsigned int poll_limit);
136140 +
136141 +/* Portal interrupt handler */
136142 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
136143 +{
136144 + struct qman_portal *p = ptr;
136145 + /*
136146 + * The CSCI/CCSCI source is cleared inside __poll_portal_slow(), because
136147 + * it could race against a Query Congestion State command also given
136148 + * as part of the handling of this interrupt source. We mustn't
136149 + * clear it a second time in this top-level function.
136150 + */
136151 + u32 clear = QM_DQAVAIL_MASK | (p->irq_sources &
136152 + ~(QM_PIRQ_CSCI | QM_PIRQ_CCSCI));
136153 + u32 is = qm_isr_status_read(&p->p) & p->irq_sources;
136154 + /* DQRR-handling if it's interrupt-driven */
136155 + if (is & QM_PIRQ_DQRI)
136156 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
136157 + /* Handling of anything else that's interrupt-driven */
136158 + clear |= __poll_portal_slow(p, is);
136159 + qm_isr_status_clear(&p->p, clear);
136160 + return IRQ_HANDLED;
136161 +}
136162 +
136163 +/* This inner version is used privately by qman_create_affine_portal(), as well
136164 + * as by the exported qman_stop_dequeues(). */
136165 +static inline void qman_stop_dequeues_ex(struct qman_portal *p)
136166 +{
136167 + unsigned long irqflags __maybe_unused;
136168 + PORTAL_IRQ_LOCK(p, irqflags);
136169 + if (!(p->dqrr_disable_ref++))
136170 + qm_dqrr_set_maxfill(&p->p, 0);
136171 + PORTAL_IRQ_UNLOCK(p, irqflags);
136172 +}
136173 +
136174 +static int drain_mr_fqrni(struct qm_portal *p)
136175 +{
136176 + const struct qm_mr_entry *msg;
136177 +loop:
136178 + msg = qm_mr_current(p);
136179 + if (!msg) {
136180 + /* if MR was full and h/w had other FQRNI entries to produce, we
136181 + * need to allow it time to produce those entries once the
136182 + * existing entries are consumed. A worst-case situation
136183 + * (fully-loaded system) means h/w sequencers may have to do 3-4
136184 + * other things before servicing the portal's MR pump, each of
136185 + * which (if slow) may take ~50 qman cycles (which is ~200
136186 + * processor cycles). So rounding up and then multiplying this
136187 + * worst-case estimate by a factor of 10, just to be
136188 + * ultra-paranoid, goes as high as 10,000 cycles. NB, we consume
136189 + * one entry at a time, so h/w has an opportunity to produce new
136190 + * entries well before the ring has been fully consumed, so
136191 + * we're being *really* paranoid here. */
136192 + u64 now, then = mfatb();
136193 + do {
136194 + now = mfatb();
136195 + } while ((then + 10000) > now);
136196 + msg = qm_mr_current(p);
136197 + if (!msg)
136198 + return 0;
136199 + }
136200 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) != QM_MR_VERB_FQRNI) {
136201 + /* We aren't draining anything but FQRNIs */
136202 + pr_err("QMan found verb 0x%x in MR\n", msg->verb);
136203 + return -1;
136204 + }
136205 + qm_mr_next(p);
136206 + qm_mr_cci_consume(p, 1);
136207 + goto loop;
136208 +}
136209 +
136210 +#ifdef CONFIG_SUSPEND
136211 +static int _qman_portal_suspend_noirq(struct device *dev)
136212 +{
136213 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136214 +#ifdef CONFIG_PM_DEBUG
136215 + struct platform_device *pdev = to_platform_device(dev);
136216 +#endif
136217 +
136218 + p->save_isdr = qm_isr_disable_read(&p->p);
136219 + qm_isr_disable_write(&p->p, 0xffffffff);
136220 + qm_isr_status_clear(&p->p, 0xffffffff);
136221 +#ifdef CONFIG_PM_DEBUG
136222 + pr_info("Suspend for %s\n", pdev->name);
136223 +#endif
136224 + return 0;
136225 +}
136226 +
136227 +static int _qman_portal_resume_noirq(struct device *dev)
136228 +{
136229 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136230 +
136231 + /* restore isdr */
136232 + qm_isr_disable_write(&p->p, p->save_isdr);
136233 + return 0;
136234 +}
136235 +#else
136236 +#define _qman_portal_suspend_noirq NULL
136237 +#define _qman_portal_resume_noirq NULL
136238 +#endif
136239 +
136240 +struct dev_pm_domain qman_portal_device_pm_domain = {
136241 + .ops = {
136242 + USE_PLATFORM_PM_SLEEP_OPS
136243 + .suspend_noirq = _qman_portal_suspend_noirq,
136244 + .resume_noirq = _qman_portal_resume_noirq,
136245 + }
136246 +};
136247 +
136248 +struct qman_portal *qman_create_portal(
136249 + struct qman_portal *portal,
136250 + const struct qm_portal_config *config,
136251 + const struct qman_cgrs *cgrs)
136252 +{
136253 + struct qm_portal *__p;
136254 + char buf[16];
136255 + int ret;
136256 + u32 isdr;
136257 +
136258 + if (!portal) {
136259 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
136260 + if (!portal)
136261 + return portal;
136262 + portal->alloced = 1;
136263 + } else
136264 + portal->alloced = 0;
136265 +
136266 + __p = &portal->p;
136267 +
136268 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && defined CONFIG_FSL_PAMU
136269 + /* PAMU is required for stashing */
136270 + portal->use_eqcr_ci_stashing = ((qman_ip_rev >= QMAN_REV30) ?
136271 + 1 : 0);
136272 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136273 + portal->use_eqcr_ci_stashing = 1;
136274 +#else
136275 + portal->use_eqcr_ci_stashing = 0;
136276 +#endif
136277 +
136278 + /* prep the low-level portal struct with the mapped addresses from the
136279 + * config, everything that follows depends on it and "config" is more
136280 + * for (de)reference... */
136281 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
136282 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
136283 + /*
136284 + * If CI-stashing is used, the current defaults use a threshold of 3,
136285 + * and stash with high-than-DQRR priority.
136286 + */
136287 + if (qm_eqcr_init(__p, qm_eqcr_pvb,
136288 + portal->use_eqcr_ci_stashing ? 3 : 0, 1)) {
136289 + pr_err("Qman EQCR initialisation failed\n");
136290 + goto fail_eqcr;
136291 + }
136292 + if (qm_dqrr_init(__p, config, qm_dqrr_dpush, qm_dqrr_pvb,
136293 + qm_dqrr_cdc, DQRR_MAXFILL)) {
136294 + pr_err("Qman DQRR initialisation failed\n");
136295 + goto fail_dqrr;
136296 + }
136297 + if (qm_mr_init(__p, qm_mr_pvb, qm_mr_cci)) {
136298 + pr_err("Qman MR initialisation failed\n");
136299 + goto fail_mr;
136300 + }
136301 + if (qm_mc_init(__p)) {
136302 + pr_err("Qman MC initialisation failed\n");
136303 + goto fail_mc;
136304 + }
136305 + if (qm_isr_init(__p)) {
136306 + pr_err("Qman ISR initialisation failed\n");
136307 + goto fail_isr;
136308 + }
136309 + /* static interrupt-gating controls */
136310 + qm_dqrr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_DQRR_ITHRESH);
136311 + qm_mr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_MR_ITHRESH);
136312 + qm_isr_set_iperiod(__p, CONFIG_FSL_QMAN_PIRQ_IPERIOD);
136313 + portal->cgrs = kmalloc(2 * sizeof(*cgrs), GFP_KERNEL);
136314 + if (!portal->cgrs)
136315 + goto fail_cgrs;
136316 + /* initial snapshot is no-depletion */
136317 + qman_cgrs_init(&portal->cgrs[1]);
136318 + if (cgrs)
136319 + portal->cgrs[0] = *cgrs;
136320 + else
136321 + /* if the given mask is NULL, assume all CGRs can be seen */
136322 + qman_cgrs_fill(&portal->cgrs[0]);
136323 + INIT_LIST_HEAD(&portal->cgr_cbs);
136324 + spin_lock_init(&portal->cgr_lock);
136325 + if (num_ceetms) {
136326 + for (ret = 0; ret < num_ceetms; ret++) {
136327 + portal->ccgrs[ret] = kmalloc(2 *
136328 + sizeof(struct qman_ccgrs), GFP_KERNEL);
136329 + if (!portal->ccgrs[ret])
136330 + goto fail_ccgrs;
136331 + qman_ccgrs_init(&portal->ccgrs[ret][1]);
136332 + qman_ccgrs_fill(&portal->ccgrs[ret][0]);
136333 + INIT_LIST_HEAD(&portal->ccgr_cbs[ret]);
136334 + }
136335 + }
136336 + spin_lock_init(&portal->ccgr_lock);
136337 + portal->bits = 0;
136338 + portal->slowpoll = 0;
136339 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
136340 + portal->eqci_owned = NULL;
136341 +#endif
136342 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136343 + raw_spin_lock_init(&portal->sharing_lock);
136344 + portal->is_shared = config->public_cfg.is_shared;
136345 + portal->sharing_redirect = NULL;
136346 +#endif
136347 + portal->sdqcr = QM_SDQCR_SOURCE_CHANNELS | QM_SDQCR_COUNT_UPTO3 |
136348 + QM_SDQCR_DEDICATED_PRECEDENCE | QM_SDQCR_TYPE_PRIO_QOS |
136349 + QM_SDQCR_TOKEN_SET(0xab) | QM_SDQCR_CHANNELS_DEDICATED;
136350 + portal->dqrr_disable_ref = 0;
136351 + portal->cb_dc_ern = NULL;
136352 + sprintf(buf, "qportal-%d", config->public_cfg.channel);
136353 + portal->pdev = platform_device_alloc(buf, -1);
136354 + if (!portal->pdev) {
136355 + pr_err("qman_portal - platform_device_alloc() failed\n");
136356 + goto fail_devalloc;
136357 + }
136358 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136359 + portal->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
136360 + portal->pdev->dev.dma_mask = &portal->pdev->dev.coherent_dma_mask;
136361 +#else
136362 + if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) {
136363 + pr_err("qman_portal - dma_set_mask() failed\n");
136364 + goto fail_devadd;
136365 + }
136366 +#endif
136367 + portal->pdev->dev.pm_domain = &qman_portal_device_pm_domain;
136368 + portal->pdev->dev.platform_data = portal;
136369 + ret = platform_device_add(portal->pdev);
136370 + if (ret) {
136371 + pr_err("qman_portal - platform_device_add() failed\n");
136372 + goto fail_devadd;
136373 + }
136374 + dpa_rbtree_init(&portal->retire_table);
136375 + isdr = 0xffffffff;
136376 + qm_isr_disable_write(__p, isdr);
136377 + portal->irq_sources = 0;
136378 + qm_isr_enable_write(__p, portal->irq_sources);
136379 + qm_isr_status_clear(__p, 0xffffffff);
136380 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
136381 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
136382 + portal)) {
136383 + pr_err("request_irq() failed\n");
136384 + goto fail_irq;
136385 + }
136386 + if ((config->public_cfg.cpu != -1) &&
136387 + irq_can_set_affinity(config->public_cfg.irq) &&
136388 + irq_set_affinity(config->public_cfg.irq,
136389 + cpumask_of(config->public_cfg.cpu))) {
136390 + pr_err("irq_set_affinity() failed\n");
136391 + goto fail_affinity;
136392 + }
136393 +
136394 + /* Need EQCR to be empty before continuing */
136395 + isdr ^= QM_PIRQ_EQCI;
136396 + qm_isr_disable_write(__p, isdr);
136397 + ret = qm_eqcr_get_fill(__p);
136398 + if (ret) {
136399 + pr_err("Qman EQCR unclean\n");
136400 + goto fail_eqcr_empty;
136401 + }
136402 + isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI);
136403 + qm_isr_disable_write(__p, isdr);
136404 + if (qm_dqrr_current(__p) != NULL) {
136405 + pr_err("Qman DQRR unclean\n");
136406 + qm_dqrr_cdc_consume_n(__p, 0xffff);
136407 + }
136408 + if (qm_mr_current(__p) != NULL) {
136409 + /* special handling, drain just in case it's a few FQRNIs */
136410 + if (drain_mr_fqrni(__p)) {
136411 + const struct qm_mr_entry *e = qm_mr_current(__p);
136412 + /*
136413 + * Message ring cannot be empty no need to check
136414 + * qm_mr_current returned successfully
136415 + */
136416 + pr_err("Qman MR unclean, MR VERB 0x%x, rc 0x%x\n, addr 0x%x",
136417 + e->verb, e->ern.rc, e->ern.fd.addr_lo);
136418 + goto fail_dqrr_mr_empty;
136419 + }
136420 + }
136421 + /* Success */
136422 + portal->config = config;
136423 + qm_isr_disable_write(__p, 0);
136424 + qm_isr_uninhibit(__p);
136425 + /* Write a sane SDQCR */
136426 + qm_dqrr_sdqcr_set(__p, portal->sdqcr);
136427 + return portal;
136428 +fail_dqrr_mr_empty:
136429 +fail_eqcr_empty:
136430 +fail_affinity:
136431 + free_irq(config->public_cfg.irq, portal);
136432 +fail_irq:
136433 + platform_device_del(portal->pdev);
136434 +fail_devadd:
136435 + platform_device_put(portal->pdev);
136436 +fail_devalloc:
136437 + if (num_ceetms)
136438 + for (ret = 0; ret < num_ceetms; ret++)
136439 + kfree(portal->ccgrs[ret]);
136440 +fail_ccgrs:
136441 + kfree(portal->cgrs);
136442 +fail_cgrs:
136443 + qm_isr_finish(__p);
136444 +fail_isr:
136445 + qm_mc_finish(__p);
136446 +fail_mc:
136447 + qm_mr_finish(__p);
136448 +fail_mr:
136449 + qm_dqrr_finish(__p);
136450 +fail_dqrr:
136451 + qm_eqcr_finish(__p);
136452 +fail_eqcr:
136453 + if (portal->alloced)
136454 + kfree(portal);
136455 + return NULL;
136456 +}
136457 +
136458 +struct qman_portal *qman_create_affine_portal(
136459 + const struct qm_portal_config *config,
136460 + const struct qman_cgrs *cgrs)
136461 +{
136462 + struct qman_portal *res;
136463 + struct qman_portal *portal;
136464 +
136465 + portal = &per_cpu(qman_affine_portal, config->public_cfg.cpu);
136466 + res = qman_create_portal(portal, config, cgrs);
136467 + if (res) {
136468 + spin_lock(&affine_mask_lock);
136469 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
136470 + affine_channels[config->public_cfg.cpu] =
136471 + config->public_cfg.channel;
136472 + affine_portals[config->public_cfg.cpu] = portal;
136473 + spin_unlock(&affine_mask_lock);
136474 + }
136475 + return res;
136476 +}
136477 +
136478 +/* These checks are BUG_ON()s because the driver is already supposed to avoid
136479 + * these cases. */
136480 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
136481 + int cpu)
136482 +{
136483 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136484 + struct qman_portal *p;
136485 + p = &per_cpu(qman_affine_portal, cpu);
136486 + /* Check that we don't already have our own portal */
136487 + BUG_ON(p->config);
136488 + /* Check that we aren't already slaving to another portal */
136489 + BUG_ON(p->is_shared);
136490 + /* Check that 'redirect' is prepared to have us */
136491 + BUG_ON(!redirect->config->public_cfg.is_shared);
136492 + /* These are the only elements to initialise when redirecting */
136493 + p->irq_sources = 0;
136494 + p->sharing_redirect = redirect;
136495 + affine_portals[cpu] = p;
136496 + return p;
136497 +#else
136498 + BUG();
136499 + return NULL;
136500 +#endif
136501 +}
136502 +
136503 +void qman_destroy_portal(struct qman_portal *qm)
136504 +{
136505 + const struct qm_portal_config *pcfg;
136506 + int i;
136507 +
136508 + /* Stop dequeues on the portal */
136509 + qm_dqrr_sdqcr_set(&qm->p, 0);
136510 +
136511 + /* NB we do this to "quiesce" EQCR. If we add enqueue-completions or
136512 + * something related to QM_PIRQ_EQCI, this may need fixing.
136513 + * Also, due to the prefetching model used for CI updates in the enqueue
136514 + * path, this update will only invalidate the CI cacheline *after*
136515 + * working on it, so we need to call this twice to ensure a full update
136516 + * irrespective of where the enqueue processing was at when the teardown
136517 + * began. */
136518 + qm_eqcr_cce_update(&qm->p);
136519 + qm_eqcr_cce_update(&qm->p);
136520 + pcfg = qm->config;
136521 +
136522 + free_irq(pcfg->public_cfg.irq, qm);
136523 +
136524 + kfree(qm->cgrs);
136525 + if (num_ceetms)
136526 + for (i = 0; i < num_ceetms; i++)
136527 + kfree(qm->ccgrs[i]);
136528 + qm_isr_finish(&qm->p);
136529 + qm_mc_finish(&qm->p);
136530 + qm_mr_finish(&qm->p);
136531 + qm_dqrr_finish(&qm->p);
136532 + qm_eqcr_finish(&qm->p);
136533 +
136534 + platform_device_del(qm->pdev);
136535 + platform_device_put(qm->pdev);
136536 +
136537 + qm->config = NULL;
136538 + if (qm->alloced)
136539 + kfree(qm);
136540 +}
136541 +
136542 +const struct qm_portal_config *qman_destroy_affine_portal(void)
136543 +{
136544 + /* We don't want to redirect if we're a slave, use "raw" */
136545 + struct qman_portal *qm = get_raw_affine_portal();
136546 + const struct qm_portal_config *pcfg;
136547 + int cpu;
136548 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136549 + if (qm->sharing_redirect) {
136550 + qm->sharing_redirect = NULL;
136551 + put_affine_portal();
136552 + return NULL;
136553 + }
136554 + qm->is_shared = 0;
136555 +#endif
136556 + pcfg = qm->config;
136557 + cpu = pcfg->public_cfg.cpu;
136558 +
136559 + qman_destroy_portal(qm);
136560 +
136561 + spin_lock(&affine_mask_lock);
136562 + cpumask_clear_cpu(cpu, &affine_mask);
136563 + spin_unlock(&affine_mask_lock);
136564 + put_affine_portal();
136565 + return pcfg;
136566 +}
136567 +
136568 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal *p)
136569 +{
136570 + return &p->config->public_cfg;
136571 +}
136572 +EXPORT_SYMBOL(qman_p_get_portal_config);
136573 +
136574 +const struct qman_portal_config *qman_get_portal_config(void)
136575 +{
136576 + struct qman_portal *p = get_affine_portal();
136577 + const struct qman_portal_config *ret = qman_p_get_portal_config(p);
136578 + put_affine_portal();
136579 + return ret;
136580 +}
136581 +EXPORT_SYMBOL(qman_get_portal_config);
136582 +
136583 +/* Inline helper to reduce nesting in __poll_portal_slow() */
136584 +static inline void fq_state_change(struct qman_portal *p, struct qman_fq *fq,
136585 + const struct qm_mr_entry *msg, u8 verb)
136586 +{
136587 + FQLOCK(fq);
136588 + switch (verb) {
136589 + case QM_MR_VERB_FQRL:
136590 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_ORL));
136591 + fq_clear(fq, QMAN_FQ_STATE_ORL);
136592 + table_del_fq(p, fq);
136593 + break;
136594 + case QM_MR_VERB_FQRN:
136595 + DPA_ASSERT((fq->state == qman_fq_state_parked) ||
136596 + (fq->state == qman_fq_state_sched));
136597 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_CHANGING));
136598 + fq_clear(fq, QMAN_FQ_STATE_CHANGING);
136599 + if (msg->fq.fqs & QM_MR_FQS_NOTEMPTY)
136600 + fq_set(fq, QMAN_FQ_STATE_NE);
136601 + if (msg->fq.fqs & QM_MR_FQS_ORLPRESENT)
136602 + fq_set(fq, QMAN_FQ_STATE_ORL);
136603 + else
136604 + table_del_fq(p, fq);
136605 + fq->state = qman_fq_state_retired;
136606 + break;
136607 + case QM_MR_VERB_FQPN:
136608 + DPA_ASSERT(fq->state == qman_fq_state_sched);
136609 + DPA_ASSERT(fq_isclear(fq, QMAN_FQ_STATE_CHANGING));
136610 + fq->state = qman_fq_state_parked;
136611 + }
136612 + FQUNLOCK(fq);
136613 +}
136614 +
136615 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is)
136616 +{
136617 + const struct qm_mr_entry *msg;
136618 + struct qm_mr_entry swapped_msg;
136619 + int k;
136620 +
136621 + if (is & QM_PIRQ_CSCI) {
136622 + struct qman_cgrs rr, c;
136623 + struct qm_mc_result *mcr;
136624 + struct qman_cgr *cgr;
136625 + unsigned long irqflags __maybe_unused;
136626 +
136627 + spin_lock_irqsave(&p->cgr_lock, irqflags);
136628 + /*
136629 + * The CSCI bit must be cleared _before_ issuing the
136630 + * Query Congestion State command, to ensure that a long
136631 + * CGR State Change callback cannot miss an intervening
136632 + * state change.
136633 + */
136634 + qm_isr_status_clear(&p->p, QM_PIRQ_CSCI);
136635 + qm_mc_start(&p->p);
136636 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
136637 + while (!(mcr = qm_mc_result(&p->p)))
136638 + cpu_relax();
136639 + for (k = 0; k < 8; k++)
136640 + mcr->querycongestion.state.__state[k] = be32_to_cpu(
136641 + mcr->querycongestion.state.__state[k]);
136642 + /* mask out the ones I'm not interested in */
136643 + qman_cgrs_and(&rr, (const struct qman_cgrs *)
136644 + &mcr->querycongestion.state, &p->cgrs[0]);
136645 + /* check previous snapshot for delta, enter/exit congestion */
136646 + qman_cgrs_xor(&c, &rr, &p->cgrs[1]);
136647 + /* update snapshot */
136648 + qman_cgrs_cp(&p->cgrs[1], &rr);
136649 + /* Invoke callback */
136650 + list_for_each_entry(cgr, &p->cgr_cbs, node)
136651 + if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
136652 + cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
136653 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
136654 + }
136655 + if (is & QM_PIRQ_CCSCI) {
136656 + struct qman_ccgrs rr, c, congestion_result;
136657 + struct qm_mc_result *mcr;
136658 + struct qm_mc_command *mcc;
136659 + struct qm_ceetm_ccg *ccg;
136660 + unsigned long irqflags __maybe_unused;
136661 + int i, j;
136662 +
136663 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
136664 + /*
136665 + * The CCSCI bit must be cleared _before_ issuing the
136666 + * Query Congestion State command, to ensure that a long
136667 + * CCGR State Change callback cannot miss an intervening
136668 + * state change.
136669 + */
136670 + qm_isr_status_clear(&p->p, QM_PIRQ_CCSCI);
136671 +
136672 + for (i = 0; i < num_ceetms; i++) {
136673 + for (j = 0; j < 2; j++) {
136674 + mcc = qm_mc_start(&p->p);
136675 + mcc->ccgr_query.ccgrid = cpu_to_be16(
136676 + CEETM_QUERY_CONGESTION_STATE | j);
136677 + mcc->ccgr_query.dcpid = i;
136678 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
136679 + while (!(mcr = qm_mc_result(&p->p)))
136680 + cpu_relax();
136681 + for (k = 0; k < 8; k++)
136682 + mcr->ccgr_query.congestion_state.state.
136683 + __state[k] = be32_to_cpu(
136684 + mcr->ccgr_query.
136685 + congestion_state.state.
136686 + __state[k]);
136687 + congestion_result.q[j] =
136688 + mcr->ccgr_query.congestion_state.state;
136689 + }
136690 + /* mask out the ones I'm not interested in */
136691 + qman_ccgrs_and(&rr, &congestion_result,
136692 + &p->ccgrs[i][0]);
136693 + /*
136694 + * check previous snapshot for delta, enter/exit
136695 + * congestion.
136696 + */
136697 + qman_ccgrs_xor(&c, &rr, &p->ccgrs[i][1]);
136698 + /* update snapshot */
136699 + qman_ccgrs_cp(&p->ccgrs[i][1], &rr);
136700 + /* Invoke callback */
136701 + list_for_each_entry(ccg, &p->ccgr_cbs[i], cb_node)
136702 + if (ccg->cb && qman_ccgrs_get(&c,
136703 + (ccg->parent->idx << 4) | ccg->idx))
136704 + ccg->cb(ccg, ccg->cb_ctx,
136705 + qman_ccgrs_get(&rr,
136706 + (ccg->parent->idx << 4)
136707 + | ccg->idx));
136708 + }
136709 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
136710 + }
136711 +
136712 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
136713 + if (is & QM_PIRQ_EQCI) {
136714 + unsigned long irqflags;
136715 + PORTAL_IRQ_LOCK(p, irqflags);
136716 + p->eqci_owned = NULL;
136717 + PORTAL_IRQ_UNLOCK(p, irqflags);
136718 + wake_up(&affine_queue);
136719 + }
136720 +#endif
136721 +
136722 + if (is & QM_PIRQ_EQRI) {
136723 + unsigned long irqflags __maybe_unused;
136724 + PORTAL_IRQ_LOCK(p, irqflags);
136725 + qm_eqcr_cce_update(&p->p);
136726 + qm_eqcr_set_ithresh(&p->p, 0);
136727 + PORTAL_IRQ_UNLOCK(p, irqflags);
136728 + wake_up(&affine_queue);
136729 + }
136730 +
136731 + if (is & QM_PIRQ_MRI) {
136732 + struct qman_fq *fq;
136733 + u8 verb, num = 0;
136734 +mr_loop:
136735 + qm_mr_pvb_update(&p->p);
136736 + msg = qm_mr_current(&p->p);
136737 + if (!msg)
136738 + goto mr_done;
136739 + swapped_msg = *msg;
136740 + hw_fd_to_cpu(&swapped_msg.ern.fd);
136741 + verb = msg->verb & QM_MR_VERB_TYPE_MASK;
136742 + /* The message is a software ERN iff the 0x20 bit is set */
136743 + if (verb & 0x20) {
136744 + switch (verb) {
136745 + case QM_MR_VERB_FQRNI:
136746 + /* nada, we drop FQRNIs on the floor */
136747 + break;
136748 + case QM_MR_VERB_FQRN:
136749 + case QM_MR_VERB_FQRL:
136750 + /* Lookup in the retirement table */
136751 + fq = table_find_fq(p, be32_to_cpu(msg->fq.fqid));
136752 + BUG_ON(!fq);
136753 + fq_state_change(p, fq, &swapped_msg, verb);
136754 + if (fq->cb.fqs)
136755 + fq->cb.fqs(p, fq, &swapped_msg);
136756 + break;
136757 + case QM_MR_VERB_FQPN:
136758 + /* Parked */
136759 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136760 + fq = get_fq_table_entry(
136761 + be32_to_cpu(msg->fq.contextB));
136762 +#else
136763 + fq = (void *)(uintptr_t)
136764 + be32_to_cpu(msg->fq.contextB);
136765 +#endif
136766 + fq_state_change(p, fq, msg, verb);
136767 + if (fq->cb.fqs)
136768 + fq->cb.fqs(p, fq, &swapped_msg);
136769 + break;
136770 + case QM_MR_VERB_DC_ERN:
136771 + /* DCP ERN */
136772 + if (p->cb_dc_ern)
136773 + p->cb_dc_ern(p, msg);
136774 + else if (cb_dc_ern)
136775 + cb_dc_ern(p, msg);
136776 + else {
136777 + static int warn_once;
136778 + if (!warn_once) {
136779 + pr_crit("Leaking DCP ERNs!\n");
136780 + warn_once = 1;
136781 + }
136782 + }
136783 + break;
136784 + default:
136785 + pr_crit("Invalid MR verb 0x%02x\n", verb);
136786 + }
136787 + } else {
136788 + /* Its a software ERN */
136789 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136790 + fq = get_fq_table_entry(be32_to_cpu(msg->ern.tag));
136791 +#else
136792 + fq = (void *)(uintptr_t)be32_to_cpu(msg->ern.tag);
136793 +#endif
136794 + fq->cb.ern(p, fq, &swapped_msg);
136795 + }
136796 + num++;
136797 + qm_mr_next(&p->p);
136798 + goto mr_loop;
136799 +mr_done:
136800 + qm_mr_cci_consume(&p->p, num);
136801 + }
136802 + /*
136803 + * QM_PIRQ_CSCI/CCSCI has already been cleared, as part of its specific
136804 + * processing. If that interrupt source has meanwhile been re-asserted,
136805 + * we mustn't clear it here (or in the top-level interrupt handler).
136806 + */
136807 + return is & (QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI);
136808 +}
136809 +
136810 +/* remove some slowish-path stuff from the "fast path" and make sure it isn't
136811 + * inlined. */
136812 +static noinline void clear_vdqcr(struct qman_portal *p, struct qman_fq *fq)
136813 +{
136814 + p->vdqcr_owned = NULL;
136815 + FQLOCK(fq);
136816 + fq_clear(fq, QMAN_FQ_STATE_VDQCR);
136817 + FQUNLOCK(fq);
136818 + wake_up(&affine_queue);
136819 +}
136820 +
136821 +/* Copy a DQRR entry ensuring reads reach QBMan in order */
136822 +static inline void safe_copy_dqrr(struct qm_dqrr_entry *dst,
136823 + const struct qm_dqrr_entry *src)
136824 +{
136825 + int i = 0;
136826 + const u64 *s64 = (u64*)src;
136827 + u64 *d64 = (u64*)dst;
136828 +
136829 + /* DQRR only has 32 bytes of valid data so only need to
136830 + * copy 4 - 64 bit values */
136831 + *d64 = *s64;
136832 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136833 + {
136834 + u32 res, zero = 0;
136835 + /* Create a dependancy after copying first bytes ensures no wrap
136836 + transaction generated to QBMan */
136837 + /* Logical AND the value pointed to by s64 with 0x0 and
136838 + store the result in res */
136839 + asm volatile("and %[result], %[in1], %[in2]"
136840 + : [result] "=r" (res)
136841 + : [in1] "r" (zero), [in2] "r" (*s64)
136842 + : "memory");
136843 + /* Add res to s64 - this creates a dependancy on the result of
136844 + reading the value of s64 before the next read. The side
136845 + effect of this is that the core must stall until the first
136846 + aligned read is complete therefore preventing a WRAP
136847 + transaction to be seen by the QBMan */
136848 + asm volatile("add %[result], %[in1], %[in2]"
136849 + : [result] "=r" (s64)
136850 + : [in1] "r" (res), [in2] "r" (s64)
136851 + : "memory");
136852 + }
136853 +#endif
136854 + /* Copy the last 3 64 bit parts */
136855 + d64++; s64++;
136856 + for (;i<3; i++)
136857 + *d64++ = *s64++;
136858 +}
136859 +
136860 +/* Look: no locks, no irq_save()s, no preempt_disable()s! :-) The only states
136861 + * that would conflict with other things if they ran at the same time on the
136862 + * same cpu are;
136863 + *
136864 + * (i) setting/clearing vdqcr_owned, and
136865 + * (ii) clearing the NE (Not Empty) flag.
136866 + *
136867 + * Both are safe. Because;
136868 + *
136869 + * (i) this clearing can only occur after qman_volatile_dequeue() has set the
136870 + * vdqcr_owned field (which it does before setting VDQCR), and
136871 + * qman_volatile_dequeue() blocks interrupts and preemption while this is
136872 + * done so that we can't interfere.
136873 + * (ii) the NE flag is only cleared after qman_retire_fq() has set it, and as
136874 + * with (i) that API prevents us from interfering until it's safe.
136875 + *
136876 + * The good thing is that qman_volatile_dequeue() and qman_retire_fq() run far
136877 + * less frequently (ie. per-FQ) than __poll_portal_fast() does, so the nett
136878 + * advantage comes from this function not having to "lock" anything at all.
136879 + *
136880 + * Note also that the callbacks are invoked at points which are safe against the
136881 + * above potential conflicts, but that this function itself is not re-entrant
136882 + * (this is because the function tracks one end of each FIFO in the portal and
136883 + * we do *not* want to lock that). So the consequence is that it is safe for
136884 + * user callbacks to call into any Qman API *except* qman_poll() (as that's the
136885 + * sole API that could be invoking the callback through this function).
136886 + */
136887 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
136888 + unsigned int poll_limit)
136889 +{
136890 + const struct qm_dqrr_entry *dq;
136891 + struct qman_fq *fq;
136892 + enum qman_cb_dqrr_result res;
136893 + unsigned int limit = 0;
136894 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
136895 + struct qm_dqrr_entry *shadow;
136896 + const struct qm_dqrr_entry *orig_dq;
136897 +#endif
136898 +loop:
136899 + qm_dqrr_pvb_update(&p->p);
136900 + dq = qm_dqrr_current(&p->p);
136901 + if (!dq)
136902 + goto done;
136903 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
136904 + /* If running on an LE system the fields of the
136905 + dequeue entry must be swapped. Because the
136906 + QMan HW will ignore writes the DQRR entry is
136907 + copied and the index stored within the copy */
136908 + shadow = &p->shadow_dqrr[DQRR_PTR2IDX(dq)];
136909 + /* Use safe copy here to avoid WRAP transaction */
136910 + safe_copy_dqrr(shadow, dq);
136911 + orig_dq = dq;
136912 + dq = shadow;
136913 + shadow->fqid = be32_to_cpu(shadow->fqid);
136914 + shadow->contextB = be32_to_cpu(shadow->contextB);
136915 + shadow->seqnum = be16_to_cpu(shadow->seqnum);
136916 + hw_fd_to_cpu(&shadow->fd);
136917 +#endif
136918 + if (dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
136919 + /* VDQCR: don't trust contextB as the FQ may have been
136920 + * configured for h/w consumption and we're draining it
136921 + * post-retirement. */
136922 + fq = p->vdqcr_owned;
136923 + /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
136924 + * to check for clearing it when doing volatile dequeues. It's
136925 + * one less thing to check in the critical path (SDQCR). */
136926 + if (dq->stat & QM_DQRR_STAT_FQ_EMPTY)
136927 + fq_clear(fq, QMAN_FQ_STATE_NE);
136928 + /* this is duplicated from the SDQCR code, but we have stuff to
136929 + * do before *and* after this callback, and we don't want
136930 + * multiple if()s in the critical path (SDQCR). */
136931 + res = fq->cb.dqrr(p, fq, dq);
136932 + if (res == qman_cb_dqrr_stop)
136933 + goto done;
136934 + /* Check for VDQCR completion */
136935 + if (dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
136936 + clear_vdqcr(p, fq);
136937 + } else {
136938 + /* SDQCR: contextB points to the FQ */
136939 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136940 + fq = get_fq_table_entry(dq->contextB);
136941 +#else
136942 + fq = (void *)(uintptr_t)dq->contextB;
136943 +#endif
136944 + /* Now let the callback do its stuff */
136945 + res = fq->cb.dqrr(p, fq, dq);
136946 +
136947 + /* The callback can request that we exit without consuming this
136948 + * entry nor advancing; */
136949 + if (res == qman_cb_dqrr_stop)
136950 + goto done;
136951 + }
136952 + /* Interpret 'dq' from a driver perspective. */
136953 + /* Parking isn't possible unless HELDACTIVE was set. NB,
136954 + * FORCEELIGIBLE implies HELDACTIVE, so we only need to
136955 + * check for HELDACTIVE to cover both. */
136956 + DPA_ASSERT((dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
136957 + (res != qman_cb_dqrr_park));
136958 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
136959 + if (res != qman_cb_dqrr_defer)
136960 + qm_dqrr_cdc_consume_1ptr(&p->p, orig_dq,
136961 + (res == qman_cb_dqrr_park));
136962 +#else
136963 + /* Defer just means "skip it, I'll consume it myself later on" */
136964 + if (res != qman_cb_dqrr_defer)
136965 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, (res == qman_cb_dqrr_park));
136966 +#endif
136967 + /* Move forward */
136968 + qm_dqrr_next(&p->p);
136969 + /* Entry processed and consumed, increment our counter. The callback can
136970 + * request that we exit after consuming the entry, and we also exit if
136971 + * we reach our processing limit, so loop back only if neither of these
136972 + * conditions is met. */
136973 + if ((++limit < poll_limit) && (res != qman_cb_dqrr_consume_stop))
136974 + goto loop;
136975 +done:
136976 + return limit;
136977 +}
136978 +
136979 +u32 qman_irqsource_get(void)
136980 +{
136981 + /* "irqsource" and "poll" APIs mustn't redirect when sharing, they
136982 + * should shut the user out if they are not the primary CPU hosting the
136983 + * portal. That's why we use the "raw" interface. */
136984 + struct qman_portal *p = get_raw_affine_portal();
136985 + u32 ret = p->irq_sources & QM_PIRQ_VISIBLE;
136986 + put_affine_portal();
136987 + return ret;
136988 +}
136989 +EXPORT_SYMBOL(qman_irqsource_get);
136990 +
136991 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits __maybe_unused)
136992 +{
136993 + __maybe_unused unsigned long irqflags;
136994 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136995 + if (p->sharing_redirect)
136996 + return -EINVAL;
136997 + else
136998 +#endif
136999 + {
137000 + bits = bits & QM_PIRQ_VISIBLE;
137001 + PORTAL_IRQ_LOCK(p, irqflags);
137002 +
137003 + /* Clear any previously remaining interrupt conditions in
137004 + * QCSP_ISR. This prevents raising a false interrupt when
137005 + * interrupt conditions are enabled in QCSP_IER.
137006 + */
137007 + qm_isr_status_clear(&p->p, bits);
137008 + set_bits(bits, &p->irq_sources);
137009 + qm_isr_enable_write(&p->p, p->irq_sources);
137010 + PORTAL_IRQ_UNLOCK(p, irqflags);
137011 + }
137012 + return 0;
137013 +}
137014 +EXPORT_SYMBOL(qman_p_irqsource_add);
137015 +
137016 +int qman_irqsource_add(u32 bits __maybe_unused)
137017 +{
137018 + struct qman_portal *p = get_raw_affine_portal();
137019 + int ret;
137020 + ret = qman_p_irqsource_add(p, bits);
137021 + put_affine_portal();
137022 + return ret;
137023 +}
137024 +EXPORT_SYMBOL(qman_irqsource_add);
137025 +
137026 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits)
137027 +{
137028 + __maybe_unused unsigned long irqflags;
137029 + u32 ier;
137030 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137031 + if (p->sharing_redirect) {
137032 + put_affine_portal();
137033 + return -EINVAL;
137034 + }
137035 +#endif
137036 + /* Our interrupt handler only processes+clears status register bits that
137037 + * are in p->irq_sources. As we're trimming that mask, if one of them
137038 + * were to assert in the status register just before we remove it from
137039 + * the enable register, there would be an interrupt-storm when we
137040 + * release the IRQ lock. So we wait for the enable register update to
137041 + * take effect in h/w (by reading it back) and then clear all other bits
137042 + * in the status register. Ie. we clear them from ISR once it's certain
137043 + * IER won't allow them to reassert. */
137044 + PORTAL_IRQ_LOCK(p, irqflags);
137045 + bits &= QM_PIRQ_VISIBLE;
137046 + clear_bits(bits, &p->irq_sources);
137047 + qm_isr_enable_write(&p->p, p->irq_sources);
137048 +
137049 + ier = qm_isr_enable_read(&p->p);
137050 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
137051 + * data-dependency, ie. to protect against re-ordering. */
137052 + qm_isr_status_clear(&p->p, ~ier);
137053 + PORTAL_IRQ_UNLOCK(p, irqflags);
137054 + return 0;
137055 +}
137056 +EXPORT_SYMBOL(qman_p_irqsource_remove);
137057 +
137058 +int qman_irqsource_remove(u32 bits)
137059 +{
137060 + struct qman_portal *p = get_raw_affine_portal();
137061 + int ret;
137062 + ret = qman_p_irqsource_remove(p, bits);
137063 + put_affine_portal();
137064 + return ret;
137065 +}
137066 +EXPORT_SYMBOL(qman_irqsource_remove);
137067 +
137068 +const cpumask_t *qman_affine_cpus(void)
137069 +{
137070 + return &affine_mask;
137071 +}
137072 +EXPORT_SYMBOL(qman_affine_cpus);
137073 +
137074 +u16 qman_affine_channel(int cpu)
137075 +{
137076 + if (cpu < 0) {
137077 + struct qman_portal *portal = get_raw_affine_portal();
137078 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137079 + BUG_ON(portal->sharing_redirect);
137080 +#endif
137081 + cpu = portal->config->public_cfg.cpu;
137082 + put_affine_portal();
137083 + }
137084 + BUG_ON(!cpumask_test_cpu(cpu, &affine_mask));
137085 + return affine_channels[cpu];
137086 +}
137087 +EXPORT_SYMBOL(qman_affine_channel);
137088 +
137089 +void *qman_get_affine_portal(int cpu)
137090 +{
137091 + return affine_portals[cpu];
137092 +}
137093 +EXPORT_SYMBOL(qman_get_affine_portal);
137094 +
137095 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit)
137096 +{
137097 + int ret;
137098 +
137099 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137100 + if (unlikely(p->sharing_redirect))
137101 + ret = -EINVAL;
137102 + else
137103 +#endif
137104 + {
137105 + BUG_ON(p->irq_sources & QM_PIRQ_DQRI);
137106 + ret = __poll_portal_fast(p, limit);
137107 + }
137108 + return ret;
137109 +}
137110 +EXPORT_SYMBOL(qman_p_poll_dqrr);
137111 +
137112 +int qman_poll_dqrr(unsigned int limit)
137113 +{
137114 + struct qman_portal *p = get_poll_portal();
137115 + int ret;
137116 + ret = qman_p_poll_dqrr(p, limit);
137117 + put_poll_portal();
137118 + return ret;
137119 +}
137120 +EXPORT_SYMBOL(qman_poll_dqrr);
137121 +
137122 +u32 qman_p_poll_slow(struct qman_portal *p)
137123 +{
137124 + u32 ret;
137125 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137126 + if (unlikely(p->sharing_redirect))
137127 + ret = (u32)-1;
137128 + else
137129 +#endif
137130 + {
137131 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
137132 + ret = __poll_portal_slow(p, is);
137133 + qm_isr_status_clear(&p->p, ret);
137134 + }
137135 + return ret;
137136 +}
137137 +EXPORT_SYMBOL(qman_p_poll_slow);
137138 +
137139 +u32 qman_poll_slow(void)
137140 +{
137141 + struct qman_portal *p = get_poll_portal();
137142 + u32 ret;
137143 + ret = qman_p_poll_slow(p);
137144 + put_poll_portal();
137145 + return ret;
137146 +}
137147 +EXPORT_SYMBOL(qman_poll_slow);
137148 +
137149 +/* Legacy wrapper */
137150 +void qman_p_poll(struct qman_portal *p)
137151 +{
137152 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137153 + if (unlikely(p->sharing_redirect))
137154 + return;
137155 +#endif
137156 + if ((~p->irq_sources) & QM_PIRQ_SLOW) {
137157 + if (!(p->slowpoll--)) {
137158 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
137159 + u32 active = __poll_portal_slow(p, is);
137160 + if (active) {
137161 + qm_isr_status_clear(&p->p, active);
137162 + p->slowpoll = SLOW_POLL_BUSY;
137163 + } else
137164 + p->slowpoll = SLOW_POLL_IDLE;
137165 + }
137166 + }
137167 + if ((~p->irq_sources) & QM_PIRQ_DQRI)
137168 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
137169 +}
137170 +EXPORT_SYMBOL(qman_p_poll);
137171 +
137172 +void qman_poll(void)
137173 +{
137174 + struct qman_portal *p = get_poll_portal();
137175 + qman_p_poll(p);
137176 + put_poll_portal();
137177 +}
137178 +EXPORT_SYMBOL(qman_poll);
137179 +
137180 +void qman_p_stop_dequeues(struct qman_portal *p)
137181 +{
137182 + qman_stop_dequeues_ex(p);
137183 +}
137184 +EXPORT_SYMBOL(qman_p_stop_dequeues);
137185 +
137186 +void qman_stop_dequeues(void)
137187 +{
137188 + struct qman_portal *p = get_affine_portal();
137189 + qman_p_stop_dequeues(p);
137190 + put_affine_portal();
137191 +}
137192 +EXPORT_SYMBOL(qman_stop_dequeues);
137193 +
137194 +void qman_p_start_dequeues(struct qman_portal *p)
137195 +{
137196 + unsigned long irqflags __maybe_unused;
137197 + PORTAL_IRQ_LOCK(p, irqflags);
137198 + DPA_ASSERT(p->dqrr_disable_ref > 0);
137199 + if (!(--p->dqrr_disable_ref))
137200 + qm_dqrr_set_maxfill(&p->p, DQRR_MAXFILL);
137201 + PORTAL_IRQ_UNLOCK(p, irqflags);
137202 +}
137203 +EXPORT_SYMBOL(qman_p_start_dequeues);
137204 +
137205 +void qman_start_dequeues(void)
137206 +{
137207 + struct qman_portal *p = get_affine_portal();
137208 + qman_p_start_dequeues(p);
137209 + put_affine_portal();
137210 +}
137211 +EXPORT_SYMBOL(qman_start_dequeues);
137212 +
137213 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools)
137214 +{
137215 + unsigned long irqflags __maybe_unused;
137216 + PORTAL_IRQ_LOCK(p, irqflags);
137217 + pools &= p->config->public_cfg.pools;
137218 + p->sdqcr |= pools;
137219 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137220 + PORTAL_IRQ_UNLOCK(p, irqflags);
137221 +}
137222 +EXPORT_SYMBOL(qman_p_static_dequeue_add);
137223 +
137224 +void qman_static_dequeue_add(u32 pools)
137225 +{
137226 + struct qman_portal *p = get_affine_portal();
137227 + qman_p_static_dequeue_add(p, pools);
137228 + put_affine_portal();
137229 +}
137230 +EXPORT_SYMBOL(qman_static_dequeue_add);
137231 +
137232 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools)
137233 +{
137234 + unsigned long irqflags __maybe_unused;
137235 + PORTAL_IRQ_LOCK(p, irqflags);
137236 + pools &= p->config->public_cfg.pools;
137237 + p->sdqcr &= ~pools;
137238 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137239 + PORTAL_IRQ_UNLOCK(p, irqflags);
137240 +}
137241 +EXPORT_SYMBOL(qman_p_static_dequeue_del);
137242 +
137243 +void qman_static_dequeue_del(u32 pools)
137244 +{
137245 + struct qman_portal *p = get_affine_portal();
137246 + qman_p_static_dequeue_del(p, pools);
137247 + put_affine_portal();
137248 +}
137249 +EXPORT_SYMBOL(qman_static_dequeue_del);
137250 +
137251 +u32 qman_p_static_dequeue_get(struct qman_portal *p)
137252 +{
137253 + return p->sdqcr;
137254 +}
137255 +EXPORT_SYMBOL(qman_p_static_dequeue_get);
137256 +
137257 +u32 qman_static_dequeue_get(void)
137258 +{
137259 + struct qman_portal *p = get_affine_portal();
137260 + u32 ret = qman_p_static_dequeue_get(p);
137261 + put_affine_portal();
137262 + return ret;
137263 +}
137264 +EXPORT_SYMBOL(qman_static_dequeue_get);
137265 +
137266 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
137267 + int park_request)
137268 +{
137269 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, park_request);
137270 +}
137271 +EXPORT_SYMBOL(qman_p_dca);
137272 +
137273 +void qman_dca(struct qm_dqrr_entry *dq, int park_request)
137274 +{
137275 + struct qman_portal *p = get_affine_portal();
137276 + qman_p_dca(p, dq, park_request);
137277 + put_affine_portal();
137278 +}
137279 +EXPORT_SYMBOL(qman_dca);
137280 +
137281 +/*******************/
137282 +/* Frame queue API */
137283 +/*******************/
137284 +
137285 +static const char *mcr_result_str(u8 result)
137286 +{
137287 + switch (result) {
137288 + case QM_MCR_RESULT_NULL:
137289 + return "QM_MCR_RESULT_NULL";
137290 + case QM_MCR_RESULT_OK:
137291 + return "QM_MCR_RESULT_OK";
137292 + case QM_MCR_RESULT_ERR_FQID:
137293 + return "QM_MCR_RESULT_ERR_FQID";
137294 + case QM_MCR_RESULT_ERR_FQSTATE:
137295 + return "QM_MCR_RESULT_ERR_FQSTATE";
137296 + case QM_MCR_RESULT_ERR_NOTEMPTY:
137297 + return "QM_MCR_RESULT_ERR_NOTEMPTY";
137298 + case QM_MCR_RESULT_PENDING:
137299 + return "QM_MCR_RESULT_PENDING";
137300 + case QM_MCR_RESULT_ERR_BADCOMMAND:
137301 + return "QM_MCR_RESULT_ERR_BADCOMMAND";
137302 + }
137303 + return "<unknown MCR result>";
137304 +}
137305 +
137306 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq)
137307 +{
137308 + struct qm_fqd fqd;
137309 + struct qm_mcr_queryfq_np np;
137310 + struct qm_mc_command *mcc;
137311 + struct qm_mc_result *mcr;
137312 + struct qman_portal *p;
137313 + unsigned long irqflags __maybe_unused;
137314 +
137315 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID) {
137316 + int ret = qman_alloc_fqid(&fqid);
137317 + if (ret)
137318 + return ret;
137319 + }
137320 + spin_lock_init(&fq->fqlock);
137321 + fq->fqid = fqid;
137322 + fq->flags = flags;
137323 + fq->state = qman_fq_state_oos;
137324 + fq->cgr_groupid = 0;
137325 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137326 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
137327 + return -ENOMEM;
137328 +#endif
137329 + if (!(flags & QMAN_FQ_FLAG_AS_IS) || (flags & QMAN_FQ_FLAG_NO_MODIFY))
137330 + return 0;
137331 + /* Everything else is AS_IS support */
137332 + p = get_affine_portal();
137333 + PORTAL_IRQ_LOCK(p, irqflags);
137334 + mcc = qm_mc_start(&p->p);
137335 + mcc->queryfq.fqid = cpu_to_be32(fqid);
137336 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
137337 + while (!(mcr = qm_mc_result(&p->p)))
137338 + cpu_relax();
137339 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ);
137340 + if (mcr->result != QM_MCR_RESULT_OK) {
137341 + pr_err("QUERYFQ failed: %s\n", mcr_result_str(mcr->result));
137342 + goto err;
137343 + }
137344 + fqd = mcr->queryfq.fqd;
137345 + hw_fqd_to_cpu(&fqd);
137346 + mcc = qm_mc_start(&p->p);
137347 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
137348 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
137349 + while (!(mcr = qm_mc_result(&p->p)))
137350 + cpu_relax();
137351 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ_NP);
137352 + if (mcr->result != QM_MCR_RESULT_OK) {
137353 + pr_err("QUERYFQ_NP failed: %s\n", mcr_result_str(mcr->result));
137354 + goto err;
137355 + }
137356 + np = mcr->queryfq_np;
137357 + /* Phew, have queryfq and queryfq_np results, stitch together
137358 + * the FQ object from those. */
137359 + fq->cgr_groupid = fqd.cgid;
137360 + switch (np.state & QM_MCR_NP_STATE_MASK) {
137361 + case QM_MCR_NP_STATE_OOS:
137362 + break;
137363 + case QM_MCR_NP_STATE_RETIRED:
137364 + fq->state = qman_fq_state_retired;
137365 + if (np.frm_cnt)
137366 + fq_set(fq, QMAN_FQ_STATE_NE);
137367 + break;
137368 + case QM_MCR_NP_STATE_TEN_SCHED:
137369 + case QM_MCR_NP_STATE_TRU_SCHED:
137370 + case QM_MCR_NP_STATE_ACTIVE:
137371 + fq->state = qman_fq_state_sched;
137372 + if (np.state & QM_MCR_NP_STATE_R)
137373 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
137374 + break;
137375 + case QM_MCR_NP_STATE_PARKED:
137376 + fq->state = qman_fq_state_parked;
137377 + break;
137378 + default:
137379 + DPA_ASSERT(NULL == "invalid FQ state");
137380 + }
137381 + if (fqd.fq_ctrl & QM_FQCTRL_CGE)
137382 + fq->state |= QMAN_FQ_STATE_CGR_EN;
137383 + PORTAL_IRQ_UNLOCK(p, irqflags);
137384 + put_affine_portal();
137385 + return 0;
137386 +err:
137387 + PORTAL_IRQ_UNLOCK(p, irqflags);
137388 + put_affine_portal();
137389 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID)
137390 + qman_release_fqid(fqid);
137391 + return -EIO;
137392 +}
137393 +EXPORT_SYMBOL(qman_create_fq);
137394 +
137395 +void qman_destroy_fq(struct qman_fq *fq, u32 flags __maybe_unused)
137396 +{
137397 +
137398 + /* We don't need to lock the FQ as it is a pre-condition that the FQ be
137399 + * quiesced. Instead, run some checks. */
137400 + switch (fq->state) {
137401 + case qman_fq_state_parked:
137402 + DPA_ASSERT(flags & QMAN_FQ_DESTROY_PARKED);
137403 + case qman_fq_state_oos:
137404 + if (fq_isset(fq, QMAN_FQ_FLAG_DYNAMIC_FQID))
137405 + qman_release_fqid(fq->fqid);
137406 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137407 + clear_fq_table_entry(fq->key);
137408 +#endif
137409 + return;
137410 + default:
137411 + break;
137412 + }
137413 + DPA_ASSERT(NULL == "qman_free_fq() on unquiesced FQ!");
137414 +}
137415 +EXPORT_SYMBOL(qman_destroy_fq);
137416 +
137417 +u32 qman_fq_fqid(struct qman_fq *fq)
137418 +{
137419 + return fq->fqid;
137420 +}
137421 +EXPORT_SYMBOL(qman_fq_fqid);
137422 +
137423 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags)
137424 +{
137425 + if (state)
137426 + *state = fq->state;
137427 + if (flags)
137428 + *flags = fq->flags;
137429 +}
137430 +EXPORT_SYMBOL(qman_fq_state);
137431 +
137432 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts)
137433 +{
137434 + struct qm_mc_command *mcc;
137435 + struct qm_mc_result *mcr;
137436 + struct qman_portal *p;
137437 + unsigned long irqflags __maybe_unused;
137438 + u8 res, myverb = (flags & QMAN_INITFQ_FLAG_SCHED) ?
137439 + QM_MCC_VERB_INITFQ_SCHED : QM_MCC_VERB_INITFQ_PARKED;
137440 +
137441 + if ((fq->state != qman_fq_state_oos) &&
137442 + (fq->state != qman_fq_state_parked))
137443 + return -EINVAL;
137444 +#ifdef CONFIG_FSL_DPA_CHECKING
137445 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137446 + return -EINVAL;
137447 +#endif
137448 + if (opts && (opts->we_mask & QM_INITFQ_WE_OAC)) {
137449 + /* And can't be set at the same time as TDTHRESH */
137450 + if (opts->we_mask & QM_INITFQ_WE_TDTHRESH)
137451 + return -EINVAL;
137452 + }
137453 + /* Issue an INITFQ_[PARKED|SCHED] management command */
137454 + p = get_affine_portal();
137455 + PORTAL_IRQ_LOCK(p, irqflags);
137456 + FQLOCK(fq);
137457 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137458 + ((fq->state != qman_fq_state_oos) &&
137459 + (fq->state != qman_fq_state_parked)))) {
137460 + FQUNLOCK(fq);
137461 + PORTAL_IRQ_UNLOCK(p, irqflags);
137462 + put_affine_portal();
137463 + return -EBUSY;
137464 + }
137465 + mcc = qm_mc_start(&p->p);
137466 + if (opts)
137467 + mcc->initfq = *opts;
137468 + mcc->initfq.fqid = cpu_to_be32(fq->fqid);
137469 + mcc->initfq.count = 0;
137470 +
137471 + /* If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a
137472 + * demux pointer. Otherwise, the caller-provided value is allowed to
137473 + * stand, don't overwrite it. */
137474 + if (fq_isclear(fq, QMAN_FQ_FLAG_TO_DCPORTAL)) {
137475 + dma_addr_t phys_fq;
137476 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTB;
137477 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137478 + mcc->initfq.fqd.context_b = fq->key;
137479 +#else
137480 + mcc->initfq.fqd.context_b = (u32)(uintptr_t)fq;
137481 +#endif
137482 + /* and the physical address - NB, if the user wasn't trying to
137483 + * set CONTEXTA, clear the stashing settings. */
137484 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_CONTEXTA)) {
137485 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
137486 + memset(&mcc->initfq.fqd.context_a, 0,
137487 + sizeof(mcc->initfq.fqd.context_a));
137488 + } else {
137489 + phys_fq = dma_map_single(&p->pdev->dev, fq, sizeof(*fq),
137490 + DMA_TO_DEVICE);
137491 + qm_fqd_stashing_set64(&mcc->initfq.fqd, phys_fq);
137492 + }
137493 + }
137494 + if (flags & QMAN_INITFQ_FLAG_LOCAL) {
137495 + mcc->initfq.fqd.dest.channel = p->config->public_cfg.channel;
137496 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_DESTWQ)) {
137497 + mcc->initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
137498 + mcc->initfq.fqd.dest.wq = 4;
137499 + }
137500 + }
137501 + mcc->initfq.we_mask = cpu_to_be16(mcc->initfq.we_mask);
137502 + cpu_to_hw_fqd(&mcc->initfq.fqd);
137503 + qm_mc_commit(&p->p, myverb);
137504 + while (!(mcr = qm_mc_result(&p->p)))
137505 + cpu_relax();
137506 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
137507 + res = mcr->result;
137508 + if (res != QM_MCR_RESULT_OK) {
137509 + FQUNLOCK(fq);
137510 + PORTAL_IRQ_UNLOCK(p, irqflags);
137511 + put_affine_portal();
137512 + return -EIO;
137513 + }
137514 + if (opts) {
137515 + if (opts->we_mask & QM_INITFQ_WE_FQCTRL) {
137516 + if (opts->fqd.fq_ctrl & QM_FQCTRL_CGE)
137517 + fq_set(fq, QMAN_FQ_STATE_CGR_EN);
137518 + else
137519 + fq_clear(fq, QMAN_FQ_STATE_CGR_EN);
137520 + }
137521 + if (opts->we_mask & QM_INITFQ_WE_CGID)
137522 + fq->cgr_groupid = opts->fqd.cgid;
137523 + }
137524 + fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ?
137525 + qman_fq_state_sched : qman_fq_state_parked;
137526 + FQUNLOCK(fq);
137527 + PORTAL_IRQ_UNLOCK(p, irqflags);
137528 + put_affine_portal();
137529 + return 0;
137530 +}
137531 +EXPORT_SYMBOL(qman_init_fq);
137532 +
137533 +int qman_schedule_fq(struct qman_fq *fq)
137534 +{
137535 + struct qm_mc_command *mcc;
137536 + struct qm_mc_result *mcr;
137537 + struct qman_portal *p;
137538 + unsigned long irqflags __maybe_unused;
137539 + int ret = 0;
137540 + u8 res;
137541 +
137542 + if (fq->state != qman_fq_state_parked)
137543 + return -EINVAL;
137544 +#ifdef CONFIG_FSL_DPA_CHECKING
137545 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137546 + return -EINVAL;
137547 +#endif
137548 + /* Issue a ALTERFQ_SCHED management command */
137549 + p = get_affine_portal();
137550 + PORTAL_IRQ_LOCK(p, irqflags);
137551 + FQLOCK(fq);
137552 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137553 + (fq->state != qman_fq_state_parked))) {
137554 + ret = -EBUSY;
137555 + goto out;
137556 + }
137557 + mcc = qm_mc_start(&p->p);
137558 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137559 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_SCHED);
137560 + while (!(mcr = qm_mc_result(&p->p)))
137561 + cpu_relax();
137562 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_SCHED);
137563 + res = mcr->result;
137564 + if (res != QM_MCR_RESULT_OK) {
137565 + ret = -EIO;
137566 + goto out;
137567 + }
137568 + fq->state = qman_fq_state_sched;
137569 +out:
137570 + FQUNLOCK(fq);
137571 + PORTAL_IRQ_UNLOCK(p, irqflags);
137572 + put_affine_portal();
137573 + return ret;
137574 +}
137575 +EXPORT_SYMBOL(qman_schedule_fq);
137576 +
137577 +int qman_retire_fq(struct qman_fq *fq, u32 *flags)
137578 +{
137579 + struct qm_mc_command *mcc;
137580 + struct qm_mc_result *mcr;
137581 + struct qman_portal *p;
137582 + unsigned long irqflags __maybe_unused;
137583 + int rval;
137584 + u8 res;
137585 +
137586 + if ((fq->state != qman_fq_state_parked) &&
137587 + (fq->state != qman_fq_state_sched))
137588 + return -EINVAL;
137589 +#ifdef CONFIG_FSL_DPA_CHECKING
137590 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137591 + return -EINVAL;
137592 +#endif
137593 + p = get_affine_portal();
137594 + PORTAL_IRQ_LOCK(p, irqflags);
137595 + FQLOCK(fq);
137596 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137597 + (fq->state == qman_fq_state_retired) ||
137598 + (fq->state == qman_fq_state_oos))) {
137599 + rval = -EBUSY;
137600 + goto out;
137601 + }
137602 + rval = table_push_fq(p, fq);
137603 + if (rval)
137604 + goto out;
137605 + mcc = qm_mc_start(&p->p);
137606 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137607 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE);
137608 + while (!(mcr = qm_mc_result(&p->p)))
137609 + cpu_relax();
137610 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_RETIRE);
137611 + res = mcr->result;
137612 + /* "Elegant" would be to treat OK/PENDING the same way; set CHANGING,
137613 + * and defer the flags until FQRNI or FQRN (respectively) show up. But
137614 + * "Friendly" is to process OK immediately, and not set CHANGING. We do
137615 + * friendly, otherwise the caller doesn't necessarily have a fully
137616 + * "retired" FQ on return even if the retirement was immediate. However
137617 + * this does mean some code duplication between here and
137618 + * fq_state_change(). */
137619 + if (likely(res == QM_MCR_RESULT_OK)) {
137620 + rval = 0;
137621 + /* Process 'fq' right away, we'll ignore FQRNI */
137622 + if (mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY)
137623 + fq_set(fq, QMAN_FQ_STATE_NE);
137624 + if (mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)
137625 + fq_set(fq, QMAN_FQ_STATE_ORL);
137626 + else
137627 + table_del_fq(p, fq);
137628 + if (flags)
137629 + *flags = fq->flags;
137630 + fq->state = qman_fq_state_retired;
137631 + if (fq->cb.fqs) {
137632 + /* Another issue with supporting "immediate" retirement
137633 + * is that we're forced to drop FQRNIs, because by the
137634 + * time they're seen it may already be "too late" (the
137635 + * fq may have been OOS'd and free()'d already). But if
137636 + * the upper layer wants a callback whether it's
137637 + * immediate or not, we have to fake a "MR" entry to
137638 + * look like an FQRNI... */
137639 + struct qm_mr_entry msg;
137640 + msg.verb = QM_MR_VERB_FQRNI;
137641 + msg.fq.fqs = mcr->alterfq.fqs;
137642 + msg.fq.fqid = fq->fqid;
137643 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137644 + msg.fq.contextB = fq->key;
137645 +#else
137646 + msg.fq.contextB = (u32)(uintptr_t)fq;
137647 +#endif
137648 + fq->cb.fqs(p, fq, &msg);
137649 + }
137650 + } else if (res == QM_MCR_RESULT_PENDING) {
137651 + rval = 1;
137652 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
137653 + } else {
137654 + rval = -EIO;
137655 + table_del_fq(p, fq);
137656 + }
137657 +out:
137658 + FQUNLOCK(fq);
137659 + PORTAL_IRQ_UNLOCK(p, irqflags);
137660 + put_affine_portal();
137661 + return rval;
137662 +}
137663 +EXPORT_SYMBOL(qman_retire_fq);
137664 +
137665 +int qman_oos_fq(struct qman_fq *fq)
137666 +{
137667 + struct qm_mc_command *mcc;
137668 + struct qm_mc_result *mcr;
137669 + struct qman_portal *p;
137670 + unsigned long irqflags __maybe_unused;
137671 + int ret = 0;
137672 + u8 res;
137673 +
137674 + if (fq->state != qman_fq_state_retired)
137675 + return -EINVAL;
137676 +#ifdef CONFIG_FSL_DPA_CHECKING
137677 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137678 + return -EINVAL;
137679 +#endif
137680 + p = get_affine_portal();
137681 + PORTAL_IRQ_LOCK(p, irqflags);
137682 + FQLOCK(fq);
137683 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_BLOCKOOS)) ||
137684 + (fq->state != qman_fq_state_retired))) {
137685 + ret = -EBUSY;
137686 + goto out;
137687 + }
137688 + mcc = qm_mc_start(&p->p);
137689 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137690 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS);
137691 + while (!(mcr = qm_mc_result(&p->p)))
137692 + cpu_relax();
137693 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_OOS);
137694 + res = mcr->result;
137695 + if (res != QM_MCR_RESULT_OK) {
137696 + ret = -EIO;
137697 + goto out;
137698 + }
137699 + fq->state = qman_fq_state_oos;
137700 +out:
137701 + FQUNLOCK(fq);
137702 + PORTAL_IRQ_UNLOCK(p, irqflags);
137703 + put_affine_portal();
137704 + return ret;
137705 +}
137706 +EXPORT_SYMBOL(qman_oos_fq);
137707 +
137708 +int qman_fq_flow_control(struct qman_fq *fq, int xon)
137709 +{
137710 + struct qm_mc_command *mcc;
137711 + struct qm_mc_result *mcr;
137712 + struct qman_portal *p;
137713 + unsigned long irqflags __maybe_unused;
137714 + int ret = 0;
137715 + u8 res;
137716 + u8 myverb;
137717 +
137718 + if ((fq->state == qman_fq_state_oos) ||
137719 + (fq->state == qman_fq_state_retired) ||
137720 + (fq->state == qman_fq_state_parked))
137721 + return -EINVAL;
137722 +
137723 +#ifdef CONFIG_FSL_DPA_CHECKING
137724 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137725 + return -EINVAL;
137726 +#endif
137727 + /* Issue a ALTER_FQXON or ALTER_FQXOFF management command */
137728 + p = get_affine_portal();
137729 + PORTAL_IRQ_LOCK(p, irqflags);
137730 + FQLOCK(fq);
137731 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137732 + (fq->state == qman_fq_state_parked) ||
137733 + (fq->state == qman_fq_state_oos) ||
137734 + (fq->state == qman_fq_state_retired))) {
137735 + ret = -EBUSY;
137736 + goto out;
137737 + }
137738 + mcc = qm_mc_start(&p->p);
137739 + mcc->alterfq.fqid = fq->fqid;
137740 + mcc->alterfq.count = 0;
137741 + myverb = xon ? QM_MCC_VERB_ALTER_FQXON : QM_MCC_VERB_ALTER_FQXOFF;
137742 +
137743 + qm_mc_commit(&p->p, myverb);
137744 + while (!(mcr = qm_mc_result(&p->p)))
137745 + cpu_relax();
137746 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
137747 +
137748 + res = mcr->result;
137749 + if (res != QM_MCR_RESULT_OK) {
137750 + ret = -EIO;
137751 + goto out;
137752 + }
137753 +out:
137754 + FQUNLOCK(fq);
137755 + PORTAL_IRQ_UNLOCK(p, irqflags);
137756 + put_affine_portal();
137757 + return ret;
137758 +}
137759 +EXPORT_SYMBOL(qman_fq_flow_control);
137760 +
137761 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd)
137762 +{
137763 + struct qm_mc_command *mcc;
137764 + struct qm_mc_result *mcr;
137765 + struct qman_portal *p = get_affine_portal();
137766 + unsigned long irqflags __maybe_unused;
137767 + u8 res;
137768 +
137769 + PORTAL_IRQ_LOCK(p, irqflags);
137770 + mcc = qm_mc_start(&p->p);
137771 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
137772 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
137773 + while (!(mcr = qm_mc_result(&p->p)))
137774 + cpu_relax();
137775 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
137776 + res = mcr->result;
137777 + if (res == QM_MCR_RESULT_OK)
137778 + *fqd = mcr->queryfq.fqd;
137779 + hw_fqd_to_cpu(fqd);
137780 + PORTAL_IRQ_UNLOCK(p, irqflags);
137781 + put_affine_portal();
137782 + if (res != QM_MCR_RESULT_OK)
137783 + return -EIO;
137784 + return 0;
137785 +}
137786 +EXPORT_SYMBOL(qman_query_fq);
137787 +
137788 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np)
137789 +{
137790 + struct qm_mc_command *mcc;
137791 + struct qm_mc_result *mcr;
137792 + struct qman_portal *p = get_affine_portal();
137793 + unsigned long irqflags __maybe_unused;
137794 + u8 res;
137795 +
137796 + PORTAL_IRQ_LOCK(p, irqflags);
137797 + mcc = qm_mc_start(&p->p);
137798 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
137799 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
137800 + while (!(mcr = qm_mc_result(&p->p)))
137801 + cpu_relax();
137802 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
137803 + res = mcr->result;
137804 + if (res == QM_MCR_RESULT_OK) {
137805 + *np = mcr->queryfq_np;
137806 + np->fqd_link = be24_to_cpu(np->fqd_link);
137807 + np->odp_seq = be16_to_cpu(np->odp_seq);
137808 + np->orp_nesn = be16_to_cpu(np->orp_nesn);
137809 + np->orp_ea_hseq = be16_to_cpu(np->orp_ea_hseq);
137810 + np->orp_ea_tseq = be16_to_cpu(np->orp_ea_tseq);
137811 + np->orp_ea_hptr = be24_to_cpu(np->orp_ea_hptr);
137812 + np->orp_ea_tptr = be24_to_cpu(np->orp_ea_tptr);
137813 + np->pfdr_hptr = be24_to_cpu(np->pfdr_hptr);
137814 + np->pfdr_tptr = be24_to_cpu(np->pfdr_tptr);
137815 + np->ics_surp = be16_to_cpu(np->ics_surp);
137816 + np->byte_cnt = be32_to_cpu(np->byte_cnt);
137817 + np->frm_cnt = be24_to_cpu(np->frm_cnt);
137818 + np->ra1_sfdr = be16_to_cpu(np->ra1_sfdr);
137819 + np->ra2_sfdr = be16_to_cpu(np->ra2_sfdr);
137820 + np->od1_sfdr = be16_to_cpu(np->od1_sfdr);
137821 + np->od2_sfdr = be16_to_cpu(np->od2_sfdr);
137822 + np->od3_sfdr = be16_to_cpu(np->od3_sfdr);
137823 + }
137824 + PORTAL_IRQ_UNLOCK(p, irqflags);
137825 + put_affine_portal();
137826 + if (res == QM_MCR_RESULT_ERR_FQID)
137827 + return -ERANGE;
137828 + else if (res != QM_MCR_RESULT_OK)
137829 + return -EIO;
137830 + return 0;
137831 +}
137832 +EXPORT_SYMBOL(qman_query_fq_np);
137833 +
137834 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq)
137835 +{
137836 + struct qm_mc_command *mcc;
137837 + struct qm_mc_result *mcr;
137838 + struct qman_portal *p = get_affine_portal();
137839 + unsigned long irqflags __maybe_unused;
137840 + u8 res, myverb;
137841 +
137842 + PORTAL_IRQ_LOCK(p, irqflags);
137843 + myverb = (query_dedicated) ? QM_MCR_VERB_QUERYWQ_DEDICATED :
137844 + QM_MCR_VERB_QUERYWQ;
137845 + mcc = qm_mc_start(&p->p);
137846 + mcc->querywq.channel.id = cpu_to_be16(wq->channel.id);
137847 + qm_mc_commit(&p->p, myverb);
137848 + while (!(mcr = qm_mc_result(&p->p)))
137849 + cpu_relax();
137850 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
137851 + res = mcr->result;
137852 + if (res == QM_MCR_RESULT_OK) {
137853 + int i, array_len;
137854 + wq->channel.id = be16_to_cpu(mcr->querywq.channel.id);
137855 + array_len = ARRAY_SIZE(mcr->querywq.wq_len);
137856 + for (i = 0; i < array_len; i++)
137857 + wq->wq_len[i] = be32_to_cpu(mcr->querywq.wq_len[i]);
137858 + }
137859 + PORTAL_IRQ_UNLOCK(p, irqflags);
137860 + put_affine_portal();
137861 + if (res != QM_MCR_RESULT_OK) {
137862 + pr_err("QUERYWQ failed: %s\n", mcr_result_str(res));
137863 + return -EIO;
137864 + }
137865 + return 0;
137866 +}
137867 +EXPORT_SYMBOL(qman_query_wq);
137868 +
137869 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
137870 + struct qm_mcr_cgrtestwrite *result)
137871 +{
137872 + struct qm_mc_command *mcc;
137873 + struct qm_mc_result *mcr;
137874 + struct qman_portal *p = get_affine_portal();
137875 + unsigned long irqflags __maybe_unused;
137876 + u8 res;
137877 +
137878 + PORTAL_IRQ_LOCK(p, irqflags);
137879 + mcc = qm_mc_start(&p->p);
137880 + mcc->cgrtestwrite.cgid = cgr->cgrid;
137881 + mcc->cgrtestwrite.i_bcnt_hi = (u8)(i_bcnt >> 32);
137882 + mcc->cgrtestwrite.i_bcnt_lo = (u32)i_bcnt;
137883 + qm_mc_commit(&p->p, QM_MCC_VERB_CGRTESTWRITE);
137884 + while (!(mcr = qm_mc_result(&p->p)))
137885 + cpu_relax();
137886 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_CGRTESTWRITE);
137887 + res = mcr->result;
137888 + if (res == QM_MCR_RESULT_OK)
137889 + *result = mcr->cgrtestwrite;
137890 + PORTAL_IRQ_UNLOCK(p, irqflags);
137891 + put_affine_portal();
137892 + if (res != QM_MCR_RESULT_OK) {
137893 + pr_err("CGR TEST WRITE failed: %s\n", mcr_result_str(res));
137894 + return -EIO;
137895 + }
137896 + return 0;
137897 +}
137898 +EXPORT_SYMBOL(qman_testwrite_cgr);
137899 +
137900 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *cgrd)
137901 +{
137902 + struct qm_mc_command *mcc;
137903 + struct qm_mc_result *mcr;
137904 + struct qman_portal *p = get_affine_portal();
137905 + unsigned long irqflags __maybe_unused;
137906 + u8 res;
137907 + int i;
137908 +
137909 + PORTAL_IRQ_LOCK(p, irqflags);
137910 + mcc = qm_mc_start(&p->p);
137911 + mcc->querycgr.cgid = cgr->cgrid;
137912 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCGR);
137913 + while (!(mcr = qm_mc_result(&p->p)))
137914 + cpu_relax();
137915 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
137916 + res = mcr->result;
137917 + if (res == QM_MCR_RESULT_OK)
137918 + *cgrd = mcr->querycgr;
137919 + PORTAL_IRQ_UNLOCK(p, irqflags);
137920 + put_affine_portal();
137921 + if (res != QM_MCR_RESULT_OK) {
137922 + pr_err("QUERY_CGR failed: %s\n", mcr_result_str(res));
137923 + return -EIO;
137924 + }
137925 + cgrd->cgr.wr_parm_g.word =
137926 + be32_to_cpu(cgrd->cgr.wr_parm_g.word);
137927 + cgrd->cgr.wr_parm_y.word =
137928 + be32_to_cpu(cgrd->cgr.wr_parm_y.word);
137929 + cgrd->cgr.wr_parm_r.word =
137930 + be32_to_cpu(cgrd->cgr.wr_parm_r.word);
137931 + cgrd->cgr.cscn_targ = be32_to_cpu(cgrd->cgr.cscn_targ);
137932 + cgrd->cgr.__cs_thres = be16_to_cpu(cgrd->cgr.__cs_thres);
137933 + for (i = 0; i < ARRAY_SIZE(cgrd->cscn_targ_swp); i++)
137934 + be32_to_cpus(&cgrd->cscn_targ_swp[i]);
137935 + return 0;
137936 +}
137937 +EXPORT_SYMBOL(qman_query_cgr);
137938 +
137939 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion)
137940 +{
137941 + struct qm_mc_result *mcr;
137942 + struct qman_portal *p = get_affine_portal();
137943 + unsigned long irqflags __maybe_unused;
137944 + u8 res;
137945 + int i;
137946 +
137947 + PORTAL_IRQ_LOCK(p, irqflags);
137948 + qm_mc_start(&p->p);
137949 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
137950 + while (!(mcr = qm_mc_result(&p->p)))
137951 + cpu_relax();
137952 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
137953 + QM_MCC_VERB_QUERYCONGESTION);
137954 + res = mcr->result;
137955 + if (res == QM_MCR_RESULT_OK)
137956 + memcpy_fromio(congestion, &mcr->querycongestion,
137957 + sizeof(*congestion));
137958 + PORTAL_IRQ_UNLOCK(p, irqflags);
137959 + put_affine_portal();
137960 + if (res != QM_MCR_RESULT_OK) {
137961 + pr_err("QUERY_CONGESTION failed: %s\n", mcr_result_str(res));
137962 + return -EIO;
137963 + }
137964 +
137965 + for (i = 0; i < ARRAY_SIZE(congestion->state.__state); i++)
137966 + be32_to_cpus(&congestion->state.__state[i]);
137967 + return 0;
137968 +}
137969 +EXPORT_SYMBOL(qman_query_congestion);
137970 +
137971 +/* internal function used as a wait_event() expression */
137972 +static int set_p_vdqcr(struct qman_portal *p, struct qman_fq *fq, u32 vdqcr)
137973 +{
137974 + unsigned long irqflags __maybe_unused;
137975 + int ret = -EBUSY;
137976 + PORTAL_IRQ_LOCK(p, irqflags);
137977 + if (!p->vdqcr_owned) {
137978 + FQLOCK(fq);
137979 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
137980 + goto escape;
137981 + fq_set(fq, QMAN_FQ_STATE_VDQCR);
137982 + FQUNLOCK(fq);
137983 + p->vdqcr_owned = fq;
137984 + ret = 0;
137985 + }
137986 +escape:
137987 + PORTAL_IRQ_UNLOCK(p, irqflags);
137988 + if (!ret)
137989 + qm_dqrr_vdqcr_set(&p->p, vdqcr);
137990 + return ret;
137991 +}
137992 +
137993 +static int set_vdqcr(struct qman_portal **p, struct qman_fq *fq, u32 vdqcr)
137994 +{
137995 + int ret;
137996 + *p = get_affine_portal();
137997 + ret = set_p_vdqcr(*p, fq, vdqcr);
137998 + put_affine_portal();
137999 + return ret;
138000 +}
138001 +
138002 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138003 +static int wait_p_vdqcr_start(struct qman_portal *p, struct qman_fq *fq,
138004 + u32 vdqcr, u32 flags)
138005 +{
138006 + int ret = 0;
138007 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138008 + ret = wait_event_interruptible(affine_queue,
138009 + !(ret = set_p_vdqcr(p, fq, vdqcr)));
138010 + else
138011 + wait_event(affine_queue, !(ret = set_p_vdqcr(p, fq, vdqcr)));
138012 + return ret;
138013 +}
138014 +
138015 +static int wait_vdqcr_start(struct qman_portal **p, struct qman_fq *fq,
138016 + u32 vdqcr, u32 flags)
138017 +{
138018 + int ret = 0;
138019 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138020 + ret = wait_event_interruptible(affine_queue,
138021 + !(ret = set_vdqcr(p, fq, vdqcr)));
138022 + else
138023 + wait_event(affine_queue, !(ret = set_vdqcr(p, fq, vdqcr)));
138024 + return ret;
138025 +}
138026 +#endif
138027 +
138028 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
138029 + u32 flags __maybe_unused, u32 vdqcr)
138030 +{
138031 + int ret;
138032 +
138033 + if ((fq->state != qman_fq_state_parked) &&
138034 + (fq->state != qman_fq_state_retired))
138035 + return -EINVAL;
138036 + if (vdqcr & QM_VDQCR_FQID_MASK)
138037 + return -EINVAL;
138038 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138039 + return -EBUSY;
138040 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
138041 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138042 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
138043 + ret = wait_p_vdqcr_start(p, fq, vdqcr, flags);
138044 + else
138045 +#endif
138046 + ret = set_p_vdqcr(p, fq, vdqcr);
138047 + if (ret)
138048 + return ret;
138049 + /* VDQCR is set */
138050 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138051 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
138052 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138053 + /* NB: don't propagate any error - the caller wouldn't
138054 + * know whether the VDQCR was issued or not. A signal
138055 + * could arrive after returning anyway, so the caller
138056 + * can check signal_pending() if that's an issue. */
138057 + wait_event_interruptible(affine_queue,
138058 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138059 + else
138060 + wait_event(affine_queue,
138061 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138062 + }
138063 +#endif
138064 + return 0;
138065 +}
138066 +EXPORT_SYMBOL(qman_p_volatile_dequeue);
138067 +
138068 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags __maybe_unused,
138069 + u32 vdqcr)
138070 +{
138071 + struct qman_portal *p;
138072 + int ret;
138073 +
138074 + if ((fq->state != qman_fq_state_parked) &&
138075 + (fq->state != qman_fq_state_retired))
138076 + return -EINVAL;
138077 + if (vdqcr & QM_VDQCR_FQID_MASK)
138078 + return -EINVAL;
138079 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138080 + return -EBUSY;
138081 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
138082 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138083 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
138084 + ret = wait_vdqcr_start(&p, fq, vdqcr, flags);
138085 + else
138086 +#endif
138087 + ret = set_vdqcr(&p, fq, vdqcr);
138088 + if (ret)
138089 + return ret;
138090 + /* VDQCR is set */
138091 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138092 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
138093 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138094 + /* NB: don't propagate any error - the caller wouldn't
138095 + * know whether the VDQCR was issued or not. A signal
138096 + * could arrive after returning anyway, so the caller
138097 + * can check signal_pending() if that's an issue. */
138098 + wait_event_interruptible(affine_queue,
138099 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138100 + else
138101 + wait_event(affine_queue,
138102 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138103 + }
138104 +#endif
138105 + return 0;
138106 +}
138107 +EXPORT_SYMBOL(qman_volatile_dequeue);
138108 +
138109 +static noinline void update_eqcr_ci(struct qman_portal *p, u8 avail)
138110 +{
138111 + if (avail)
138112 + qm_eqcr_cce_prefetch(&p->p);
138113 + else
138114 + qm_eqcr_cce_update(&p->p);
138115 +}
138116 +
138117 +int qman_eqcr_is_empty(void)
138118 +{
138119 + unsigned long irqflags __maybe_unused;
138120 + struct qman_portal *p = get_affine_portal();
138121 + u8 avail;
138122 +
138123 + PORTAL_IRQ_LOCK(p, irqflags);
138124 + update_eqcr_ci(p, 0);
138125 + avail = qm_eqcr_get_fill(&p->p);
138126 + PORTAL_IRQ_UNLOCK(p, irqflags);
138127 + put_affine_portal();
138128 + return avail == 0;
138129 +}
138130 +EXPORT_SYMBOL(qman_eqcr_is_empty);
138131 +
138132 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine)
138133 +{
138134 + if (affine) {
138135 + unsigned long irqflags __maybe_unused;
138136 + struct qman_portal *p = get_affine_portal();
138137 + PORTAL_IRQ_LOCK(p, irqflags);
138138 + p->cb_dc_ern = handler;
138139 + PORTAL_IRQ_UNLOCK(p, irqflags);
138140 + put_affine_portal();
138141 + } else
138142 + cb_dc_ern = handler;
138143 +}
138144 +EXPORT_SYMBOL(qman_set_dc_ern);
138145 +
138146 +static inline struct qm_eqcr_entry *try_p_eq_start(struct qman_portal *p,
138147 + unsigned long *irqflags __maybe_unused,
138148 + struct qman_fq *fq,
138149 + const struct qm_fd *fd,
138150 + u32 flags)
138151 +{
138152 + struct qm_eqcr_entry *eq;
138153 + u8 avail;
138154 + PORTAL_IRQ_LOCK(p, (*irqflags));
138155 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138156 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138157 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138158 + if (p->eqci_owned) {
138159 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
138160 + return NULL;
138161 + }
138162 + p->eqci_owned = fq;
138163 + }
138164 +#endif
138165 + if (p->use_eqcr_ci_stashing) {
138166 + /*
138167 + * The stashing case is easy, only update if we need to in
138168 + * order to try and liberate ring entries.
138169 + */
138170 + eq = qm_eqcr_start_stash(&p->p);
138171 + } else {
138172 + /*
138173 + * The non-stashing case is harder, need to prefetch ahead of
138174 + * time.
138175 + */
138176 + avail = qm_eqcr_get_avail(&p->p);
138177 + if (avail < 2)
138178 + update_eqcr_ci(p, avail);
138179 + eq = qm_eqcr_start_no_stash(&p->p);
138180 + }
138181 +
138182 + if (unlikely(!eq)) {
138183 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138184 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138185 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC)))
138186 + p->eqci_owned = NULL;
138187 +#endif
138188 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
138189 + return NULL;
138190 + }
138191 + if (flags & QMAN_ENQUEUE_FLAG_DCA)
138192 + eq->dca = QM_EQCR_DCA_ENABLE |
138193 + ((flags & QMAN_ENQUEUE_FLAG_DCA_PARK) ?
138194 + QM_EQCR_DCA_PARK : 0) |
138195 + ((flags >> 8) & QM_EQCR_DCA_IDXMASK);
138196 + eq->fqid = cpu_to_be32(fq->fqid);
138197 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138198 + eq->tag = cpu_to_be32(fq->key);
138199 +#else
138200 + eq->tag = cpu_to_be32((u32)(uintptr_t)fq);
138201 +#endif
138202 + eq->fd = *fd;
138203 + cpu_to_hw_fd(&eq->fd);
138204 + return eq;
138205 +}
138206 +
138207 +static inline struct qm_eqcr_entry *try_eq_start(struct qman_portal **p,
138208 + unsigned long *irqflags __maybe_unused,
138209 + struct qman_fq *fq,
138210 + const struct qm_fd *fd,
138211 + u32 flags)
138212 +{
138213 + struct qm_eqcr_entry *eq;
138214 + *p = get_affine_portal();
138215 + eq = try_p_eq_start(*p, irqflags, fq, fd, flags);
138216 + if (!eq)
138217 + put_affine_portal();
138218 + return eq;
138219 +}
138220 +
138221 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138222 +static noinline struct qm_eqcr_entry *__wait_eq_start(struct qman_portal **p,
138223 + unsigned long *irqflags __maybe_unused,
138224 + struct qman_fq *fq,
138225 + const struct qm_fd *fd,
138226 + u32 flags)
138227 +{
138228 + struct qm_eqcr_entry *eq = try_eq_start(p, irqflags, fq, fd, flags);
138229 + if (!eq)
138230 + qm_eqcr_set_ithresh(&(*p)->p, EQCR_ITHRESH);
138231 + return eq;
138232 +}
138233 +static noinline struct qm_eqcr_entry *wait_eq_start(struct qman_portal **p,
138234 + unsigned long *irqflags __maybe_unused,
138235 + struct qman_fq *fq,
138236 + const struct qm_fd *fd,
138237 + u32 flags)
138238 +{
138239 + struct qm_eqcr_entry *eq;
138240 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138241 + /* NB: return NULL if signal occurs before completion. Signal
138242 + * can occur during return. Caller must check for signal */
138243 + wait_event_interruptible(affine_queue,
138244 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138245 + else
138246 + wait_event(affine_queue,
138247 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138248 + return eq;
138249 +}
138250 +static noinline struct qm_eqcr_entry *__wait_p_eq_start(struct qman_portal *p,
138251 + unsigned long *irqflags __maybe_unused,
138252 + struct qman_fq *fq,
138253 + const struct qm_fd *fd,
138254 + u32 flags)
138255 +{
138256 + struct qm_eqcr_entry *eq = try_p_eq_start(p, irqflags, fq, fd, flags);
138257 + if (!eq)
138258 + qm_eqcr_set_ithresh(&p->p, EQCR_ITHRESH);
138259 + return eq;
138260 +}
138261 +static noinline struct qm_eqcr_entry *wait_p_eq_start(struct qman_portal *p,
138262 + unsigned long *irqflags __maybe_unused,
138263 + struct qman_fq *fq,
138264 + const struct qm_fd *fd,
138265 + u32 flags)
138266 +{
138267 + struct qm_eqcr_entry *eq;
138268 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138269 + /* NB: return NULL if signal occurs before completion. Signal
138270 + * can occur during return. Caller must check for signal */
138271 + wait_event_interruptible(affine_queue,
138272 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138273 + else
138274 + wait_event(affine_queue,
138275 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138276 + return eq;
138277 +}
138278 +#endif
138279 +
138280 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
138281 + const struct qm_fd *fd, u32 flags)
138282 +{
138283 + struct qm_eqcr_entry *eq;
138284 + unsigned long irqflags __maybe_unused;
138285 +
138286 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138287 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138288 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138289 + else
138290 +#endif
138291 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138292 + if (!eq)
138293 + return -EBUSY;
138294 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138295 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138296 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138297 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138298 + PORTAL_IRQ_UNLOCK(p, irqflags);
138299 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138300 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138301 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138302 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138303 + /* NB: return success even if signal occurs before
138304 + * condition is true. pvb_commit guarantees success */
138305 + wait_event_interruptible(affine_queue,
138306 + (p->eqci_owned != fq));
138307 + else
138308 + wait_event(affine_queue, (p->eqci_owned != fq));
138309 + }
138310 +#endif
138311 + return 0;
138312 +}
138313 +EXPORT_SYMBOL(qman_p_enqueue);
138314 +
138315 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags)
138316 +{
138317 + struct qman_portal *p;
138318 + struct qm_eqcr_entry *eq;
138319 + unsigned long irqflags __maybe_unused;
138320 +
138321 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138322 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138323 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138324 + else
138325 +#endif
138326 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138327 + if (!eq)
138328 + return -EBUSY;
138329 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138330 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138331 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138332 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138333 + PORTAL_IRQ_UNLOCK(p, irqflags);
138334 + put_affine_portal();
138335 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138336 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138337 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138338 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138339 + /* NB: return success even if signal occurs before
138340 + * condition is true. pvb_commit guarantees success */
138341 + wait_event_interruptible(affine_queue,
138342 + (p->eqci_owned != fq));
138343 + else
138344 + wait_event(affine_queue, (p->eqci_owned != fq));
138345 + }
138346 +#endif
138347 + return 0;
138348 +}
138349 +EXPORT_SYMBOL(qman_enqueue);
138350 +
138351 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
138352 + const struct qm_fd *fd, u32 flags,
138353 + struct qman_fq *orp, u16 orp_seqnum)
138354 +{
138355 + struct qm_eqcr_entry *eq;
138356 + unsigned long irqflags __maybe_unused;
138357 +
138358 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138359 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138360 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138361 + else
138362 +#endif
138363 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138364 + if (!eq)
138365 + return -EBUSY;
138366 + /* Process ORP-specifics here */
138367 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
138368 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
138369 + else {
138370 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
138371 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
138372 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
138373 + else
138374 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
138375 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
138376 + }
138377 + eq->seqnum = cpu_to_be16(orp_seqnum);
138378 + eq->orp = cpu_to_be32(orp->fqid);
138379 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138380 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
138381 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
138382 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
138383 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138384 + PORTAL_IRQ_UNLOCK(p, irqflags);
138385 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138386 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138387 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138388 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138389 + /* NB: return success even if signal occurs before
138390 + * condition is true. pvb_commit guarantees success */
138391 + wait_event_interruptible(affine_queue,
138392 + (p->eqci_owned != fq));
138393 + else
138394 + wait_event(affine_queue, (p->eqci_owned != fq));
138395 + }
138396 +#endif
138397 + return 0;
138398 +}
138399 +EXPORT_SYMBOL(qman_p_enqueue_orp);
138400 +
138401 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
138402 + struct qman_fq *orp, u16 orp_seqnum)
138403 +{
138404 + struct qman_portal *p;
138405 + struct qm_eqcr_entry *eq;
138406 + unsigned long irqflags __maybe_unused;
138407 +
138408 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138409 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138410 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138411 + else
138412 +#endif
138413 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138414 + if (!eq)
138415 + return -EBUSY;
138416 + /* Process ORP-specifics here */
138417 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
138418 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
138419 + else {
138420 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
138421 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
138422 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
138423 + else
138424 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
138425 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
138426 + }
138427 + eq->seqnum = cpu_to_be16(orp_seqnum);
138428 + eq->orp = cpu_to_be32(orp->fqid);
138429 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138430 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
138431 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
138432 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
138433 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138434 + PORTAL_IRQ_UNLOCK(p, irqflags);
138435 + put_affine_portal();
138436 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138437 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138438 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138439 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138440 + /* NB: return success even if signal occurs before
138441 + * condition is true. pvb_commit guarantees success */
138442 + wait_event_interruptible(affine_queue,
138443 + (p->eqci_owned != fq));
138444 + else
138445 + wait_event(affine_queue, (p->eqci_owned != fq));
138446 + }
138447 +#endif
138448 + return 0;
138449 +}
138450 +EXPORT_SYMBOL(qman_enqueue_orp);
138451 +
138452 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
138453 + const struct qm_fd *fd, u32 flags,
138454 + qman_cb_precommit cb, void *cb_arg)
138455 +{
138456 + struct qm_eqcr_entry *eq;
138457 + unsigned long irqflags __maybe_unused;
138458 +
138459 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138460 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138461 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138462 + else
138463 +#endif
138464 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138465 + if (!eq)
138466 + return -EBUSY;
138467 + /* invoke user supplied callback function before writing commit verb */
138468 + if (cb(cb_arg)) {
138469 + PORTAL_IRQ_UNLOCK(p, irqflags);
138470 + return -EINVAL;
138471 + }
138472 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138473 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138474 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138475 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138476 + PORTAL_IRQ_UNLOCK(p, irqflags);
138477 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138478 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138479 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138480 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138481 + /* NB: return success even if signal occurs before
138482 + * condition is true. pvb_commit guarantees success */
138483 + wait_event_interruptible(affine_queue,
138484 + (p->eqci_owned != fq));
138485 + else
138486 + wait_event(affine_queue, (p->eqci_owned != fq));
138487 + }
138488 +#endif
138489 + return 0;
138490 +}
138491 +EXPORT_SYMBOL(qman_p_enqueue_precommit);
138492 +
138493 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
138494 + u32 flags, qman_cb_precommit cb, void *cb_arg)
138495 +{
138496 + struct qman_portal *p;
138497 + struct qm_eqcr_entry *eq;
138498 + unsigned long irqflags __maybe_unused;
138499 +
138500 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138501 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138502 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138503 + else
138504 +#endif
138505 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138506 + if (!eq)
138507 + return -EBUSY;
138508 + /* invoke user supplied callback function before writing commit verb */
138509 + if (cb(cb_arg)) {
138510 + PORTAL_IRQ_UNLOCK(p, irqflags);
138511 + put_affine_portal();
138512 + return -EINVAL;
138513 + }
138514 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138515 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138516 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138517 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138518 + PORTAL_IRQ_UNLOCK(p, irqflags);
138519 + put_affine_portal();
138520 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138521 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138522 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138523 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138524 + /* NB: return success even if signal occurs before
138525 + * condition is true. pvb_commit guarantees success */
138526 + wait_event_interruptible(affine_queue,
138527 + (p->eqci_owned != fq));
138528 + else
138529 + wait_event(affine_queue, (p->eqci_owned != fq));
138530 + }
138531 +#endif
138532 + return 0;
138533 +}
138534 +EXPORT_SYMBOL(qman_enqueue_precommit);
138535 +
138536 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
138537 + struct qm_mcc_initcgr *opts)
138538 +{
138539 + struct qm_mc_command *mcc;
138540 + struct qm_mc_result *mcr;
138541 + struct qman_portal *p = get_affine_portal();
138542 + unsigned long irqflags __maybe_unused;
138543 + u8 res;
138544 + u8 verb = QM_MCC_VERB_MODIFYCGR;
138545 +
138546 + PORTAL_IRQ_LOCK(p, irqflags);
138547 + mcc = qm_mc_start(&p->p);
138548 + if (opts)
138549 + mcc->initcgr = *opts;
138550 + mcc->initcgr.we_mask = cpu_to_be16(mcc->initcgr.we_mask);
138551 + mcc->initcgr.cgr.wr_parm_g.word =
138552 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_g.word);
138553 + mcc->initcgr.cgr.wr_parm_y.word =
138554 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_y.word);
138555 + mcc->initcgr.cgr.wr_parm_r.word =
138556 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_r.word);
138557 + mcc->initcgr.cgr.cscn_targ = cpu_to_be32(mcc->initcgr.cgr.cscn_targ);
138558 + mcc->initcgr.cgr.__cs_thres = cpu_to_be16(mcc->initcgr.cgr.__cs_thres);
138559 +
138560 + mcc->initcgr.cgid = cgr->cgrid;
138561 + if (flags & QMAN_CGR_FLAG_USE_INIT)
138562 + verb = QM_MCC_VERB_INITCGR;
138563 + qm_mc_commit(&p->p, verb);
138564 + while (!(mcr = qm_mc_result(&p->p)))
138565 + cpu_relax();
138566 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == verb);
138567 + res = mcr->result;
138568 + PORTAL_IRQ_UNLOCK(p, irqflags);
138569 + put_affine_portal();
138570 + return (res == QM_MCR_RESULT_OK) ? 0 : -EIO;
138571 +}
138572 +EXPORT_SYMBOL(qman_modify_cgr);
138573 +
138574 +#define TARG_MASK(n) (0x80000000 >> (n->config->public_cfg.channel - \
138575 + QM_CHANNEL_SWPORTAL0))
138576 +#define TARG_DCP_MASK(n) (0x80000000 >> (10 + n))
138577 +#define PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0)
138578 +
138579 +static u8 qman_cgr_cpus[__CGR_NUM];
138580 +
138581 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
138582 + struct qm_mcc_initcgr *opts)
138583 +{
138584 + unsigned long irqflags __maybe_unused;
138585 + struct qm_mcr_querycgr cgr_state;
138586 + struct qm_mcc_initcgr local_opts;
138587 + int ret;
138588 + struct qman_portal *p;
138589 +
138590 + /* We have to check that the provided CGRID is within the limits of the
138591 + * data-structures, for obvious reasons. However we'll let h/w take
138592 + * care of determining whether it's within the limits of what exists on
138593 + * the SoC. */
138594 + if (cgr->cgrid >= __CGR_NUM)
138595 + return -EINVAL;
138596 +
138597 + preempt_disable();
138598 + p = get_affine_portal();
138599 + qman_cgr_cpus[cgr->cgrid] = smp_processor_id();
138600 + preempt_enable();
138601 +
138602 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
138603 + cgr->chan = p->config->public_cfg.channel;
138604 + spin_lock_irqsave(&p->cgr_lock, irqflags);
138605 +
138606 + /* if no opts specified, just add it to the list */
138607 + if (!opts)
138608 + goto add_list;
138609 +
138610 + ret = qman_query_cgr(cgr, &cgr_state);
138611 + if (ret)
138612 + goto release_lock;
138613 + if (opts)
138614 + local_opts = *opts;
138615 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
138616 + local_opts.cgr.cscn_targ_upd_ctrl =
138617 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p);
138618 + else
138619 + /* Overwrite TARG */
138620 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
138621 + TARG_MASK(p);
138622 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
138623 +
138624 + /* send init if flags indicate so */
138625 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
138626 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT, &local_opts);
138627 + else
138628 + ret = qman_modify_cgr(cgr, 0, &local_opts);
138629 + if (ret)
138630 + goto release_lock;
138631 +add_list:
138632 + list_add(&cgr->node, &p->cgr_cbs);
138633 +
138634 + /* Determine if newly added object requires its callback to be called */
138635 + ret = qman_query_cgr(cgr, &cgr_state);
138636 + if (ret) {
138637 + /* we can't go back, so proceed and return success, but screen
138638 + * and wail to the log file */
138639 + pr_crit("CGR HW state partially modified\n");
138640 + ret = 0;
138641 + goto release_lock;
138642 + }
138643 + if (cgr->cb && cgr_state.cgr.cscn_en && qman_cgrs_get(&p->cgrs[1],
138644 + cgr->cgrid))
138645 + cgr->cb(p, cgr, 1);
138646 +release_lock:
138647 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
138648 + put_affine_portal();
138649 + return ret;
138650 +}
138651 +EXPORT_SYMBOL(qman_create_cgr);
138652 +
138653 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
138654 + struct qm_mcc_initcgr *opts)
138655 +{
138656 + unsigned long irqflags __maybe_unused;
138657 + struct qm_mcc_initcgr local_opts;
138658 + struct qm_mcr_querycgr cgr_state;
138659 + int ret;
138660 +
138661 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30) {
138662 + pr_warn("This QMan version doesn't support to send CSCN to DCP portal\n");
138663 + return -EINVAL;
138664 + }
138665 + /* We have to check that the provided CGRID is within the limits of the
138666 + * data-structures, for obvious reasons. However we'll let h/w take
138667 + * care of determining whether it's within the limits of what exists on
138668 + * the SoC.
138669 + */
138670 + if (cgr->cgrid >= __CGR_NUM)
138671 + return -EINVAL;
138672 +
138673 + ret = qman_query_cgr(cgr, &cgr_state);
138674 + if (ret)
138675 + return ret;
138676 +
138677 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
138678 + if (opts)
138679 + local_opts = *opts;
138680 +
138681 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
138682 + local_opts.cgr.cscn_targ_upd_ctrl =
138683 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT |
138684 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_portal;
138685 + else
138686 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
138687 + TARG_DCP_MASK(dcp_portal);
138688 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
138689 +
138690 + /* send init if flags indicate so */
138691 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
138692 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT,
138693 + &local_opts);
138694 + else
138695 + ret = qman_modify_cgr(cgr, 0, &local_opts);
138696 +
138697 + return ret;
138698 +}
138699 +EXPORT_SYMBOL(qman_create_cgr_to_dcp);
138700 +
138701 +int qman_delete_cgr(struct qman_cgr *cgr)
138702 +{
138703 + unsigned long irqflags __maybe_unused;
138704 + struct qm_mcr_querycgr cgr_state;
138705 + struct qm_mcc_initcgr local_opts;
138706 + int ret = 0;
138707 + struct qman_cgr *i;
138708 + struct qman_portal *p = get_affine_portal();
138709 +
138710 + if (cgr->chan != p->config->public_cfg.channel) {
138711 + pr_crit("Attempting to delete cgr from different portal "
138712 + "than it was create: create 0x%x, delete 0x%x\n",
138713 + cgr->chan, p->config->public_cfg.channel);
138714 + ret = -EINVAL;
138715 + goto put_portal;
138716 + }
138717 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
138718 + spin_lock_irqsave(&p->cgr_lock, irqflags);
138719 + list_del(&cgr->node);
138720 + /*
138721 + * If there are no other CGR objects for this CGRID in the list, update
138722 + * CSCN_TARG accordingly
138723 + */
138724 + list_for_each_entry(i, &p->cgr_cbs, node)
138725 + if ((i->cgrid == cgr->cgrid) && i->cb)
138726 + goto release_lock;
138727 + ret = qman_query_cgr(cgr, &cgr_state);
138728 + if (ret) {
138729 + /* add back to the list */
138730 + list_add(&cgr->node, &p->cgr_cbs);
138731 + goto release_lock;
138732 + }
138733 + /* Overwrite TARG */
138734 + local_opts.we_mask = QM_CGR_WE_CSCN_TARG;
138735 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
138736 + local_opts.cgr.cscn_targ_upd_ctrl = PORTAL_IDX(p);
138737 + else
138738 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ &
138739 + ~(TARG_MASK(p));
138740 + ret = qman_modify_cgr(cgr, 0, &local_opts);
138741 + if (ret)
138742 + /* add back to the list */
138743 + list_add(&cgr->node, &p->cgr_cbs);
138744 +release_lock:
138745 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
138746 +put_portal:
138747 + put_affine_portal();
138748 + return ret;
138749 +}
138750 +EXPORT_SYMBOL(qman_delete_cgr);
138751 +
138752 +struct cgr_comp {
138753 + struct qman_cgr *cgr;
138754 + struct completion completion;
138755 +};
138756 +
138757 +static int qman_delete_cgr_thread(void *p)
138758 +{
138759 + struct cgr_comp *cgr_comp = (struct cgr_comp *)p;
138760 + int res;
138761 +
138762 + res = qman_delete_cgr((struct qman_cgr *)cgr_comp->cgr);
138763 + complete(&cgr_comp->completion);
138764 +
138765 + return res;
138766 +}
138767 +
138768 +void qman_delete_cgr_safe(struct qman_cgr *cgr)
138769 +{
138770 + struct task_struct *thread;
138771 + struct cgr_comp cgr_comp;
138772 +
138773 + preempt_disable();
138774 + if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
138775 + init_completion(&cgr_comp.completion);
138776 + cgr_comp.cgr = cgr;
138777 + thread = kthread_create(qman_delete_cgr_thread, &cgr_comp,
138778 + "cgr_del");
138779 +
138780 + if (likely(!IS_ERR(thread))) {
138781 + kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]);
138782 + wake_up_process(thread);
138783 + wait_for_completion(&cgr_comp.completion);
138784 + preempt_enable();
138785 + return;
138786 + }
138787 + }
138788 + qman_delete_cgr(cgr);
138789 + preempt_enable();
138790 +}
138791 +EXPORT_SYMBOL(qman_delete_cgr_safe);
138792 +
138793 +int qm_get_clock(u64 *clock_hz)
138794 +{
138795 + if (!qman_clk) {
138796 + pr_warn("Qman clock speed is unknown\n");
138797 + return -EINVAL;
138798 + }
138799 + *clock_hz = (u64)qman_clk;
138800 + return 0;
138801 +}
138802 +EXPORT_SYMBOL(qm_get_clock);
138803 +
138804 +int qm_set_clock(u64 clock_hz)
138805 +{
138806 + if (qman_clk)
138807 + return -1;
138808 + qman_clk = (u32)clock_hz;
138809 + return 0;
138810 +}
138811 +EXPORT_SYMBOL(qm_set_clock);
138812 +
138813 +/* CEETM management command */
138814 +static int qman_ceetm_configure_lfqmt(struct qm_mcc_ceetm_lfqmt_config *opts)
138815 +{
138816 + struct qm_mc_command *mcc;
138817 + struct qm_mc_result *mcr;
138818 + struct qman_portal *p;
138819 + unsigned long irqflags __maybe_unused;
138820 + u8 res;
138821 +
138822 + p = get_affine_portal();
138823 + PORTAL_IRQ_LOCK(p, irqflags);
138824 +
138825 + mcc = qm_mc_start(&p->p);
138826 + mcc->lfqmt_config = *opts;
138827 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_CONFIG);
138828 + while (!(mcr = qm_mc_result(&p->p)))
138829 + cpu_relax();
138830 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
138831 + QM_CEETM_VERB_LFQMT_CONFIG);
138832 + PORTAL_IRQ_UNLOCK(p, irqflags);
138833 + put_affine_portal();
138834 +
138835 + res = mcr->result;
138836 + if (res != QM_MCR_RESULT_OK) {
138837 + pr_err("CEETM: CONFIGURE LFQMT failed\n");
138838 + return -EIO;
138839 + }
138840 + return 0;
138841 +}
138842 +
138843 +int qman_ceetm_query_lfqmt(int lfqid,
138844 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query)
138845 +{
138846 + struct qm_mc_command *mcc;
138847 + struct qm_mc_result *mcr;
138848 + struct qman_portal *p;
138849 + unsigned long irqflags __maybe_unused;
138850 + u8 res;
138851 +
138852 + p = get_affine_portal();
138853 + PORTAL_IRQ_LOCK(p, irqflags);
138854 +
138855 + mcc = qm_mc_start(&p->p);
138856 + mcc->lfqmt_query.lfqid = lfqid;
138857 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_QUERY);
138858 + while (!(mcr = qm_mc_result(&p->p)))
138859 + cpu_relax();
138860 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_LFQMT_QUERY);
138861 + res = mcr->result;
138862 + if (res == QM_MCR_RESULT_OK)
138863 + *lfqmt_query = mcr->lfqmt_query;
138864 +
138865 + PORTAL_IRQ_UNLOCK(p, irqflags);
138866 + put_affine_portal();
138867 + if (res != QM_MCR_RESULT_OK) {
138868 + pr_err("CEETM: QUERY LFQMT failed\n");
138869 + return -EIO;
138870 + }
138871 + return 0;
138872 +}
138873 +EXPORT_SYMBOL(qman_ceetm_query_lfqmt);
138874 +
138875 +static int qman_ceetm_configure_cq(struct qm_mcc_ceetm_cq_config *opts)
138876 +{
138877 + struct qm_mc_command *mcc;
138878 + struct qm_mc_result *mcr;
138879 + struct qman_portal *p;
138880 + unsigned long irqflags __maybe_unused;
138881 + u8 res;
138882 +
138883 + p = get_affine_portal();
138884 + PORTAL_IRQ_LOCK(p, irqflags);
138885 +
138886 + mcc = qm_mc_start(&p->p);
138887 + mcc->cq_config = *opts;
138888 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_CONFIG);
138889 + while (!(mcr = qm_mc_result(&p->p)))
138890 + cpu_relax();
138891 + res = mcr->result;
138892 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_CONFIG);
138893 +
138894 + PORTAL_IRQ_UNLOCK(p, irqflags);
138895 + put_affine_portal();
138896 +
138897 + if (res != QM_MCR_RESULT_OK) {
138898 + pr_err("CEETM: CONFIGURE CQ failed\n");
138899 + return -EIO;
138900 + }
138901 + return 0;
138902 +}
138903 +
138904 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
138905 + struct qm_mcr_ceetm_cq_query *cq_query)
138906 +{
138907 + struct qm_mc_command *mcc;
138908 + struct qm_mc_result *mcr;
138909 + struct qman_portal *p;
138910 + unsigned long irqflags __maybe_unused;
138911 + u8 res;
138912 +
138913 + p = get_affine_portal();
138914 + PORTAL_IRQ_LOCK(p, irqflags);
138915 +
138916 + mcc = qm_mc_start(&p->p);
138917 + mcc->cq_query.cqid = cpu_to_be16(cqid);
138918 + mcc->cq_query.dcpid = dcpid;
138919 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_QUERY);
138920 + while (!(mcr = qm_mc_result(&p->p)))
138921 + cpu_relax();
138922 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_QUERY);
138923 + res = mcr->result;
138924 + if (res == QM_MCR_RESULT_OK) {
138925 + *cq_query = mcr->cq_query;
138926 + hw_cq_query_to_cpu(cq_query);
138927 + }
138928 +
138929 + PORTAL_IRQ_UNLOCK(p, irqflags);
138930 + put_affine_portal();
138931 +
138932 + if (res != QM_MCR_RESULT_OK) {
138933 + pr_err("CEETM: QUERY CQ failed\n");
138934 + return -EIO;
138935 + }
138936 +
138937 + return 0;
138938 +}
138939 +EXPORT_SYMBOL(qman_ceetm_query_cq);
138940 +
138941 +static int qman_ceetm_configure_dct(struct qm_mcc_ceetm_dct_config *opts)
138942 +{
138943 + struct qm_mc_command *mcc;
138944 + struct qm_mc_result *mcr;
138945 + struct qman_portal *p;
138946 + unsigned long irqflags __maybe_unused;
138947 + u8 res;
138948 +
138949 + p = get_affine_portal();
138950 + PORTAL_IRQ_LOCK(p, irqflags);
138951 +
138952 + mcc = qm_mc_start(&p->p);
138953 + mcc->dct_config = *opts;
138954 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_CONFIG);
138955 + while (!(mcr = qm_mc_result(&p->p)))
138956 + cpu_relax();
138957 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_CONFIG);
138958 + res = mcr->result;
138959 +
138960 + PORTAL_IRQ_UNLOCK(p, irqflags);
138961 + put_affine_portal();
138962 +
138963 + if (res != QM_MCR_RESULT_OK) {
138964 + pr_err("CEETM: CONFIGURE DCT failed\n");
138965 + return -EIO;
138966 + }
138967 + return 0;
138968 +}
138969 +
138970 +static int qman_ceetm_query_dct(struct qm_mcc_ceetm_dct_query *opts,
138971 + struct qm_mcr_ceetm_dct_query *dct_query)
138972 +{
138973 + struct qm_mc_command *mcc;
138974 + struct qm_mc_result *mcr;
138975 + struct qman_portal *p = get_affine_portal();
138976 + unsigned long irqflags __maybe_unused;
138977 + u8 res;
138978 +
138979 + PORTAL_IRQ_LOCK(p, irqflags);
138980 +
138981 + mcc = qm_mc_start(&p->p);
138982 + mcc->dct_query = *opts;
138983 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_QUERY);
138984 + while (!(mcr = qm_mc_result(&p->p)))
138985 + cpu_relax();
138986 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_QUERY);
138987 + res = mcr->result;
138988 +
138989 + PORTAL_IRQ_UNLOCK(p, irqflags);
138990 + put_affine_portal();
138991 +
138992 + if (res != QM_MCR_RESULT_OK) {
138993 + pr_err("CEETM: QUERY DCT failed\n");
138994 + return -EIO;
138995 + }
138996 +
138997 + *dct_query = mcr->dct_query;
138998 + return 0;
138999 +}
139000 +
139001 +static int qman_ceetm_configure_class_scheduler(
139002 + struct qm_mcc_ceetm_class_scheduler_config *opts)
139003 +{
139004 + struct qm_mc_command *mcc;
139005 + struct qm_mc_result *mcr;
139006 + struct qman_portal *p;
139007 + unsigned long irqflags __maybe_unused;
139008 + u8 res;
139009 +
139010 + p = get_affine_portal();
139011 + PORTAL_IRQ_LOCK(p, irqflags);
139012 +
139013 + mcc = qm_mc_start(&p->p);
139014 + mcc->csch_config = *opts;
139015 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
139016 + while (!(mcr = qm_mc_result(&p->p)))
139017 + cpu_relax();
139018 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139019 + QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
139020 + res = mcr->result;
139021 +
139022 + PORTAL_IRQ_UNLOCK(p, irqflags);
139023 + put_affine_portal();
139024 +
139025 + if (res != QM_MCR_RESULT_OK) {
139026 + pr_err("CEETM: CONFIGURE CLASS SCHEDULER failed\n");
139027 + return -EIO;
139028 + }
139029 + return 0;
139030 +}
139031 +
139032 +static int qman_ceetm_query_class_scheduler(struct qm_ceetm_channel *channel,
139033 + struct qm_mcr_ceetm_class_scheduler_query *query)
139034 +{
139035 + struct qm_mc_command *mcc;
139036 + struct qm_mc_result *mcr;
139037 + struct qman_portal *p;
139038 + unsigned long irqflags __maybe_unused;
139039 + u8 res;
139040 +
139041 + p = get_affine_portal();
139042 + PORTAL_IRQ_LOCK(p, irqflags);
139043 +
139044 + mcc = qm_mc_start(&p->p);
139045 + mcc->csch_query.cqcid = cpu_to_be16(channel->idx);
139046 + mcc->csch_query.dcpid = channel->dcp_idx;
139047 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
139048 + while (!(mcr = qm_mc_result(&p->p)))
139049 + cpu_relax();
139050 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139051 + QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
139052 + res = mcr->result;
139053 +
139054 + PORTAL_IRQ_UNLOCK(p, irqflags);
139055 + put_affine_portal();
139056 +
139057 + if (res != QM_MCR_RESULT_OK) {
139058 + pr_err("CEETM: QUERY CLASS SCHEDULER failed\n");
139059 + return -EIO;
139060 + }
139061 + *query = mcr->csch_query;
139062 + return 0;
139063 +}
139064 +
139065 +static int qman_ceetm_configure_mapping_shaper_tcfc(
139066 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config *opts)
139067 +{
139068 + struct qm_mc_command *mcc;
139069 + struct qm_mc_result *mcr;
139070 + struct qman_portal *p;
139071 + unsigned long irqflags __maybe_unused;
139072 + u8 res;
139073 +
139074 + p = get_affine_portal();
139075 + PORTAL_IRQ_LOCK(p, irqflags);
139076 +
139077 + mcc = qm_mc_start(&p->p);
139078 + mcc->mst_config = *opts;
139079 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
139080 + while (!(mcr = qm_mc_result(&p->p)))
139081 + cpu_relax();
139082 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139083 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
139084 + res = mcr->result;
139085 +
139086 + PORTAL_IRQ_UNLOCK(p, irqflags);
139087 + put_affine_portal();
139088 +
139089 + if (res != QM_MCR_RESULT_OK) {
139090 + pr_err("CEETM: CONFIGURE CHANNEL MAPPING failed\n");
139091 + return -EIO;
139092 + }
139093 + return 0;
139094 +}
139095 +
139096 +static int qman_ceetm_query_mapping_shaper_tcfc(
139097 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query *opts,
139098 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query *response)
139099 +{
139100 + struct qm_mc_command *mcc;
139101 + struct qm_mc_result *mcr;
139102 + struct qman_portal *p;
139103 + unsigned long irqflags __maybe_unused;
139104 + u8 res;
139105 +
139106 + p = get_affine_portal();
139107 + PORTAL_IRQ_LOCK(p, irqflags);
139108 +
139109 + mcc = qm_mc_start(&p->p);
139110 + mcc->mst_query = *opts;
139111 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
139112 + while (!(mcr = qm_mc_result(&p->p)))
139113 + cpu_relax();
139114 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139115 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
139116 + res = mcr->result;
139117 +
139118 + PORTAL_IRQ_UNLOCK(p, irqflags);
139119 + put_affine_portal();
139120 +
139121 + if (res != QM_MCR_RESULT_OK) {
139122 + pr_err("CEETM: QUERY CHANNEL MAPPING failed\n");
139123 + return -EIO;
139124 + }
139125 +
139126 + *response = mcr->mst_query;
139127 + return 0;
139128 +}
139129 +
139130 +static int qman_ceetm_configure_ccgr(struct qm_mcc_ceetm_ccgr_config *opts)
139131 +{
139132 + struct qm_mc_command *mcc;
139133 + struct qm_mc_result *mcr;
139134 + struct qman_portal *p;
139135 + unsigned long irqflags __maybe_unused;
139136 + u8 res;
139137 +
139138 + p = get_affine_portal();
139139 + PORTAL_IRQ_LOCK(p, irqflags);
139140 +
139141 + mcc = qm_mc_start(&p->p);
139142 + mcc->ccgr_config = *opts;
139143 +
139144 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_CONFIG);
139145 + while (!(mcr = qm_mc_result(&p->p)))
139146 + cpu_relax();
139147 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_CONFIG);
139148 +
139149 + PORTAL_IRQ_UNLOCK(p, irqflags);
139150 + put_affine_portal();
139151 +
139152 + res = mcr->result;
139153 + if (res != QM_MCR_RESULT_OK) {
139154 + pr_err("CEETM: CONFIGURE CCGR failed\n");
139155 + return -EIO;
139156 + }
139157 + return 0;
139158 +}
139159 +
139160 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
139161 + struct qm_mcr_ceetm_ccgr_query *response)
139162 +{
139163 + struct qm_mc_command *mcc;
139164 + struct qm_mc_result *mcr;
139165 + struct qman_portal *p;
139166 + unsigned long irqflags __maybe_unused;
139167 + u8 res;
139168 +
139169 + p = get_affine_portal();
139170 + PORTAL_IRQ_LOCK(p, irqflags);
139171 +
139172 + mcc = qm_mc_start(&p->p);
139173 + mcc->ccgr_query.ccgrid = cpu_to_be16(ccgr_query->ccgrid);
139174 + mcc->ccgr_query.dcpid = ccgr_query->dcpid;
139175 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
139176 +
139177 + while (!(mcr = qm_mc_result(&p->p)))
139178 + cpu_relax();
139179 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_QUERY);
139180 + res = mcr->result;
139181 + if (res == QM_MCR_RESULT_OK) {
139182 + *response = mcr->ccgr_query;
139183 + hw_ccgr_query_to_cpu(response);
139184 + }
139185 +
139186 + PORTAL_IRQ_UNLOCK(p, irqflags);
139187 + put_affine_portal();
139188 + if (res != QM_MCR_RESULT_OK) {
139189 + pr_err("CEETM: QUERY CCGR failed\n");
139190 + return -EIO;
139191 + }
139192 + return 0;
139193 +}
139194 +EXPORT_SYMBOL(qman_ceetm_query_ccgr);
139195 +
139196 +static int qman_ceetm_cq_peek_pop_xsfdrread(struct qm_ceetm_cq *cq,
139197 + u8 command_type, u16 xsfdr,
139198 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread *cq_ppxr)
139199 +{
139200 + struct qm_mc_command *mcc;
139201 + struct qm_mc_result *mcr;
139202 + struct qman_portal *p;
139203 + unsigned long irqflags __maybe_unused;
139204 + u8 res;
139205 +
139206 + p = get_affine_portal();
139207 + PORTAL_IRQ_LOCK(p, irqflags);
139208 +
139209 + mcc = qm_mc_start(&p->p);
139210 + switch (command_type) {
139211 + case 0:
139212 + case 1:
139213 + mcc->cq_ppxr.cqid = (cq->parent->idx << 4) | cq->idx;
139214 + break;
139215 + case 2:
139216 + mcc->cq_ppxr.xsfdr = xsfdr;
139217 + break;
139218 + default:
139219 + break;
139220 + }
139221 + mcc->cq_ppxr.ct = command_type;
139222 + mcc->cq_ppxr.dcpid = cq->parent->dcp_idx;
139223 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139224 + while (!(mcr = qm_mc_result(&p->p)))
139225 + cpu_relax();
139226 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139227 + QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139228 +
139229 + PORTAL_IRQ_UNLOCK(p, irqflags);
139230 + put_affine_portal();
139231 +
139232 + res = mcr->result;
139233 + if (res != QM_MCR_RESULT_OK) {
139234 + pr_err("CEETM: CQ PEEK/POP/XSFDR READ failed\n");
139235 + return -EIO;
139236 + }
139237 + *cq_ppxr = mcr->cq_ppxr;
139238 + return 0;
139239 +}
139240 +
139241 +static int qman_ceetm_query_statistics(u16 cid,
139242 + enum qm_dc_portal dcp_idx,
139243 + u16 command_type,
139244 + struct qm_mcr_ceetm_statistics_query *query_result)
139245 +{
139246 + struct qm_mc_command *mcc;
139247 + struct qm_mc_result *mcr;
139248 + struct qman_portal *p;
139249 + unsigned long irqflags __maybe_unused;
139250 + u8 res;
139251 +
139252 + p = get_affine_portal();
139253 + PORTAL_IRQ_LOCK(p, irqflags);
139254 +
139255 + mcc = qm_mc_start(&p->p);
139256 + mcc->stats_query_write.cid = cid;
139257 + mcc->stats_query_write.dcpid = dcp_idx;
139258 + mcc->stats_query_write.ct = command_type;
139259 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139260 +
139261 + while (!(mcr = qm_mc_result(&p->p)))
139262 + cpu_relax();
139263 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139264 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139265 +
139266 + PORTAL_IRQ_UNLOCK(p, irqflags);
139267 + put_affine_portal();
139268 +
139269 + res = mcr->result;
139270 + if (res != QM_MCR_RESULT_OK) {
139271 + pr_err("CEETM: STATISTICS QUERY failed\n");
139272 + return -EIO;
139273 + }
139274 + *query_result = mcr->stats_query;
139275 + return 0;
139276 +}
139277 +
139278 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
139279 + u16 command_type, u64 frame_count,
139280 + u64 byte_count)
139281 +{
139282 + struct qm_mc_command *mcc;
139283 + struct qm_mc_result *mcr;
139284 + struct qman_portal *p;
139285 + unsigned long irqflags __maybe_unused;
139286 + u8 res;
139287 +
139288 + p = get_affine_portal();
139289 + PORTAL_IRQ_LOCK(p, irqflags);
139290 +
139291 + mcc = qm_mc_start(&p->p);
139292 + mcc->stats_query_write.cid = cid;
139293 + mcc->stats_query_write.dcpid = dcp_idx;
139294 + mcc->stats_query_write.ct = command_type;
139295 + mcc->stats_query_write.frm_cnt = frame_count;
139296 + mcc->stats_query_write.byte_cnt = byte_count;
139297 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139298 +
139299 + while (!(mcr = qm_mc_result(&p->p)))
139300 + cpu_relax();
139301 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139302 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139303 +
139304 + PORTAL_IRQ_UNLOCK(p, irqflags);
139305 + put_affine_portal();
139306 +
139307 + res = mcr->result;
139308 + if (res != QM_MCR_RESULT_OK) {
139309 + pr_err("CEETM: STATISTICS WRITE failed\n");
139310 + return -EIO;
139311 + }
139312 + return 0;
139313 +}
139314 +EXPORT_SYMBOL(qman_ceetm_query_write_statistics);
139315 +
139316 +int qman_ceetm_bps2tokenrate(u64 bps, struct qm_ceetm_rate *token_rate,
139317 + int rounding)
139318 +{
139319 + u16 pres;
139320 + u64 temp;
139321 + u64 qman_freq;
139322 + int ret;
139323 +
139324 + /* Read PRES from CEET_CFG_PRES register */
139325 + ret = qman_ceetm_get_prescaler(&pres);
139326 + if (ret)
139327 + return -EINVAL;
139328 +
139329 + ret = qm_get_clock(&qman_freq);
139330 + if (ret)
139331 + return -EINVAL;
139332 +
139333 + /* token-rate = bytes-per-second * update-reference-period
139334 + *
139335 + * Where token-rate is N/8192 for a integer N, and
139336 + * update-reference-period is (2^22)/(PRES*QHz), where PRES
139337 + * is the prescalar value and QHz is the QMan clock frequency.
139338 + * So:
139339 + *
139340 + * token-rate = (byte-per-second*2^22)/PRES*QHZ)
139341 + *
139342 + * Converting to bits-per-second gives;
139343 + *
139344 + * token-rate = (bps*2^19) / (PRES*QHZ)
139345 + * N = (bps*2^32) / (PRES*QHz)
139346 + *
139347 + * And to avoid 64-bit overflow if 'bps' is larger than 4Gbps
139348 + * (yet minimise rounding error if 'bps' is small), we reorganise
139349 + * the formula to use two 16-bit shifts rather than 1 32-bit shift.
139350 + * N = (((bps*2^16)/PRES)*2^16)/QHz
139351 + */
139352 + temp = ROUNDING((bps << 16), pres, rounding);
139353 + temp = ROUNDING((temp << 16), qman_freq, rounding);
139354 + token_rate->whole = temp >> 13;
139355 + token_rate->fraction = temp & (((u64)1 << 13) - 1);
139356 + return 0;
139357 +}
139358 +EXPORT_SYMBOL(qman_ceetm_bps2tokenrate);
139359 +
139360 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate, u64 *bps,
139361 + int rounding)
139362 +{
139363 + u16 pres;
139364 + u64 temp;
139365 + u64 qman_freq;
139366 + int ret;
139367 +
139368 + /* Read PRES from CEET_CFG_PRES register */
139369 + ret = qman_ceetm_get_prescaler(&pres);
139370 + if (ret)
139371 + return -EINVAL;
139372 +
139373 + ret = qm_get_clock(&qman_freq);
139374 + if (ret)
139375 + return -EINVAL;
139376 +
139377 + /* bytes-per-second = token-rate / update-reference-period
139378 + *
139379 + * where "token-rate" is N/8192 for an integer N, and
139380 + * "update-reference-period" is (2^22)/(PRES*QHz), where PRES is
139381 + * the prescalar value and QHz is the QMan clock frequency. So;
139382 + *
139383 + * bytes-per-second = (N/8192) / (4194304/PRES*QHz)
139384 + * = N*PRES*QHz / (4194304*8192)
139385 + * = N*PRES*QHz / (2^35)
139386 + *
139387 + * Converting to bits-per-second gives;
139388 + *
139389 + * bps = N*PRES*QHZ / (2^32)
139390 + *
139391 + * Note, the numerator has a maximum width of 72 bits! So to
139392 + * avoid 64-bit overflow errors, we calculate PRES*QHZ (maximum
139393 + * width 48 bits) divided by 2^9 (reducing to maximum 39 bits), before
139394 + * multiplying by N (goes to maximum of 63 bits).
139395 + *
139396 + * temp = PRES*QHZ / (2^16)
139397 + * kbps = temp*N / (2^16)
139398 + */
139399 + temp = ROUNDING(qman_freq * pres, (u64)1 << 16 , rounding);
139400 + temp *= ((token_rate->whole << 13) + token_rate->fraction);
139401 + *bps = ROUNDING(temp, (u64)(1) << 16, rounding);
139402 + return 0;
139403 +}
139404 +EXPORT_SYMBOL(qman_ceetm_tokenrate2bps);
139405 +
139406 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp, enum qm_dc_portal dcp_idx,
139407 + unsigned int sp_idx)
139408 +{
139409 + struct qm_ceetm_sp *p;
139410 +
139411 + DPA_ASSERT((dcp_idx == qm_dc_portal_fman0) ||
139412 + (dcp_idx == qm_dc_portal_fman1));
139413 +
139414 + if ((sp_idx < qman_ceetms[dcp_idx].sp_range[0]) ||
139415 + (sp_idx >= (qman_ceetms[dcp_idx].sp_range[0] +
139416 + qman_ceetms[dcp_idx].sp_range[1]))) {
139417 + pr_err("Sub-portal index doesn't exist\n");
139418 + return -EINVAL;
139419 + }
139420 +
139421 + list_for_each_entry(p, &qman_ceetms[dcp_idx].sub_portals, node) {
139422 + if ((p->idx == sp_idx) && (p->is_claimed == 0)) {
139423 + p->is_claimed = 1;
139424 + *sp = p;
139425 + return 0;
139426 + }
139427 + }
139428 + pr_err("The sub-portal#%d is not available!\n", sp_idx);
139429 + return -ENODEV;
139430 +}
139431 +EXPORT_SYMBOL(qman_ceetm_sp_claim);
139432 +
139433 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp)
139434 +{
139435 + struct qm_ceetm_sp *p;
139436 +
139437 + if (sp->lni && sp->lni->is_claimed == 1) {
139438 + pr_err("The dependency of sub-portal has not been released!\n");
139439 + return -EBUSY;
139440 + }
139441 +
139442 + list_for_each_entry(p, &qman_ceetms[sp->dcp_idx].sub_portals, node) {
139443 + if (p->idx == sp->idx) {
139444 + p->is_claimed = 0;
139445 + p->lni = NULL;
139446 + }
139447 + }
139448 + /* Disable CEETM mode of this sub-portal */
139449 + qman_sp_disable_ceetm_mode(sp->dcp_idx, sp->idx);
139450 +
139451 + return 0;
139452 +}
139453 +EXPORT_SYMBOL(qman_ceetm_sp_release);
139454 +
139455 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni, enum qm_dc_portal dcp_idx,
139456 + unsigned int lni_idx)
139457 +{
139458 + struct qm_ceetm_lni *p;
139459 +
139460 + if ((lni_idx < qman_ceetms[dcp_idx].lni_range[0]) ||
139461 + (lni_idx >= (qman_ceetms[dcp_idx].lni_range[0] +
139462 + qman_ceetms[dcp_idx].lni_range[1]))) {
139463 + pr_err("The lni index is out of range\n");
139464 + return -EINVAL;
139465 + }
139466 +
139467 + list_for_each_entry(p, &qman_ceetms[dcp_idx].lnis, node) {
139468 + if ((p->idx == lni_idx) && (p->is_claimed == 0)) {
139469 + *lni = p;
139470 + p->is_claimed = 1;
139471 + return 0;
139472 + }
139473 + }
139474 +
139475 + pr_err("The LNI#%d is not available!\n", lni_idx);
139476 + return -EINVAL;
139477 +}
139478 +EXPORT_SYMBOL(qman_ceetm_lni_claim);
139479 +
139480 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni)
139481 +{
139482 + struct qm_ceetm_lni *p;
139483 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139484 +
139485 + if (!list_empty(&lni->channels)) {
139486 + pr_err("The LNI dependencies are not released!\n");
139487 + return -EBUSY;
139488 + }
139489 +
139490 + list_for_each_entry(p, &qman_ceetms[lni->dcp_idx].lnis, node) {
139491 + if (p->idx == lni->idx) {
139492 + p->shaper_enable = 0;
139493 + p->shaper_couple = 0;
139494 + p->cr_token_rate.whole = 0;
139495 + p->cr_token_rate.fraction = 0;
139496 + p->er_token_rate.whole = 0;
139497 + p->er_token_rate.fraction = 0;
139498 + p->cr_token_bucket_limit = 0;
139499 + p->er_token_bucket_limit = 0;
139500 + p->is_claimed = 0;
139501 + }
139502 + }
139503 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139504 + config_opts.dcpid = lni->dcp_idx;
139505 + memset(&config_opts.shaper_config, 0,
139506 + sizeof(config_opts.shaper_config));
139507 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139508 +}
139509 +EXPORT_SYMBOL(qman_ceetm_lni_release);
139510 +
139511 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp, struct qm_ceetm_lni *lni)
139512 +{
139513 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139514 +
139515 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
139516 + config_opts.dcpid = sp->dcp_idx;
139517 + config_opts.sp_mapping.map_lni_id = lni->idx;
139518 + sp->lni = lni;
139519 +
139520 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts))
139521 + return -EINVAL;
139522 +
139523 + /* Enable CEETM mode for this sub-portal */
139524 + return qman_sp_enable_ceetm_mode(sp->dcp_idx, sp->idx);
139525 +}
139526 +EXPORT_SYMBOL(qman_ceetm_sp_set_lni);
139527 +
139528 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp, unsigned int *lni_idx)
139529 +{
139530 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139531 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139532 +
139533 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
139534 + query_opts.dcpid = sp->dcp_idx;
139535 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
139536 + pr_err("Can't get SP <-> LNI mapping\n");
139537 + return -EINVAL;
139538 + }
139539 + *lni_idx = query_result.sp_mapping_query.map_lni_id;
139540 + sp->lni->idx = query_result.sp_mapping_query.map_lni_id;
139541 + return 0;
139542 +}
139543 +EXPORT_SYMBOL(qman_ceetm_sp_get_lni);
139544 +
139545 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
139546 + int oal)
139547 +{
139548 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139549 +
139550 + if (lni->shaper_enable) {
139551 + pr_err("The shaper has already been enabled\n");
139552 + return -EINVAL;
139553 + }
139554 + lni->shaper_enable = 1;
139555 + lni->shaper_couple = coupled;
139556 + lni->oal = oal;
139557 +
139558 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139559 + config_opts.dcpid = lni->dcp_idx;
139560 + config_opts.shaper_config.cpl = coupled;
139561 + config_opts.shaper_config.oal = oal;
139562 + config_opts.shaper_config.crtcr = cpu_to_be24((lni->cr_token_rate.whole
139563 + << 13) | lni->cr_token_rate.fraction);
139564 + config_opts.shaper_config.ertcr = cpu_to_be24((lni->er_token_rate.whole
139565 + << 13) | lni->er_token_rate.fraction);
139566 + config_opts.shaper_config.crtbl =
139567 + cpu_to_be16(lni->cr_token_bucket_limit);
139568 + config_opts.shaper_config.ertbl =
139569 + cpu_to_be16(lni->er_token_bucket_limit);
139570 + config_opts.shaper_config.mps = 60;
139571 +
139572 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139573 +}
139574 +EXPORT_SYMBOL(qman_ceetm_lni_enable_shaper);
139575 +
139576 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni)
139577 +{
139578 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139579 +
139580 + if (!lni->shaper_enable) {
139581 + pr_err("The shaper has been disabled\n");
139582 + return -EINVAL;
139583 + }
139584 +
139585 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139586 + config_opts.dcpid = lni->dcp_idx;
139587 + config_opts.shaper_config.cpl = lni->shaper_couple;
139588 + config_opts.shaper_config.oal = lni->oal;
139589 + config_opts.shaper_config.crtbl =
139590 + cpu_to_be16(lni->cr_token_bucket_limit);
139591 + config_opts.shaper_config.ertbl =
139592 + cpu_to_be16(lni->er_token_bucket_limit);
139593 + /* Set CR/ER rate with all 1's to configure an infinite rate, thus
139594 + * disable the shaping.
139595 + */
139596 + config_opts.shaper_config.crtcr = 0xFFFFFF;
139597 + config_opts.shaper_config.ertcr = 0xFFFFFF;
139598 + config_opts.shaper_config.mps = 60;
139599 + lni->shaper_enable = 0;
139600 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139601 +}
139602 +EXPORT_SYMBOL(qman_ceetm_lni_disable_shaper);
139603 +
139604 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni)
139605 +{
139606 + return lni->shaper_enable;
139607 +}
139608 +EXPORT_SYMBOL(qman_ceetm_lni_is_shaper_enabled);
139609 +
139610 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
139611 + const struct qm_ceetm_rate *token_rate,
139612 + u16 token_limit)
139613 +{
139614 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139615 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139616 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139617 + int ret;
139618 +
139619 + lni->cr_token_rate.whole = token_rate->whole;
139620 + lni->cr_token_rate.fraction = token_rate->fraction;
139621 + lni->cr_token_bucket_limit = token_limit;
139622 + if (!lni->shaper_enable)
139623 + return 0;
139624 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139625 + query_opts.dcpid = lni->dcp_idx;
139626 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
139627 + &query_result);
139628 + if (ret) {
139629 + pr_err("Fail to get current LNI shaper setting\n");
139630 + return -EINVAL;
139631 + }
139632 +
139633 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139634 + config_opts.dcpid = lni->dcp_idx;
139635 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole << 13)
139636 + | (token_rate->fraction));
139637 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
139638 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
139639 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
139640 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
139641 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
139642 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
139643 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139644 +}
139645 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate);
139646 +
139647 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
139648 + u64 bps,
139649 + u16 token_limit)
139650 +{
139651 + struct qm_ceetm_rate token_rate;
139652 + int ret;
139653 +
139654 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
139655 + if (ret) {
139656 + pr_err("Can not convert bps to token rate\n");
139657 + return -EINVAL;
139658 + }
139659 +
139660 + return qman_ceetm_lni_set_commit_rate(lni, &token_rate, token_limit);
139661 +}
139662 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate_bps);
139663 +
139664 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
139665 + struct qm_ceetm_rate *token_rate,
139666 + u16 *token_limit)
139667 +{
139668 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139669 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139670 + int ret;
139671 +
139672 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139673 + query_opts.dcpid = lni->dcp_idx;
139674 +
139675 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139676 + if (ret) {
139677 + pr_err("The LNI CR rate or limit is not set\n");
139678 + return -EINVAL;
139679 + }
139680 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
139681 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
139682 + 0x1FFF;
139683 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
139684 + return 0;
139685 +}
139686 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate);
139687 +
139688 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
139689 + u64 *bps, u16 *token_limit)
139690 +{
139691 + struct qm_ceetm_rate token_rate;
139692 + int ret;
139693 +
139694 + ret = qman_ceetm_lni_get_commit_rate(lni, &token_rate, token_limit);
139695 + if (ret) {
139696 + pr_err("The LNI CR rate or limit is not available\n");
139697 + return -EINVAL;
139698 + }
139699 +
139700 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
139701 +}
139702 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate_bps);
139703 +
139704 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
139705 + const struct qm_ceetm_rate *token_rate,
139706 + u16 token_limit)
139707 +{
139708 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139709 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139710 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139711 + int ret;
139712 +
139713 + lni->er_token_rate.whole = token_rate->whole;
139714 + lni->er_token_rate.fraction = token_rate->fraction;
139715 + lni->er_token_bucket_limit = token_limit;
139716 + if (!lni->shaper_enable)
139717 + return 0;
139718 +
139719 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139720 + query_opts.dcpid = lni->dcp_idx;
139721 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
139722 + &query_result);
139723 + if (ret) {
139724 + pr_err("Fail to get current LNI shaper setting\n");
139725 + return -EINVAL;
139726 + }
139727 +
139728 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139729 + config_opts.dcpid = lni->dcp_idx;
139730 + config_opts.shaper_config.ertcr = cpu_to_be24(
139731 + (token_rate->whole << 13) | (token_rate->fraction));
139732 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
139733 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
139734 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
139735 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
139736 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
139737 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
139738 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139739 +}
139740 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate);
139741 +
139742 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
139743 + u64 bps,
139744 + u16 token_limit)
139745 +{
139746 + struct qm_ceetm_rate token_rate;
139747 + int ret;
139748 +
139749 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
139750 + if (ret) {
139751 + pr_err("Can not convert bps to token rate\n");
139752 + return -EINVAL;
139753 + }
139754 + return qman_ceetm_lni_set_excess_rate(lni, &token_rate, token_limit);
139755 +}
139756 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate_bps);
139757 +
139758 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
139759 + struct qm_ceetm_rate *token_rate,
139760 + u16 *token_limit)
139761 +{
139762 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139763 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139764 + int ret;
139765 +
139766 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139767 + query_opts.dcpid = lni->dcp_idx;
139768 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139769 + if (ret) {
139770 + pr_err("The LNI ER rate or limit is not set\n");
139771 + return -EINVAL;
139772 + }
139773 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
139774 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
139775 + 0x1FFF;
139776 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
139777 + return 0;
139778 +}
139779 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate);
139780 +
139781 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
139782 + u64 *bps, u16 *token_limit)
139783 +{
139784 + struct qm_ceetm_rate token_rate;
139785 + int ret;
139786 +
139787 + ret = qman_ceetm_lni_get_excess_rate(lni, &token_rate, token_limit);
139788 + if (ret) {
139789 + pr_err("The LNI ER rate or limit is not available\n");
139790 + return -EINVAL;
139791 + }
139792 +
139793 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
139794 +}
139795 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate_bps);
139796 +
139797 +#define QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(n) ((15 - n) * 4)
139798 +#define QMAN_CEETM_LNITCFCC_ENABLE 0x8
139799 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
139800 + unsigned int cq_level,
139801 + int traffic_class)
139802 +{
139803 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139804 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139805 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139806 + u64 lnitcfcc;
139807 +
139808 + if ((cq_level > 15) | (traffic_class > 7)) {
139809 + pr_err("The CQ or traffic class id is out of range\n");
139810 + return -EINVAL;
139811 + }
139812 +
139813 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
139814 + query_opts.dcpid = lni->dcp_idx;
139815 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
139816 + pr_err("Fail to query tcfcc\n");
139817 + return -EINVAL;
139818 + }
139819 +
139820 + lnitcfcc = be64_to_cpu(query_result.tcfc_query.lnitcfcc);
139821 + if (traffic_class == -1) {
139822 + /* disable tcfc for this CQ */
139823 + lnitcfcc &= ~((u64)QMAN_CEETM_LNITCFCC_ENABLE <<
139824 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
139825 + } else {
139826 + lnitcfcc &= ~((u64)0xF <<
139827 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
139828 + lnitcfcc |= ((u64)(QMAN_CEETM_LNITCFCC_ENABLE |
139829 + traffic_class)) <<
139830 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level);
139831 + }
139832 + config_opts.tcfc_config.lnitcfcc = cpu_to_be64(lnitcfcc);
139833 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
139834 + config_opts.dcpid = lni->dcp_idx;
139835 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139836 +}
139837 +EXPORT_SYMBOL(qman_ceetm_lni_set_tcfcc);
139838 +
139839 +#define QMAN_CEETM_LNITCFCC_TC_MASK 0x7
139840 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni, unsigned int cq_level,
139841 + int *traffic_class)
139842 +{
139843 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139844 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139845 + int ret;
139846 + u8 lnitcfcc;
139847 +
139848 + if (cq_level > 15) {
139849 + pr_err("the CQ level is out of range\n");
139850 + return -EINVAL;
139851 + }
139852 +
139853 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
139854 + query_opts.dcpid = lni->dcp_idx;
139855 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139856 + if (ret)
139857 + return ret;
139858 + lnitcfcc = (u8)be64_to_cpu((query_result.tcfc_query.lnitcfcc) >>
139859 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
139860 + if (lnitcfcc & QMAN_CEETM_LNITCFCC_ENABLE)
139861 + *traffic_class = lnitcfcc & QMAN_CEETM_LNITCFCC_TC_MASK;
139862 + else
139863 + *traffic_class = -1;
139864 + return 0;
139865 +}
139866 +EXPORT_SYMBOL(qman_ceetm_lni_get_tcfcc);
139867 +
139868 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
139869 + struct qm_ceetm_lni *lni)
139870 +{
139871 + struct qm_ceetm_channel *p;
139872 + u32 channel_idx;
139873 + int ret = 0;
139874 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139875 +
139876 + if (lni->dcp_idx == qm_dc_portal_fman0) {
139877 + ret = qman_alloc_ceetm0_channel(&channel_idx);
139878 + } else if (lni->dcp_idx == qm_dc_portal_fman1) {
139879 + ret = qman_alloc_ceetm1_channel(&channel_idx);
139880 + } else {
139881 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
139882 + lni->dcp_idx);
139883 + return -EINVAL;
139884 + }
139885 +
139886 + if (ret) {
139887 + pr_err("The is no channel available for LNI#%d\n", lni->idx);
139888 + return -ENODEV;
139889 + }
139890 +
139891 + p = kzalloc(sizeof(*p), GFP_KERNEL);
139892 + if (!p)
139893 + return -ENOMEM;
139894 + p->idx = channel_idx;
139895 + p->dcp_idx = lni->dcp_idx;
139896 + p->lni_idx = lni->idx;
139897 + list_add_tail(&p->node, &lni->channels);
139898 + INIT_LIST_HEAD(&p->class_queues);
139899 + INIT_LIST_HEAD(&p->ccgs);
139900 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
139901 + channel_idx);
139902 + config_opts.dcpid = lni->dcp_idx;
139903 + config_opts.channel_mapping.map_lni_id = lni->idx;
139904 + config_opts.channel_mapping.map_shaped = 0;
139905 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
139906 + pr_err("Can't map channel#%d for LNI#%d\n",
139907 + channel_idx, lni->idx);
139908 + return -EINVAL;
139909 + }
139910 + *channel = p;
139911 + return 0;
139912 +}
139913 +EXPORT_SYMBOL(qman_ceetm_channel_claim);
139914 +
139915 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel)
139916 +{
139917 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139918 + if (!list_empty(&channel->class_queues)) {
139919 + pr_err("CEETM channel#%d has class queue unreleased!\n",
139920 + channel->idx);
139921 + return -EBUSY;
139922 + }
139923 + if (!list_empty(&channel->ccgs)) {
139924 + pr_err("CEETM channel#%d has ccg unreleased!\n",
139925 + channel->idx);
139926 + return -EBUSY;
139927 + }
139928 +
139929 + /* channel->dcp_idx corresponds to known fman validation */
139930 + if ((channel->dcp_idx != qm_dc_portal_fman0) &&
139931 + (channel->dcp_idx != qm_dc_portal_fman1)) {
139932 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
139933 + channel->dcp_idx);
139934 + return -EINVAL;
139935 + }
139936 +
139937 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
139938 + channel->idx);
139939 + config_opts.dcpid = channel->dcp_idx;
139940 + memset(&config_opts.shaper_config, 0,
139941 + sizeof(config_opts.shaper_config));
139942 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
139943 + pr_err("Can't reset channel shapping parameters\n");
139944 + return -EINVAL;
139945 + }
139946 +
139947 + if (channel->dcp_idx == qm_dc_portal_fman0) {
139948 + qman_release_ceetm0_channelid(channel->idx);
139949 + } else if (channel->dcp_idx == qm_dc_portal_fman1) {
139950 + qman_release_ceetm1_channelid(channel->idx);
139951 + } else {
139952 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
139953 + channel->dcp_idx);
139954 + return -EINVAL;
139955 + }
139956 + list_del(&channel->node);
139957 + kfree(channel);
139958 +
139959 + return 0;
139960 +}
139961 +EXPORT_SYMBOL(qman_ceetm_channel_release);
139962 +
139963 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
139964 + int coupled)
139965 +{
139966 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139967 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139968 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139969 +
139970 + if (channel->shaper_enable == 1) {
139971 + pr_err("This channel shaper has been enabled!\n");
139972 + return -EINVAL;
139973 + }
139974 +
139975 + channel->shaper_enable = 1;
139976 + channel->shaper_couple = coupled;
139977 +
139978 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
139979 + channel->idx);
139980 + query_opts.dcpid = channel->dcp_idx;
139981 +
139982 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
139983 + pr_err("Can't query channel mapping\n");
139984 + return -EINVAL;
139985 + }
139986 +
139987 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
139988 + channel->idx);
139989 + config_opts.dcpid = channel->dcp_idx;
139990 + config_opts.channel_mapping.map_lni_id =
139991 + query_result.channel_mapping_query.map_lni_id;
139992 + config_opts.channel_mapping.map_shaped = 1;
139993 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
139994 + pr_err("Can't enable shaper for channel #%d\n", channel->idx);
139995 + return -EINVAL;
139996 + }
139997 +
139998 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
139999 + channel->idx);
140000 + config_opts.shaper_config.cpl = coupled;
140001 + config_opts.shaper_config.crtcr =
140002 + cpu_to_be24((channel->cr_token_rate.whole
140003 + << 13) |
140004 + channel->cr_token_rate.fraction);
140005 + config_opts.shaper_config.ertcr =
140006 + cpu_to_be24(channel->er_token_rate.whole
140007 + << 13 |
140008 + channel->er_token_rate.fraction);
140009 + config_opts.shaper_config.crtbl =
140010 + cpu_to_be16(channel->cr_token_bucket_limit);
140011 + config_opts.shaper_config.ertbl =
140012 + cpu_to_be16(channel->er_token_bucket_limit);
140013 +
140014 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140015 +}
140016 +EXPORT_SYMBOL(qman_ceetm_channel_enable_shaper);
140017 +
140018 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel)
140019 +{
140020 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140021 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140022 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140023 +
140024 +
140025 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140026 + channel->idx);
140027 + query_opts.dcpid = channel->dcp_idx;
140028 +
140029 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140030 + pr_err("Can't query channel mapping\n");
140031 + return -EINVAL;
140032 + }
140033 +
140034 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140035 + channel->idx);
140036 + config_opts.dcpid = channel->dcp_idx;
140037 + config_opts.channel_mapping.map_shaped = 0;
140038 + config_opts.channel_mapping.map_lni_id =
140039 + query_result.channel_mapping_query.map_lni_id;
140040 +
140041 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140042 +}
140043 +EXPORT_SYMBOL(qman_ceetm_channel_disable_shaper);
140044 +
140045 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel)
140046 +{
140047 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140048 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140049 +
140050 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140051 + channel->idx);
140052 + query_opts.dcpid = channel->dcp_idx;
140053 +
140054 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140055 + pr_err("Can't query channel mapping\n");
140056 + return -EINVAL;
140057 + }
140058 +
140059 + return query_result.channel_mapping_query.map_shaped;
140060 +}
140061 +EXPORT_SYMBOL(qman_ceetm_channel_is_shaper_enabled);
140062 +
140063 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
140064 + const struct qm_ceetm_rate *token_rate,
140065 + u16 token_limit)
140066 +{
140067 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140068 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140069 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140070 + int ret;
140071 +
140072 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140073 + channel->idx);
140074 + query_opts.dcpid = channel->dcp_idx;
140075 +
140076 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140077 + if (ret) {
140078 + pr_err("Fail to get the current channel shaper setting\n");
140079 + return -EINVAL;
140080 + }
140081 +
140082 + channel->cr_token_rate.whole = token_rate->whole;
140083 + channel->cr_token_rate.fraction = token_rate->fraction;
140084 + channel->cr_token_bucket_limit = token_limit;
140085 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140086 + channel->idx);
140087 + config_opts.dcpid = channel->dcp_idx;
140088 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole
140089 + << 13) | (token_rate->fraction));
140090 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140091 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140092 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
140093 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
140094 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140095 +}
140096 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate);
140097 +
140098 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
140099 + u64 bps, u16 token_limit)
140100 +{
140101 + struct qm_ceetm_rate token_rate;
140102 + int ret;
140103 +
140104 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140105 + if (ret) {
140106 + pr_err("Can not convert bps to token rate\n");
140107 + return -EINVAL;
140108 + }
140109 + return qman_ceetm_channel_set_commit_rate(channel, &token_rate,
140110 + token_limit);
140111 +}
140112 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate_bps);
140113 +
140114 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
140115 + struct qm_ceetm_rate *token_rate,
140116 + u16 *token_limit)
140117 +{
140118 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140119 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140120 + int ret;
140121 +
140122 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140123 + channel->idx);
140124 + query_opts.dcpid = channel->dcp_idx;
140125 +
140126 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140127 + if (ret | !query_result.shaper_query.crtcr |
140128 + !query_result.shaper_query.crtbl) {
140129 + pr_err("The channel commit rate or limit is not set\n");
140130 + return -EINVAL;
140131 + }
140132 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
140133 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
140134 + 0x1FFF;
140135 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140136 + return 0;
140137 +}
140138 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate);
140139 +
140140 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
140141 + u64 *bps, u16 *token_limit)
140142 +{
140143 + struct qm_ceetm_rate token_rate;
140144 + int ret;
140145 +
140146 + ret = qman_ceetm_channel_get_commit_rate(channel, &token_rate,
140147 + token_limit);
140148 + if (ret) {
140149 + pr_err("The channel CR rate or limit is not available\n");
140150 + return -EINVAL;
140151 + }
140152 +
140153 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140154 +}
140155 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate_bps);
140156 +
140157 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
140158 + const struct qm_ceetm_rate *token_rate,
140159 + u16 token_limit)
140160 +{
140161 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140162 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140163 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140164 + int ret;
140165 +
140166 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140167 + channel->idx);
140168 + query_opts.dcpid = channel->dcp_idx;
140169 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140170 + if (ret) {
140171 + pr_err("Fail to get the current channel shaper setting\n");
140172 + return -EINVAL;
140173 + }
140174 +
140175 + channel->er_token_rate.whole = token_rate->whole;
140176 + channel->er_token_rate.fraction = token_rate->fraction;
140177 + channel->er_token_bucket_limit = token_limit;
140178 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140179 + channel->idx);
140180 + config_opts.dcpid = channel->dcp_idx;
140181 + config_opts.shaper_config.ertcr = cpu_to_be24(
140182 + (token_rate->whole << 13) | (token_rate->fraction));
140183 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
140184 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140185 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
140186 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
140187 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140188 +}
140189 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate);
140190 +
140191 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
140192 + u64 bps, u16 token_limit)
140193 +{
140194 + struct qm_ceetm_rate token_rate;
140195 + int ret;
140196 +
140197 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140198 + if (ret) {
140199 + pr_err("Can not convert bps to token rate\n");
140200 + return -EINVAL;
140201 + }
140202 + return qman_ceetm_channel_set_excess_rate(channel, &token_rate,
140203 + token_limit);
140204 +}
140205 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate_bps);
140206 +
140207 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
140208 + struct qm_ceetm_rate *token_rate,
140209 + u16 *token_limit)
140210 +{
140211 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140212 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140213 + int ret;
140214 +
140215 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140216 + channel->idx);
140217 + query_opts.dcpid = channel->dcp_idx;
140218 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140219 + if (ret | !query_result.shaper_query.ertcr |
140220 + !query_result.shaper_query.ertbl) {
140221 + pr_err("The channel excess rate or limit is not set\n");
140222 + return -EINVAL;
140223 + }
140224 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
140225 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
140226 + 0x1FFF;
140227 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
140228 + return 0;
140229 +}
140230 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate);
140231 +
140232 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
140233 + u64 *bps, u16 *token_limit)
140234 +{
140235 + struct qm_ceetm_rate token_rate;
140236 + int ret;
140237 +
140238 + ret = qman_ceetm_channel_get_excess_rate(channel, &token_rate,
140239 + token_limit);
140240 + if (ret) {
140241 + pr_err("The channel ER rate or limit is not available\n");
140242 + return -EINVAL;
140243 + }
140244 +
140245 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140246 +}
140247 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate_bps);
140248 +
140249 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
140250 + u16 token_limit)
140251 +{
140252 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140253 +
140254 + if (channel->shaper_enable) {
140255 + pr_err("This channel is a shaped one\n");
140256 + return -EINVAL;
140257 + }
140258 +
140259 + channel->cr_token_bucket_limit = token_limit;
140260 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140261 + channel->idx);
140262 + config_opts.dcpid = channel->dcp_idx;
140263 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140264 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140265 +}
140266 +EXPORT_SYMBOL(qman_ceetm_channel_set_weight);
140267 +
140268 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
140269 + u16 *token_limit)
140270 +{
140271 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140272 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140273 + int ret;
140274 +
140275 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140276 + channel->idx);
140277 + query_opts.dcpid = channel->dcp_idx;
140278 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140279 + if (ret | !query_result.shaper_query.crtbl) {
140280 + pr_err("This unshaped channel's uFQ wight is unavailable\n");
140281 + return -EINVAL;
140282 + }
140283 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140284 + return 0;
140285 +}
140286 +EXPORT_SYMBOL(qman_ceetm_channel_get_weight);
140287 +
140288 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel, int group_b,
140289 + unsigned int prio_a, unsigned int prio_b)
140290 +{
140291 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
140292 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140293 + int i;
140294 +
140295 + if (prio_a > 7) {
140296 + pr_err("The priority of group A is out of range\n");
140297 + return -EINVAL;
140298 + }
140299 + if (group_b && (prio_b > 7)) {
140300 + pr_err("The priority of group B is out of range\n");
140301 + return -EINVAL;
140302 + }
140303 +
140304 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
140305 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
140306 + return -EINVAL;
140307 + }
140308 +
140309 + config_opts.cqcid = cpu_to_be16(channel->idx);
140310 + config_opts.dcpid = channel->dcp_idx;
140311 + config_opts.gpc_combine_flag = !group_b;
140312 + config_opts.gpc_prio_a = prio_a;
140313 + config_opts.gpc_prio_b = prio_b;
140314 +
140315 + for (i = 0; i < 8; i++)
140316 + config_opts.w[i] = query_result.w[i];
140317 + config_opts.crem = query_result.crem;
140318 + config_opts.erem = query_result.erem;
140319 +
140320 + return qman_ceetm_configure_class_scheduler(&config_opts);
140321 +}
140322 +EXPORT_SYMBOL(qman_ceetm_channel_set_group);
140323 +
140324 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, int *group_b,
140325 + unsigned int *prio_a, unsigned int *prio_b)
140326 +{
140327 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140328 +
140329 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
140330 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
140331 + return -EINVAL;
140332 + }
140333 + *group_b = !query_result.gpc_combine_flag;
140334 + *prio_a = query_result.gpc_prio_a;
140335 + *prio_b = query_result.gpc_prio_b;
140336 +
140337 + return 0;
140338 +}
140339 +EXPORT_SYMBOL(qman_ceetm_channel_get_group);
140340 +
140341 +#define GROUP_A_ELIGIBILITY_SET (1 << 8)
140342 +#define GROUP_B_ELIGIBILITY_SET (1 << 9)
140343 +#define CQ_ELIGIBILITY_SET(n) (1 << (7 - n))
140344 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
140345 + *channel, int group_b, int cre)
140346 +{
140347 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140348 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140349 + int i;
140350 +
140351 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140352 + pr_err("Cannot get the channel %d scheduler setting.\n",
140353 + channel->idx);
140354 + return -EINVAL;
140355 + }
140356 + csch_config.cqcid = cpu_to_be16(channel->idx);
140357 + csch_config.dcpid = channel->dcp_idx;
140358 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140359 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140360 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140361 +
140362 + for (i = 0; i < 8; i++)
140363 + csch_config.w[i] = csch_query.w[i];
140364 + csch_config.erem = csch_query.erem;
140365 + if (group_b)
140366 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140367 + & ~GROUP_B_ELIGIBILITY_SET)
140368 + | (cre ? GROUP_B_ELIGIBILITY_SET : 0);
140369 + else
140370 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140371 + & ~GROUP_A_ELIGIBILITY_SET)
140372 + | (cre ? GROUP_A_ELIGIBILITY_SET : 0);
140373 +
140374 + csch_config.crem = cpu_to_be16(csch_config.crem);
140375 +
140376 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140377 + pr_err("Cannot config channel %d's scheduler with "
140378 + "group_%c's cr eligibility\n", channel->idx,
140379 + group_b ? 'b' : 'a');
140380 + return -EINVAL;
140381 + }
140382 +
140383 + return 0;
140384 +}
140385 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_cr_eligibility);
140386 +
140387 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
140388 + *channel, int group_b, int ere)
140389 +{
140390 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140391 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140392 + int i;
140393 +
140394 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140395 + pr_err("Cannot get the channel %d scheduler setting.\n",
140396 + channel->idx);
140397 + return -EINVAL;
140398 + }
140399 + csch_config.cqcid = cpu_to_be16(channel->idx);
140400 + csch_config.dcpid = channel->dcp_idx;
140401 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140402 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140403 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140404 +
140405 + for (i = 0; i < 8; i++)
140406 + csch_config.w[i] = csch_query.w[i];
140407 + csch_config.crem = csch_query.crem;
140408 + if (group_b)
140409 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140410 + & ~GROUP_B_ELIGIBILITY_SET)
140411 + | (ere ? GROUP_B_ELIGIBILITY_SET : 0);
140412 + else
140413 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140414 + & ~GROUP_A_ELIGIBILITY_SET)
140415 + | (ere ? GROUP_A_ELIGIBILITY_SET : 0);
140416 +
140417 + csch_config.erem = cpu_to_be16(csch_config.erem);
140418 +
140419 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140420 + pr_err("Cannot config channel %d's scheduler with "
140421 + "group_%c's er eligibility\n", channel->idx,
140422 + group_b ? 'b' : 'a');
140423 + return -EINVAL;
140424 + }
140425 +
140426 + return 0;
140427 +}
140428 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_er_eligibility);
140429 +
140430 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
140431 + unsigned int idx, int cre)
140432 +{
140433 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140434 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140435 + int i;
140436 +
140437 + if (idx > 7) {
140438 + pr_err("CQ index is out of range\n");
140439 + return -EINVAL;
140440 + }
140441 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140442 + pr_err("Cannot get the channel %d scheduler setting.\n",
140443 + channel->idx);
140444 + return -EINVAL;
140445 + }
140446 + csch_config.cqcid = cpu_to_be16(channel->idx);
140447 + csch_config.dcpid = channel->dcp_idx;
140448 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140449 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140450 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140451 + for (i = 0; i < 8; i++)
140452 + csch_config.w[i] = csch_query.w[i];
140453 + csch_config.erem = csch_query.erem;
140454 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140455 + & ~CQ_ELIGIBILITY_SET(idx)) |
140456 + (cre ? CQ_ELIGIBILITY_SET(idx) : 0);
140457 + csch_config.crem = cpu_to_be16(csch_config.crem);
140458 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140459 + pr_err("Cannot config channel scheduler to set "
140460 + "cr eligibility mask for CQ#%d\n", idx);
140461 + return -EINVAL;
140462 + }
140463 +
140464 + return 0;
140465 +}
140466 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_cr_eligibility);
140467 +
140468 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
140469 + unsigned int idx, int ere)
140470 +{
140471 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140472 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140473 + int i;
140474 +
140475 + if (idx > 7) {
140476 + pr_err("CQ index is out of range\n");
140477 + return -EINVAL;
140478 + }
140479 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140480 + pr_err("Cannot get the channel %d scheduler setting.\n",
140481 + channel->idx);
140482 + return -EINVAL;
140483 + }
140484 + csch_config.cqcid = cpu_to_be16(channel->idx);
140485 + csch_config.dcpid = channel->dcp_idx;
140486 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140487 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140488 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140489 + for (i = 0; i < 8; i++)
140490 + csch_config.w[i] = csch_query.w[i];
140491 + csch_config.crem = csch_query.crem;
140492 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140493 + & ~CQ_ELIGIBILITY_SET(idx)) |
140494 + (ere ? CQ_ELIGIBILITY_SET(idx) : 0);
140495 + csch_config.erem = cpu_to_be16(csch_config.erem);
140496 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140497 + pr_err("Cannot config channel scheduler to set "
140498 + "er eligibility mask for CQ#%d\n", idx);
140499 + return -EINVAL;
140500 + }
140501 + return 0;
140502 +}
140503 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_er_eligibility);
140504 +
140505 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
140506 + struct qm_ceetm_channel *channel, unsigned int idx,
140507 + struct qm_ceetm_ccg *ccg)
140508 +{
140509 + struct qm_ceetm_cq *p;
140510 + struct qm_mcc_ceetm_cq_config cq_config;
140511 +
140512 + if (idx > 7) {
140513 + pr_err("The independent class queue id is out of range\n");
140514 + return -EINVAL;
140515 + }
140516 +
140517 + list_for_each_entry(p, &channel->class_queues, node) {
140518 + if (p->idx == idx) {
140519 + pr_err("The CQ#%d has been claimed!\n", idx);
140520 + return -EINVAL;
140521 + }
140522 + }
140523 +
140524 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140525 + if (!p) {
140526 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140527 + return -ENOMEM;
140528 + }
140529 +
140530 + list_add_tail(&p->node, &channel->class_queues);
140531 + p->idx = idx;
140532 + p->is_claimed = 1;
140533 + p->parent = channel;
140534 + INIT_LIST_HEAD(&p->bound_lfqids);
140535 +
140536 + if (ccg) {
140537 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140538 + cq_config.dcpid = channel->dcp_idx;
140539 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140540 + if (qman_ceetm_configure_cq(&cq_config)) {
140541 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140542 + idx, ccg->idx);
140543 + list_del(&p->node);
140544 + kfree(p);
140545 + return -EINVAL;
140546 + }
140547 + }
140548 +
140549 + *cq = p;
140550 + return 0;
140551 +}
140552 +EXPORT_SYMBOL(qman_ceetm_cq_claim);
140553 +
140554 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
140555 + struct qm_ceetm_channel *channel, unsigned int idx,
140556 + struct qm_ceetm_ccg *ccg)
140557 +{
140558 + struct qm_ceetm_cq *p;
140559 + struct qm_mcc_ceetm_cq_config cq_config;
140560 +
140561 + if ((idx < 8) || (idx > 15)) {
140562 + pr_err("This grouped class queue id is out of range\n");
140563 + return -EINVAL;
140564 + }
140565 +
140566 + list_for_each_entry(p, &channel->class_queues, node) {
140567 + if (p->idx == idx) {
140568 + pr_err("The CQ#%d has been claimed!\n", idx);
140569 + return -EINVAL;
140570 + }
140571 + }
140572 +
140573 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140574 + if (!p) {
140575 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140576 + return -ENOMEM;
140577 + }
140578 +
140579 + list_add_tail(&p->node, &channel->class_queues);
140580 + p->idx = idx;
140581 + p->is_claimed = 1;
140582 + p->parent = channel;
140583 + INIT_LIST_HEAD(&p->bound_lfqids);
140584 +
140585 + if (ccg) {
140586 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140587 + cq_config.dcpid = channel->dcp_idx;
140588 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140589 + if (qman_ceetm_configure_cq(&cq_config)) {
140590 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140591 + idx, ccg->idx);
140592 + list_del(&p->node);
140593 + kfree(p);
140594 + return -EINVAL;
140595 + }
140596 + }
140597 + *cq = p;
140598 + return 0;
140599 +}
140600 +EXPORT_SYMBOL(qman_ceetm_cq_claim_A);
140601 +
140602 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
140603 + struct qm_ceetm_channel *channel, unsigned int idx,
140604 + struct qm_ceetm_ccg *ccg)
140605 +{
140606 + struct qm_ceetm_cq *p;
140607 + struct qm_mcc_ceetm_cq_config cq_config;
140608 +
140609 + if ((idx < 12) || (idx > 15)) {
140610 + pr_err("This grouped class queue id is out of range\n");
140611 + return -EINVAL;
140612 + }
140613 +
140614 + list_for_each_entry(p, &channel->class_queues, node) {
140615 + if (p->idx == idx) {
140616 + pr_err("The CQ#%d has been claimed!\n", idx);
140617 + return -EINVAL;
140618 + }
140619 + }
140620 +
140621 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140622 + if (!p) {
140623 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140624 + return -ENOMEM;
140625 + }
140626 +
140627 + list_add_tail(&p->node, &channel->class_queues);
140628 + p->idx = idx;
140629 + p->is_claimed = 1;
140630 + p->parent = channel;
140631 + INIT_LIST_HEAD(&p->bound_lfqids);
140632 +
140633 + if (ccg) {
140634 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140635 + cq_config.dcpid = channel->dcp_idx;
140636 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140637 + if (qman_ceetm_configure_cq(&cq_config)) {
140638 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140639 + idx, ccg->idx);
140640 + list_del(&p->node);
140641 + kfree(p);
140642 + return -EINVAL;
140643 + }
140644 + }
140645 + *cq = p;
140646 + return 0;
140647 +}
140648 +EXPORT_SYMBOL(qman_ceetm_cq_claim_B);
140649 +
140650 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq)
140651 +{
140652 + if (!list_empty(&cq->bound_lfqids)) {
140653 + pr_err("The CQ#%d has unreleased LFQID\n", cq->idx);
140654 + return -EBUSY;
140655 + }
140656 + list_del(&cq->node);
140657 + qman_ceetm_drain_cq(cq);
140658 + kfree(cq);
140659 + return 0;
140660 +}
140661 +EXPORT_SYMBOL(qman_ceetm_cq_release);
140662 +
140663 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
140664 + struct qm_ceetm_weight_code *weight_code)
140665 +{
140666 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
140667 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140668 + int i;
140669 +
140670 + if (cq->idx < 8) {
140671 + pr_err("Can not set weight for ungrouped class queue\n");
140672 + return -EINVAL;
140673 + }
140674 +
140675 + if (qman_ceetm_query_class_scheduler(cq->parent, &query_result)) {
140676 + pr_err("Can't query channel#%d's scheduler!\n",
140677 + cq->parent->idx);
140678 + return -EINVAL;
140679 + }
140680 +
140681 + config_opts.cqcid = cpu_to_be16(cq->parent->idx);
140682 + config_opts.dcpid = cq->parent->dcp_idx;
140683 + config_opts.crem = query_result.crem;
140684 + config_opts.erem = query_result.erem;
140685 + config_opts.gpc_combine_flag = query_result.gpc_combine_flag;
140686 + config_opts.gpc_prio_a = query_result.gpc_prio_a;
140687 + config_opts.gpc_prio_b = query_result.gpc_prio_b;
140688 +
140689 + for (i = 0; i < 8; i++)
140690 + config_opts.w[i] = query_result.w[i];
140691 + config_opts.w[cq->idx - 8] = ((weight_code->y << 3) |
140692 + (weight_code->x & 0x7));
140693 + return qman_ceetm_configure_class_scheduler(&config_opts);
140694 +}
140695 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight);
140696 +
140697 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
140698 + struct qm_ceetm_weight_code *weight_code)
140699 +{
140700 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140701 +
140702 + if (cq->idx < 8) {
140703 + pr_err("Can not get weight for ungrouped class queue\n");
140704 + return -EINVAL;
140705 + }
140706 +
140707 + if (qman_ceetm_query_class_scheduler(cq->parent,
140708 + &query_result)) {
140709 + pr_err("Can't get the weight code for CQ#%d!\n", cq->idx);
140710 + return -EINVAL;
140711 + }
140712 + weight_code->y = query_result.w[cq->idx - 8] >> 3;
140713 + weight_code->x = query_result.w[cq->idx - 8] & 0x7;
140714 +
140715 + return 0;
140716 +}
140717 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight);
140718 +
140719 +/* The WBFS code is represent as {x,y}, the effect wieght can be calculated as:
140720 + * effective weight = 2^x / (1 - (y/64))
140721 + * = 2^(x+6) / (64 - y)
140722 + */
140723 +static void reduce_fraction(u32 *n, u32 *d)
140724 +{
140725 + u32 factor = 2;
140726 + u32 lesser = (*n < *d) ? *n : *d;
140727 + /* If factor exceeds the square-root of the lesser of *n and *d,
140728 + * then there's no point continuing. Proof: if there was a factor
140729 + * bigger than the square root, that would imply there exists
140730 + * another factor smaller than the square-root with which it
140731 + * multiplies to give 'lesser' - but that's a contradiction
140732 + * because the other factor would have already been found and
140733 + * divided out.
140734 + */
140735 + while ((factor * factor) <= lesser) {
140736 + /* If 'factor' is a factor of *n and *d, divide them both
140737 + * by 'factor' as many times as possible.
140738 + */
140739 + while (!(*n % factor) && !(*d % factor)) {
140740 + *n /= factor;
140741 + *d /= factor;
140742 + lesser /= factor;
140743 + }
140744 + if (factor == 2)
140745 + factor = 3;
140746 + else
140747 + factor += 2;
140748 + }
140749 +}
140750 +
140751 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
140752 + u32 *numerator,
140753 + u32 *denominator)
140754 +{
140755 + *numerator = (u32) 1 << (weight_code->x + 6);
140756 + *denominator = 64 - weight_code->y;
140757 + reduce_fraction(numerator, denominator);
140758 + return 0;
140759 +}
140760 +EXPORT_SYMBOL(qman_ceetm_wbfs2ratio);
140761 +
140762 +/* For a given x, the weight is between 2^x (inclusive) and 2^(x+1) (exclusive).
140763 + * So find 'x' by range, and then estimate 'y' using:
140764 + * 64 - y = 2^(x + 6) / weight
140765 + * = 2^(x + 6) / (n/d)
140766 + * = d * 2^(x+6) / n
140767 + * y = 64 - (d * 2^(x+6) / n)
140768 + */
140769 +int qman_ceetm_ratio2wbfs(u32 numerator,
140770 + u32 denominator,
140771 + struct qm_ceetm_weight_code *weight_code,
140772 + int rounding)
140773 +{
140774 + unsigned int y, x = 0;
140775 + /* search incrementing 'x' until:
140776 + * weight < 2^(x+1)
140777 + * n/d < 2^(x+1)
140778 + * n < d * 2^(x+1)
140779 + */
140780 + while ((x < 8) && (numerator >= (denominator << (x + 1))))
140781 + x++;
140782 + if (x >= 8)
140783 + return -ERANGE;
140784 + /* because of the subtraction, use '-rounding' */
140785 + y = 64 - ROUNDING(denominator << (x + 6), numerator, -rounding);
140786 + if (y >= 32)
140787 + return -ERANGE;
140788 + weight_code->x = x;
140789 + weight_code->y = y;
140790 + return 0;
140791 +}
140792 +EXPORT_SYMBOL(qman_ceetm_ratio2wbfs);
140793 +
140794 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio)
140795 +{
140796 + struct qm_ceetm_weight_code weight_code;
140797 +
140798 + if (qman_ceetm_ratio2wbfs(ratio, 100, &weight_code, 0)) {
140799 + pr_err("Cannot get wbfs code for cq %x\n", cq->idx);
140800 + return -EINVAL;
140801 + }
140802 + return qman_ceetm_set_queue_weight(cq, &weight_code);
140803 +}
140804 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight_in_ratio);
140805 +
140806 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio)
140807 +{
140808 + struct qm_ceetm_weight_code weight_code;
140809 + u32 n, d;
140810 +
140811 + if (qman_ceetm_get_queue_weight(cq, &weight_code)) {
140812 + pr_err("Cannot query the weight code for cq%x\n", cq->idx);
140813 + return -EINVAL;
140814 + }
140815 +
140816 + if (qman_ceetm_wbfs2ratio(&weight_code, &n, &d)) {
140817 + pr_err("Cannot get the ratio with wbfs code\n");
140818 + return -EINVAL;
140819 + }
140820 +
140821 + *ratio = (n * 100) / d;
140822 + return 0;
140823 +}
140824 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight_in_ratio);
140825 +
140826 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
140827 + u64 *frame_count, u64 *byte_count)
140828 +{
140829 + struct qm_mcr_ceetm_statistics_query result;
140830 + u16 cid, command_type;
140831 + enum qm_dc_portal dcp_idx;
140832 + int ret;
140833 +
140834 + cid = cpu_to_be16((cq->parent->idx << 4) | cq->idx);
140835 + dcp_idx = cq->parent->dcp_idx;
140836 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
140837 + command_type = CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS;
140838 + else
140839 + command_type = CEETM_QUERY_DEQUEUE_STATISTICS;
140840 +
140841 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
140842 + if (ret) {
140843 + pr_err("Can't query the statistics of CQ#%d!\n", cq->idx);
140844 + return -EINVAL;
140845 + }
140846 +
140847 + *frame_count = be40_to_cpu(result.frm_cnt);
140848 + *byte_count = be48_to_cpu(result.byte_cnt);
140849 + return 0;
140850 +}
140851 +EXPORT_SYMBOL(qman_ceetm_cq_get_dequeue_statistics);
140852 +
140853 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq)
140854 +{
140855 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread ppxr;
140856 + int ret;
140857 +
140858 + do {
140859 + ret = qman_ceetm_cq_peek_pop_xsfdrread(cq, 1, 0, &ppxr);
140860 + if (ret) {
140861 + pr_err("Failed to pop frame from CQ\n");
140862 + return -EINVAL;
140863 + }
140864 + } while (!(ppxr.stat & 0x2));
140865 +
140866 + return 0;
140867 +}
140868 +EXPORT_SYMBOL(qman_ceetm_drain_cq);
140869 +
140870 +#define CEETM_LFQMT_LFQID_MSB 0xF00000
140871 +#define CEETM_LFQMT_LFQID_LSB 0x000FFF
140872 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
140873 + struct qm_ceetm_cq *cq)
140874 +{
140875 + struct qm_ceetm_lfq *p;
140876 + u32 lfqid;
140877 + int ret = 0;
140878 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
140879 +
140880 + if (cq->parent->dcp_idx == qm_dc_portal_fman0) {
140881 + ret = qman_alloc_ceetm0_lfqid(&lfqid);
140882 + } else if (cq->parent->dcp_idx == qm_dc_portal_fman1) {
140883 + ret = qman_alloc_ceetm1_lfqid(&lfqid);
140884 + } else {
140885 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140886 + cq->parent->dcp_idx);
140887 + return -EINVAL;
140888 + }
140889 +
140890 + if (ret) {
140891 + pr_err("There is no lfqid avalaible for CQ#%d!\n", cq->idx);
140892 + return -ENODEV;
140893 + }
140894 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140895 + if (!p)
140896 + return -ENOMEM;
140897 + p->idx = lfqid;
140898 + p->dctidx = (u16)(lfqid & CEETM_LFQMT_LFQID_LSB);
140899 + p->parent = cq->parent;
140900 + list_add_tail(&p->node, &cq->bound_lfqids);
140901 +
140902 + lfqmt_config.lfqid = cpu_to_be24(CEETM_LFQMT_LFQID_MSB |
140903 + (cq->parent->dcp_idx << 16) |
140904 + (lfqid & CEETM_LFQMT_LFQID_LSB));
140905 + lfqmt_config.cqid = cpu_to_be16((cq->parent->idx << 4) | (cq->idx));
140906 + lfqmt_config.dctidx = cpu_to_be16(p->dctidx);
140907 + if (qman_ceetm_configure_lfqmt(&lfqmt_config)) {
140908 + pr_err("Can't configure LFQMT for LFQID#%d @ CQ#%d\n",
140909 + lfqid, cq->idx);
140910 + list_del(&p->node);
140911 + kfree(p);
140912 + return -EINVAL;
140913 + }
140914 + *lfq = p;
140915 + return 0;
140916 +}
140917 +EXPORT_SYMBOL(qman_ceetm_lfq_claim);
140918 +
140919 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq)
140920 +{
140921 + if (lfq->parent->dcp_idx == qm_dc_portal_fman0) {
140922 + qman_release_ceetm0_lfqid(lfq->idx);
140923 + } else if (lfq->parent->dcp_idx == qm_dc_portal_fman1) {
140924 + qman_release_ceetm1_lfqid(lfq->idx);
140925 + } else {
140926 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140927 + lfq->parent->dcp_idx);
140928 + return -EINVAL;
140929 + }
140930 + list_del(&lfq->node);
140931 + kfree(lfq);
140932 + return 0;
140933 +}
140934 +EXPORT_SYMBOL(qman_ceetm_lfq_release);
140935 +
140936 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq, u64 context_a,
140937 + u32 context_b)
140938 +{
140939 + struct qm_mcc_ceetm_dct_config dct_config;
140940 + lfq->context_a = context_a;
140941 + lfq->context_b = context_b;
140942 + dct_config.dctidx = cpu_to_be16((u16)lfq->dctidx);
140943 + dct_config.dcpid = lfq->parent->dcp_idx;
140944 + dct_config.context_b = cpu_to_be32(context_b);
140945 + dct_config.context_a = cpu_to_be64(context_a);
140946 +
140947 + return qman_ceetm_configure_dct(&dct_config);
140948 +}
140949 +EXPORT_SYMBOL(qman_ceetm_lfq_set_context);
140950 +
140951 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq, u64 *context_a,
140952 + u32 *context_b)
140953 +{
140954 + struct qm_mcc_ceetm_dct_query dct_query;
140955 + struct qm_mcr_ceetm_dct_query query_result;
140956 +
140957 + dct_query.dctidx = cpu_to_be16(lfq->dctidx);
140958 + dct_query.dcpid = lfq->parent->dcp_idx;
140959 + if (qman_ceetm_query_dct(&dct_query, &query_result)) {
140960 + pr_err("Can't query LFQID#%d's context!\n", lfq->idx);
140961 + return -EINVAL;
140962 + }
140963 + *context_a = be64_to_cpu(query_result.context_a);
140964 + *context_b = be32_to_cpu(query_result.context_b);
140965 + return 0;
140966 +}
140967 +EXPORT_SYMBOL(qman_ceetm_lfq_get_context);
140968 +
140969 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq)
140970 +{
140971 + spin_lock_init(&fq->fqlock);
140972 + fq->fqid = lfq->idx;
140973 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
140974 + if (lfq->ern)
140975 + fq->cb.ern = lfq->ern;
140976 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
140977 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
140978 + return -ENOMEM;
140979 +#endif
140980 + return 0;
140981 +}
140982 +EXPORT_SYMBOL(qman_ceetm_create_fq);
140983 +
140984 +#define MAX_CCG_IDX 0x000F
140985 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
140986 + struct qm_ceetm_channel *channel,
140987 + unsigned int idx,
140988 + void (*cscn)(struct qm_ceetm_ccg *,
140989 + void *cb_ctx,
140990 + int congested),
140991 + void *cb_ctx)
140992 +{
140993 + struct qm_ceetm_ccg *p;
140994 +
140995 + if (idx > MAX_CCG_IDX) {
140996 + pr_err("The given ccg index is out of range\n");
140997 + return -EINVAL;
140998 + }
140999 +
141000 + list_for_each_entry(p, &channel->ccgs, node) {
141001 + if (p->idx == idx) {
141002 + pr_err("The CCG#%d has been claimed\n", idx);
141003 + return -EINVAL;
141004 + }
141005 + }
141006 +
141007 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141008 + if (!p) {
141009 + pr_err("Can't allocate memory for CCG#%d!\n", idx);
141010 + return -ENOMEM;
141011 + }
141012 +
141013 + list_add_tail(&p->node, &channel->ccgs);
141014 +
141015 + p->idx = idx;
141016 + p->parent = channel;
141017 + p->cb = cscn;
141018 + p->cb_ctx = cb_ctx;
141019 + INIT_LIST_HEAD(&p->cb_node);
141020 +
141021 + *ccg = p;
141022 + return 0;
141023 +}
141024 +EXPORT_SYMBOL(qman_ceetm_ccg_claim);
141025 +
141026 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg)
141027 +{
141028 + unsigned long irqflags __maybe_unused;
141029 + struct qm_mcc_ceetm_ccgr_config config_opts;
141030 + int ret = 0;
141031 + struct qman_portal *p = get_affine_portal();
141032 +
141033 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
141034 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
141035 + if (!list_empty(&ccg->cb_node))
141036 + list_del(&ccg->cb_node);
141037 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141038 + (ccg->parent->idx << 4) | ccg->idx);
141039 + config_opts.dcpid = ccg->parent->dcp_idx;
141040 + config_opts.we_mask = cpu_to_be16(QM_CCGR_WE_CSCN_TUPD);
141041 + config_opts.cm_config.cscn_tupd = cpu_to_be16(PORTAL_IDX(p));
141042 + ret = qman_ceetm_configure_ccgr(&config_opts);
141043 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
141044 + put_affine_portal();
141045 +
141046 + list_del(&ccg->node);
141047 + kfree(ccg);
141048 + return ret;
141049 +}
141050 +EXPORT_SYMBOL(qman_ceetm_ccg_release);
141051 +
141052 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg, u16 we_mask,
141053 + const struct qm_ceetm_ccg_params *params)
141054 +{
141055 + struct qm_mcc_ceetm_ccgr_config config_opts;
141056 + unsigned long irqflags __maybe_unused;
141057 + int ret;
141058 + struct qman_portal *p;
141059 +
141060 + if (((ccg->parent->idx << 4) | ccg->idx) >= (2 * __CGR_NUM))
141061 + return -EINVAL;
141062 +
141063 + p = get_affine_portal();
141064 +
141065 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
141066 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
141067 +
141068 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141069 + (ccg->parent->idx << 4) | ccg->idx);
141070 + config_opts.dcpid = ccg->parent->dcp_idx;
141071 + config_opts.we_mask = we_mask;
141072 + if (we_mask & QM_CCGR_WE_CSCN_EN) {
141073 + config_opts.we_mask |= QM_CCGR_WE_CSCN_TUPD;
141074 + config_opts.cm_config.cscn_tupd = cpu_to_be16(
141075 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p));
141076 + }
141077 + config_opts.we_mask = cpu_to_be16(config_opts.we_mask);
141078 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
141079 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
141080 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
141081 + config_opts.cm_config.ctl_td_en = params->td_en;
141082 + config_opts.cm_config.ctl_td_mode = params->td_mode;
141083 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
141084 + config_opts.cm_config.ctl_mode = params->mode;
141085 + config_opts.cm_config.oal = params->oal;
141086 + config_opts.cm_config.cs_thres.hword =
141087 + cpu_to_be16(params->cs_thres_in.hword);
141088 + config_opts.cm_config.cs_thres_x.hword =
141089 + cpu_to_be16(params->cs_thres_out.hword);
141090 + config_opts.cm_config.td_thres.hword =
141091 + cpu_to_be16(params->td_thres.hword);
141092 + config_opts.cm_config.wr_parm_g.word =
141093 + cpu_to_be32(params->wr_parm_g.word);
141094 + config_opts.cm_config.wr_parm_y.word =
141095 + cpu_to_be32(params->wr_parm_y.word);
141096 + config_opts.cm_config.wr_parm_r.word =
141097 + cpu_to_be32(params->wr_parm_r.word);
141098 + ret = qman_ceetm_configure_ccgr(&config_opts);
141099 + if (ret) {
141100 + pr_err("Configure CCGR CM failed!\n");
141101 + goto release_lock;
141102 + }
141103 +
141104 + if (we_mask & QM_CCGR_WE_CSCN_EN)
141105 + if (list_empty(&ccg->cb_node))
141106 + list_add(&ccg->cb_node,
141107 + &p->ccgr_cbs[ccg->parent->dcp_idx]);
141108 +release_lock:
141109 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
141110 + put_affine_portal();
141111 + return ret;
141112 +}
141113 +EXPORT_SYMBOL(qman_ceetm_ccg_set);
141114 +
141115 +#define CEETM_CCGR_CTL_MASK 0x01
141116 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
141117 + struct qm_ceetm_ccg_params *params)
141118 +{
141119 + struct qm_mcc_ceetm_ccgr_query query_opts;
141120 + struct qm_mcr_ceetm_ccgr_query query_result;
141121 +
141122 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141123 + (ccg->parent->idx << 4) | ccg->idx);
141124 + query_opts.dcpid = ccg->parent->dcp_idx;
141125 +
141126 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141127 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141128 + return -EINVAL;
141129 + }
141130 +
141131 + params->wr_parm_r.word = query_result.cm_query.wr_parm_r.word;
141132 + params->wr_parm_y.word = query_result.cm_query.wr_parm_y.word;
141133 + params->wr_parm_g.word = query_result.cm_query.wr_parm_g.word;
141134 + params->td_thres.hword = query_result.cm_query.td_thres.hword;
141135 + params->cs_thres_out.hword = query_result.cm_query.cs_thres_x.hword;
141136 + params->cs_thres_in.hword = query_result.cm_query.cs_thres.hword;
141137 + params->oal = query_result.cm_query.oal;
141138 + params->wr_en_g = query_result.cm_query.ctl_wr_en_g;
141139 + params->wr_en_y = query_result.cm_query.ctl_wr_en_y;
141140 + params->wr_en_r = query_result.cm_query.ctl_wr_en_r;
141141 + params->td_en = query_result.cm_query.ctl_td_en;
141142 + params->td_mode = query_result.cm_query.ctl_td_mode;
141143 + params->cscn_en = query_result.cm_query.ctl_cscn_en;
141144 + params->mode = query_result.cm_query.ctl_mode;
141145 +
141146 + return 0;
141147 +}
141148 +EXPORT_SYMBOL(qman_ceetm_ccg_get);
141149 +
141150 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
141151 + u64 *frame_count, u64 *byte_count)
141152 +{
141153 + struct qm_mcr_ceetm_statistics_query result;
141154 + u16 cid, command_type;
141155 + enum qm_dc_portal dcp_idx;
141156 + int ret;
141157 +
141158 + cid = cpu_to_be16((ccg->parent->idx << 4) | ccg->idx);
141159 + dcp_idx = ccg->parent->dcp_idx;
141160 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
141161 + command_type = CEETM_QUERY_REJECT_CLEAR_STATISTICS;
141162 + else
141163 + command_type = CEETM_QUERY_REJECT_STATISTICS;
141164 +
141165 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
141166 + if (ret) {
141167 + pr_err("Can't query the statistics of CCG#%d!\n", ccg->idx);
141168 + return -EINVAL;
141169 + }
141170 +
141171 + *frame_count = be40_to_cpu(result.frm_cnt);
141172 + *byte_count = be48_to_cpu(result.byte_cnt);
141173 + return 0;
141174 +}
141175 +EXPORT_SYMBOL(qman_ceetm_ccg_get_reject_statistics);
141176 +
141177 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
141178 + u16 swp_idx,
141179 + unsigned int *cscn_enabled)
141180 +{
141181 + struct qm_mcc_ceetm_ccgr_query query_opts;
141182 + struct qm_mcr_ceetm_ccgr_query query_result;
141183 + int i;
141184 +
141185 + DPA_ASSERT(swp_idx < 127);
141186 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141187 + (ccg->parent->idx << 4) | ccg->idx);
141188 + query_opts.dcpid = ccg->parent->dcp_idx;
141189 +
141190 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141191 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141192 + return -EINVAL;
141193 + }
141194 +
141195 + i = swp_idx / 32;
141196 + i = 3 - i;
141197 + *cscn_enabled = query_result.cm_query.cscn_targ_swp[i] >>
141198 + (31 - swp_idx % 32);
141199 +
141200 + return 0;
141201 +}
141202 +EXPORT_SYMBOL(qman_ceetm_cscn_swp_get);
141203 +
141204 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
141205 + u16 dcp_idx,
141206 + u8 vcgid,
141207 + unsigned int cscn_enabled,
141208 + u16 we_mask,
141209 + const struct qm_ceetm_ccg_params *params)
141210 +{
141211 + struct qm_mcc_ceetm_ccgr_config config_opts;
141212 + int ret;
141213 +
141214 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141215 + (ccg->parent->idx << 4) | ccg->idx);
141216 + config_opts.dcpid = ccg->parent->dcp_idx;
141217 + config_opts.we_mask = cpu_to_be16(we_mask | QM_CCGR_WE_CSCN_TUPD |
141218 + QM_CCGR_WE_CDV);
141219 + config_opts.cm_config.cdv = vcgid;
141220 + config_opts.cm_config.cscn_tupd = cpu_to_be16((cscn_enabled << 15) |
141221 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_idx);
141222 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
141223 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
141224 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
141225 + config_opts.cm_config.ctl_td_en = params->td_en;
141226 + config_opts.cm_config.ctl_td_mode = params->td_mode;
141227 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
141228 + config_opts.cm_config.ctl_mode = params->mode;
141229 + config_opts.cm_config.cs_thres.hword =
141230 + cpu_to_be16(params->cs_thres_in.hword);
141231 + config_opts.cm_config.cs_thres_x.hword =
141232 + cpu_to_be16(params->cs_thres_out.hword);
141233 + config_opts.cm_config.td_thres.hword =
141234 + cpu_to_be16(params->td_thres.hword);
141235 + config_opts.cm_config.wr_parm_g.word =
141236 + cpu_to_be32(params->wr_parm_g.word);
141237 + config_opts.cm_config.wr_parm_y.word =
141238 + cpu_to_be32(params->wr_parm_y.word);
141239 + config_opts.cm_config.wr_parm_r.word =
141240 + cpu_to_be32(params->wr_parm_r.word);
141241 +
141242 + ret = qman_ceetm_configure_ccgr(&config_opts);
141243 + if (ret) {
141244 + pr_err("Configure CSCN_TARG_DCP failed!\n");
141245 + return -EINVAL;
141246 + }
141247 + return 0;
141248 +}
141249 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_set);
141250 +
141251 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
141252 + u16 dcp_idx,
141253 + u8 *vcgid,
141254 + unsigned int *cscn_enabled)
141255 +{
141256 + struct qm_mcc_ceetm_ccgr_query query_opts;
141257 + struct qm_mcr_ceetm_ccgr_query query_result;
141258 +
141259 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141260 + (ccg->parent->idx << 4) | ccg->idx);
141261 + query_opts.dcpid = ccg->parent->dcp_idx;
141262 +
141263 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141264 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141265 + return -EINVAL;
141266 + }
141267 +
141268 + *vcgid = query_result.cm_query.cdv;
141269 + *cscn_enabled = (query_result.cm_query.cscn_targ_dcp >> dcp_idx) & 0x1;
141270 + return 0;
141271 +}
141272 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_get);
141273 +
141274 +int qman_ceetm_querycongestion(struct __qm_mcr_querycongestion *ccg_state,
141275 + unsigned int dcp_idx)
141276 +{
141277 + struct qm_mc_command *mcc;
141278 + struct qm_mc_result *mcr;
141279 + struct qman_portal *p;
141280 + unsigned long irqflags __maybe_unused;
141281 + u8 res;
141282 + int i, j;
141283 +
141284 + p = get_affine_portal();
141285 + PORTAL_IRQ_LOCK(p, irqflags);
141286 +
141287 + mcc = qm_mc_start(&p->p);
141288 + for (i = 0; i < 2; i++) {
141289 + mcc->ccgr_query.ccgrid =
141290 + cpu_to_be16(CEETM_QUERY_CONGESTION_STATE | i);
141291 + mcc->ccgr_query.dcpid = dcp_idx;
141292 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
141293 +
141294 + while (!(mcr = qm_mc_result(&p->p)))
141295 + cpu_relax();
141296 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
141297 + QM_CEETM_VERB_CCGR_QUERY);
141298 + res = mcr->result;
141299 + if (res == QM_MCR_RESULT_OK) {
141300 + for (j = 0; j < 8; j++)
141301 + mcr->ccgr_query.congestion_state.state.
141302 + __state[j] = be32_to_cpu(mcr->ccgr_query.
141303 + congestion_state.state.__state[j]);
141304 + *(ccg_state + i) =
141305 + mcr->ccgr_query.congestion_state.state;
141306 + } else {
141307 + pr_err("QUERY CEETM CONGESTION STATE failed\n");
141308 + PORTAL_IRQ_UNLOCK(p, irqflags);
141309 + return -EIO;
141310 + }
141311 + }
141312 + PORTAL_IRQ_UNLOCK(p, irqflags);
141313 + put_affine_portal();
141314 + return 0;
141315 +}
141316 +
141317 +int qman_set_wpm(int wpm_enable)
141318 +{
141319 + return qm_set_wpm(wpm_enable);
141320 +}
141321 +EXPORT_SYMBOL(qman_set_wpm);
141322 +
141323 +int qman_get_wpm(int *wpm_enable)
141324 +{
141325 + return qm_get_wpm(wpm_enable);
141326 +}
141327 +EXPORT_SYMBOL(qman_get_wpm);
141328 +
141329 +int qman_shutdown_fq(u32 fqid)
141330 +{
141331 + struct qman_portal *p;
141332 + unsigned long irqflags __maybe_unused;
141333 + int ret;
141334 + struct qm_portal *low_p;
141335 + p = get_affine_portal();
141336 + PORTAL_IRQ_LOCK(p, irqflags);
141337 + low_p = &p->p;
141338 + ret = qm_shutdown_fq(&low_p, 1, fqid);
141339 + PORTAL_IRQ_UNLOCK(p, irqflags);
141340 + put_affine_portal();
141341 + return ret;
141342 +}
141343 +
141344 +const struct qm_portal_config *qman_get_qm_portal_config(
141345 + struct qman_portal *portal)
141346 +{
141347 + return portal->sharing_redirect ? NULL : portal->config;
141348 +}
141349 --- /dev/null
141350 +++ b/drivers/staging/fsl_qbman/qman_low.h
141351 @@ -0,0 +1,1427 @@
141352 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
141353 + *
141354 + * Redistribution and use in source and binary forms, with or without
141355 + * modification, are permitted provided that the following conditions are met:
141356 + * * Redistributions of source code must retain the above copyright
141357 + * notice, this list of conditions and the following disclaimer.
141358 + * * Redistributions in binary form must reproduce the above copyright
141359 + * notice, this list of conditions and the following disclaimer in the
141360 + * documentation and/or other materials provided with the distribution.
141361 + * * Neither the name of Freescale Semiconductor nor the
141362 + * names of its contributors may be used to endorse or promote products
141363 + * derived from this software without specific prior written permission.
141364 + *
141365 + *
141366 + * ALTERNATIVELY, this software may be distributed under the terms of the
141367 + * GNU General Public License ("GPL") as published by the Free Software
141368 + * Foundation, either version 2 of that License or (at your option) any
141369 + * later version.
141370 + *
141371 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
141372 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
141373 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
141374 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
141375 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
141376 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
141377 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
141378 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
141379 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
141380 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
141381 + */
141382 +
141383 +#include "qman_private.h"
141384 +
141385 +/***************************/
141386 +/* Portal register assists */
141387 +/***************************/
141388 +
141389 +/* Cache-inhibited register offsets */
141390 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141391 +
141392 +#define QM_REG_EQCR_PI_CINH 0x0000
141393 +#define QM_REG_EQCR_CI_CINH 0x0004
141394 +#define QM_REG_EQCR_ITR 0x0008
141395 +#define QM_REG_DQRR_PI_CINH 0x0040
141396 +#define QM_REG_DQRR_CI_CINH 0x0044
141397 +#define QM_REG_DQRR_ITR 0x0048
141398 +#define QM_REG_DQRR_DCAP 0x0050
141399 +#define QM_REG_DQRR_SDQCR 0x0054
141400 +#define QM_REG_DQRR_VDQCR 0x0058
141401 +#define QM_REG_DQRR_PDQCR 0x005c
141402 +#define QM_REG_MR_PI_CINH 0x0080
141403 +#define QM_REG_MR_CI_CINH 0x0084
141404 +#define QM_REG_MR_ITR 0x0088
141405 +#define QM_REG_CFG 0x0100
141406 +#define QM_REG_ISR 0x0e00
141407 +#define QM_REG_IIR 0x0e0c
141408 +#define QM_REG_ITPR 0x0e14
141409 +
141410 +/* Cache-enabled register offsets */
141411 +#define QM_CL_EQCR 0x0000
141412 +#define QM_CL_DQRR 0x1000
141413 +#define QM_CL_MR 0x2000
141414 +#define QM_CL_EQCR_PI_CENA 0x3000
141415 +#define QM_CL_EQCR_CI_CENA 0x3100
141416 +#define QM_CL_DQRR_PI_CENA 0x3200
141417 +#define QM_CL_DQRR_CI_CENA 0x3300
141418 +#define QM_CL_MR_PI_CENA 0x3400
141419 +#define QM_CL_MR_CI_CENA 0x3500
141420 +#define QM_CL_CR 0x3800
141421 +#define QM_CL_RR0 0x3900
141422 +#define QM_CL_RR1 0x3940
141423 +
141424 +#endif
141425 +
141426 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
141427 +
141428 +#define QM_REG_EQCR_PI_CINH 0x3000
141429 +#define QM_REG_EQCR_CI_CINH 0x3040
141430 +#define QM_REG_EQCR_ITR 0x3080
141431 +#define QM_REG_DQRR_PI_CINH 0x3100
141432 +#define QM_REG_DQRR_CI_CINH 0x3140
141433 +#define QM_REG_DQRR_ITR 0x3180
141434 +#define QM_REG_DQRR_DCAP 0x31C0
141435 +#define QM_REG_DQRR_SDQCR 0x3200
141436 +#define QM_REG_DQRR_VDQCR 0x3240
141437 +#define QM_REG_DQRR_PDQCR 0x3280
141438 +#define QM_REG_MR_PI_CINH 0x3300
141439 +#define QM_REG_MR_CI_CINH 0x3340
141440 +#define QM_REG_MR_ITR 0x3380
141441 +#define QM_REG_CFG 0x3500
141442 +#define QM_REG_ISR 0x3600
141443 +#define QM_REG_IIR 0x36C0
141444 +#define QM_REG_ITPR 0x3740
141445 +
141446 +/* Cache-enabled register offsets */
141447 +#define QM_CL_EQCR 0x0000
141448 +#define QM_CL_DQRR 0x1000
141449 +#define QM_CL_MR 0x2000
141450 +#define QM_CL_EQCR_PI_CENA 0x3000
141451 +#define QM_CL_EQCR_CI_CENA 0x3040
141452 +#define QM_CL_DQRR_PI_CENA 0x3100
141453 +#define QM_CL_DQRR_CI_CENA 0x3140
141454 +#define QM_CL_MR_PI_CENA 0x3300
141455 +#define QM_CL_MR_CI_CENA 0x3340
141456 +#define QM_CL_CR 0x3800
141457 +#define QM_CL_RR0 0x3900
141458 +#define QM_CL_RR1 0x3940
141459 +
141460 +#endif
141461 +
141462 +
141463 +/* BTW, the drivers (and h/w programming model) already obtain the required
141464 + * synchronisation for portal accesses via lwsync(), hwsync(), and
141465 + * data-dependencies. Use of barrier()s or other order-preserving primitives
141466 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
141467 + * simply ensure that the compiler treats the portal registers as volatile (ie.
141468 + * non-coherent). */
141469 +
141470 +/* Cache-inhibited register access. */
141471 +#define __qm_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ci + (o)))
141472 +#define __qm_out(qm, o, val) __raw_writel((cpu_to_be32(val)), \
141473 + (qm)->addr_ci + (o));
141474 +#define qm_in(reg) __qm_in(&portal->addr, QM_REG_##reg)
141475 +#define qm_out(reg, val) __qm_out(&portal->addr, QM_REG_##reg, val)
141476 +
141477 +/* Cache-enabled (index) register access */
141478 +#define __qm_cl_touch_ro(qm, o) dcbt_ro((qm)->addr_ce + (o))
141479 +#define __qm_cl_touch_rw(qm, o) dcbt_rw((qm)->addr_ce + (o))
141480 +#define __qm_cl_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ce + (o)))
141481 +#define __qm_cl_out(qm, o, val) \
141482 + do { \
141483 + u32 *__tmpclout = (qm)->addr_ce + (o); \
141484 + __raw_writel(cpu_to_be32(val), __tmpclout); \
141485 + dcbf(__tmpclout); \
141486 + } while (0)
141487 +#define __qm_cl_invalidate(qm, o) dcbi((qm)->addr_ce + (o))
141488 +#define qm_cl_touch_ro(reg) __qm_cl_touch_ro(&portal->addr, QM_CL_##reg##_CENA)
141489 +#define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, QM_CL_##reg##_CENA)
141490 +#define qm_cl_in(reg) __qm_cl_in(&portal->addr, QM_CL_##reg##_CENA)
141491 +#define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, QM_CL_##reg##_CENA, val)
141492 +#define qm_cl_invalidate(reg)\
141493 + __qm_cl_invalidate(&portal->addr, QM_CL_##reg##_CENA)
141494 +
141495 +/* Cache-enabled ring access */
141496 +#define qm_cl(base, idx) ((void *)base + ((idx) << 6))
141497 +
141498 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
141499 + * analysis, look at using the "extra" bit in the ring index registers to avoid
141500 + * cyclic issues. */
141501 +static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
141502 +{
141503 + /* 'first' is included, 'last' is excluded */
141504 + if (first <= last)
141505 + return last - first;
141506 + return ringsize + last - first;
141507 +}
141508 +
141509 +/* Portal modes.
141510 + * Enum types;
141511 + * pmode == production mode
141512 + * cmode == consumption mode,
141513 + * dmode == h/w dequeue mode.
141514 + * Enum values use 3 letter codes. First letter matches the portal mode,
141515 + * remaining two letters indicate;
141516 + * ci == cache-inhibited portal register
141517 + * ce == cache-enabled portal register
141518 + * vb == in-band valid-bit (cache-enabled)
141519 + * dc == DCA (Discrete Consumption Acknowledgement), DQRR-only
141520 + * As for "enum qm_dqrr_dmode", it should be self-explanatory.
141521 + */
141522 +enum qm_eqcr_pmode { /* matches QCSP_CFG::EPM */
141523 + qm_eqcr_pci = 0, /* PI index, cache-inhibited */
141524 + qm_eqcr_pce = 1, /* PI index, cache-enabled */
141525 + qm_eqcr_pvb = 2 /* valid-bit */
141526 +};
141527 +enum qm_dqrr_dmode { /* matches QCSP_CFG::DP */
141528 + qm_dqrr_dpush = 0, /* SDQCR + VDQCR */
141529 + qm_dqrr_dpull = 1 /* PDQCR */
141530 +};
141531 +enum qm_dqrr_pmode { /* s/w-only */
141532 + qm_dqrr_pci, /* reads DQRR_PI_CINH */
141533 + qm_dqrr_pce, /* reads DQRR_PI_CENA */
141534 + qm_dqrr_pvb /* reads valid-bit */
141535 +};
141536 +enum qm_dqrr_cmode { /* matches QCSP_CFG::DCM */
141537 + qm_dqrr_cci = 0, /* CI index, cache-inhibited */
141538 + qm_dqrr_cce = 1, /* CI index, cache-enabled */
141539 + qm_dqrr_cdc = 2 /* Discrete Consumption Acknowledgement */
141540 +};
141541 +enum qm_mr_pmode { /* s/w-only */
141542 + qm_mr_pci, /* reads MR_PI_CINH */
141543 + qm_mr_pce, /* reads MR_PI_CENA */
141544 + qm_mr_pvb /* reads valid-bit */
141545 +};
141546 +enum qm_mr_cmode { /* matches QCSP_CFG::MM */
141547 + qm_mr_cci = 0, /* CI index, cache-inhibited */
141548 + qm_mr_cce = 1 /* CI index, cache-enabled */
141549 +};
141550 +
141551 +
141552 +/* ------------------------- */
141553 +/* --- Portal structures --- */
141554 +
141555 +#define QM_EQCR_SIZE 8
141556 +#define QM_DQRR_SIZE 16
141557 +#define QM_MR_SIZE 8
141558 +
141559 +struct qm_eqcr {
141560 + struct qm_eqcr_entry *ring, *cursor;
141561 + u8 ci, available, ithresh, vbit;
141562 +#ifdef CONFIG_FSL_DPA_CHECKING
141563 + u32 busy;
141564 + enum qm_eqcr_pmode pmode;
141565 +#endif
141566 +};
141567 +
141568 +struct qm_dqrr {
141569 + const struct qm_dqrr_entry *ring, *cursor;
141570 + u8 pi, ci, fill, ithresh, vbit;
141571 +#ifdef CONFIG_FSL_DPA_CHECKING
141572 + enum qm_dqrr_dmode dmode;
141573 + enum qm_dqrr_pmode pmode;
141574 + enum qm_dqrr_cmode cmode;
141575 +#endif
141576 +};
141577 +
141578 +struct qm_mr {
141579 + const struct qm_mr_entry *ring, *cursor;
141580 + u8 pi, ci, fill, ithresh, vbit;
141581 +#ifdef CONFIG_FSL_DPA_CHECKING
141582 + enum qm_mr_pmode pmode;
141583 + enum qm_mr_cmode cmode;
141584 +#endif
141585 +};
141586 +
141587 +struct qm_mc {
141588 + struct qm_mc_command *cr;
141589 + struct qm_mc_result *rr;
141590 + u8 rridx, vbit;
141591 +#ifdef CONFIG_FSL_DPA_CHECKING
141592 + enum {
141593 + /* Can be _mc_start()ed */
141594 + qman_mc_idle,
141595 + /* Can be _mc_commit()ed or _mc_abort()ed */
141596 + qman_mc_user,
141597 + /* Can only be _mc_retry()ed */
141598 + qman_mc_hw
141599 + } state;
141600 +#endif
141601 +};
141602 +
141603 +#define QM_PORTAL_ALIGNMENT ____cacheline_aligned
141604 +
141605 +struct qm_addr {
141606 + void __iomem *addr_ce; /* cache-enabled */
141607 + void __iomem *addr_ci; /* cache-inhibited */
141608 +};
141609 +
141610 +struct qm_portal {
141611 + /* In the non-CONFIG_FSL_DPA_CHECKING case, the following stuff up to
141612 + * and including 'mc' fits within a cacheline (yay!). The 'config' part
141613 + * is setup-only, so isn't a cause for a concern. In other words, don't
141614 + * rearrange this structure on a whim, there be dragons ... */
141615 + struct qm_addr addr;
141616 + struct qm_eqcr eqcr;
141617 + struct qm_dqrr dqrr;
141618 + struct qm_mr mr;
141619 + struct qm_mc mc;
141620 +} QM_PORTAL_ALIGNMENT;
141621 +
141622 +
141623 +/* ---------------- */
141624 +/* --- EQCR API --- */
141625 +
141626 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
141627 +#define EQCR_CARRYCLEAR(p) \
141628 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_EQCR_SIZE << 6)))
141629 +
141630 +/* Bit-wise logic to convert a ring pointer to a ring index */
141631 +static inline u8 EQCR_PTR2IDX(struct qm_eqcr_entry *e)
141632 +{
141633 + return ((uintptr_t)e >> 6) & (QM_EQCR_SIZE - 1);
141634 +}
141635 +
141636 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
141637 +static inline void EQCR_INC(struct qm_eqcr *eqcr)
141638 +{
141639 + /* NB: this is odd-looking, but experiments show that it generates fast
141640 + * code with essentially no branching overheads. We increment to the
141641 + * next EQCR pointer and handle overflow and 'vbit'. */
141642 + struct qm_eqcr_entry *partial = eqcr->cursor + 1;
141643 + eqcr->cursor = EQCR_CARRYCLEAR(partial);
141644 + if (partial != eqcr->cursor)
141645 + eqcr->vbit ^= QM_EQCR_VERB_VBIT;
141646 +}
141647 +
141648 +static inline int qm_eqcr_init(struct qm_portal *portal,
141649 + enum qm_eqcr_pmode pmode,
141650 + unsigned int eq_stash_thresh,
141651 + int eq_stash_prio)
141652 +{
141653 + /* This use of 'register', as well as all other occurrences, is because
141654 + * it has been observed to generate much faster code with gcc than is
141655 + * otherwise the case. */
141656 + register struct qm_eqcr *eqcr = &portal->eqcr;
141657 + u32 cfg;
141658 + u8 pi;
141659 +
141660 + eqcr->ring = portal->addr.addr_ce + QM_CL_EQCR;
141661 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
141662 + qm_cl_invalidate(EQCR_CI);
141663 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
141664 + eqcr->cursor = eqcr->ring + pi;
141665 + eqcr->vbit = (qm_in(EQCR_PI_CINH) & QM_EQCR_SIZE) ?
141666 + QM_EQCR_VERB_VBIT : 0;
141667 + eqcr->available = QM_EQCR_SIZE - 1 -
141668 + qm_cyc_diff(QM_EQCR_SIZE, eqcr->ci, pi);
141669 + eqcr->ithresh = qm_in(EQCR_ITR);
141670 +#ifdef CONFIG_FSL_DPA_CHECKING
141671 + eqcr->busy = 0;
141672 + eqcr->pmode = pmode;
141673 +#endif
141674 + cfg = (qm_in(CFG) & 0x00ffffff) |
141675 + (eq_stash_thresh << 28) | /* QCSP_CFG: EST */
141676 + (eq_stash_prio << 26) | /* QCSP_CFG: EP */
141677 + ((pmode & 0x3) << 24); /* QCSP_CFG::EPM */
141678 + qm_out(CFG, cfg);
141679 + return 0;
141680 +}
141681 +
141682 +static inline unsigned int qm_eqcr_get_ci_stashing(struct qm_portal *portal)
141683 +{
141684 + return (qm_in(CFG) >> 28) & 0x7;
141685 +}
141686 +
141687 +static inline void qm_eqcr_finish(struct qm_portal *portal)
141688 +{
141689 + register struct qm_eqcr *eqcr = &portal->eqcr;
141690 + u8 pi, ci;
141691 + u32 cfg;
141692 +
141693 + /*
141694 + * Disable EQCI stashing because the QMan only
141695 + * presents the value it previously stashed to
141696 + * maintain coherency. Setting the stash threshold
141697 + * to 1 then 0 ensures that QMan has resyncronized
141698 + * its internal copy so that the portal is clean
141699 + * when it is reinitialized in the future
141700 + */
141701 + cfg = (qm_in(CFG) & 0x0fffffff) |
141702 + (1 << 28); /* QCSP_CFG: EST */
141703 + qm_out(CFG, cfg);
141704 + cfg &= 0x0fffffff; /* stash threshold = 0 */
141705 + qm_out(CFG, cfg);
141706 +
141707 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
141708 + ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
141709 +
141710 + /* Refresh EQCR CI cache value */
141711 + qm_cl_invalidate(EQCR_CI);
141712 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
141713 +
141714 + DPA_ASSERT(!eqcr->busy);
141715 + if (pi != EQCR_PTR2IDX(eqcr->cursor))
141716 + pr_crit("losing uncommited EQCR entries\n");
141717 + if (ci != eqcr->ci)
141718 + pr_crit("missing existing EQCR completions\n");
141719 + if (eqcr->ci != EQCR_PTR2IDX(eqcr->cursor))
141720 + pr_crit("EQCR destroyed unquiesced\n");
141721 +}
141722 +
141723 +static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal
141724 + *portal)
141725 +{
141726 + register struct qm_eqcr *eqcr = &portal->eqcr;
141727 + DPA_ASSERT(!eqcr->busy);
141728 + if (!eqcr->available)
141729 + return NULL;
141730 +
141731 +
141732 +#ifdef CONFIG_FSL_DPA_CHECKING
141733 + eqcr->busy = 1;
141734 +#endif
141735 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141736 + dcbz_64(eqcr->cursor);
141737 +#endif
141738 + return eqcr->cursor;
141739 +}
141740 +
141741 +static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal
141742 + *portal)
141743 +{
141744 + register struct qm_eqcr *eqcr = &portal->eqcr;
141745 + u8 diff, old_ci;
141746 +
141747 + DPA_ASSERT(!eqcr->busy);
141748 + if (!eqcr->available) {
141749 + old_ci = eqcr->ci;
141750 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
141751 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
141752 + eqcr->available += diff;
141753 + if (!diff)
141754 + return NULL;
141755 + }
141756 +#ifdef CONFIG_FSL_DPA_CHECKING
141757 + eqcr->busy = 1;
141758 +#endif
141759 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141760 + dcbz_64(eqcr->cursor);
141761 +#endif
141762 + return eqcr->cursor;
141763 +}
141764 +
141765 +static inline void qm_eqcr_abort(struct qm_portal *portal)
141766 +{
141767 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
141768 + DPA_ASSERT(eqcr->busy);
141769 +#ifdef CONFIG_FSL_DPA_CHECKING
141770 + eqcr->busy = 0;
141771 +#endif
141772 +}
141773 +
141774 +static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next(
141775 + struct qm_portal *portal, u8 myverb)
141776 +{
141777 + register struct qm_eqcr *eqcr = &portal->eqcr;
141778 + DPA_ASSERT(eqcr->busy);
141779 + DPA_ASSERT(eqcr->pmode != qm_eqcr_pvb);
141780 + if (eqcr->available == 1)
141781 + return NULL;
141782 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141783 + dcbf(eqcr->cursor);
141784 + EQCR_INC(eqcr);
141785 + eqcr->available--;
141786 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141787 + dcbz_64(eqcr->cursor);
141788 +#endif
141789 + return eqcr->cursor;
141790 +}
141791 +
141792 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
141793 +#define EQCR_COMMIT_CHECKS(eqcr) \
141794 +do { \
141795 + DPA_ASSERT(eqcr->busy); \
141796 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0xffffff00)); \
141797 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0xffffff00)); \
141798 +} while (0)
141799 +#else
141800 +#define EQCR_COMMIT_CHECKS(eqcr) \
141801 +do { \
141802 + DPA_ASSERT(eqcr->busy); \
141803 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & \
141804 + cpu_to_be32(0x00ffffff))); \
141805 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & \
141806 + cpu_to_be32(0x00ffffff))); \
141807 +} while (0)
141808 +#endif
141809 +
141810 +static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb)
141811 +{
141812 + register struct qm_eqcr *eqcr = &portal->eqcr;
141813 + EQCR_COMMIT_CHECKS(eqcr);
141814 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pci);
141815 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141816 + EQCR_INC(eqcr);
141817 + eqcr->available--;
141818 + dcbf(eqcr->cursor);
141819 + hwsync();
141820 + qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor));
141821 +#ifdef CONFIG_FSL_DPA_CHECKING
141822 + eqcr->busy = 0;
141823 +#endif
141824 +}
141825 +
141826 +static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal)
141827 +{
141828 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
141829 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
141830 + qm_cl_invalidate(EQCR_PI);
141831 + qm_cl_touch_rw(EQCR_PI);
141832 +}
141833 +
141834 +static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb)
141835 +{
141836 + register struct qm_eqcr *eqcr = &portal->eqcr;
141837 + EQCR_COMMIT_CHECKS(eqcr);
141838 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
141839 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141840 + EQCR_INC(eqcr);
141841 + eqcr->available--;
141842 + dcbf(eqcr->cursor);
141843 + lwsync();
141844 + qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor));
141845 +#ifdef CONFIG_FSL_DPA_CHECKING
141846 + eqcr->busy = 0;
141847 +#endif
141848 +}
141849 +
141850 +static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb)
141851 +{
141852 + register struct qm_eqcr *eqcr = &portal->eqcr;
141853 + struct qm_eqcr_entry *eqcursor;
141854 + EQCR_COMMIT_CHECKS(eqcr);
141855 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pvb);
141856 + lwsync();
141857 + eqcursor = eqcr->cursor;
141858 + eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141859 + dcbf(eqcursor);
141860 + EQCR_INC(eqcr);
141861 + eqcr->available--;
141862 +#ifdef CONFIG_FSL_DPA_CHECKING
141863 + eqcr->busy = 0;
141864 +#endif
141865 +}
141866 +
141867 +static inline u8 qm_eqcr_cci_update(struct qm_portal *portal)
141868 +{
141869 + register struct qm_eqcr *eqcr = &portal->eqcr;
141870 + u8 diff, old_ci = eqcr->ci;
141871 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
141872 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
141873 + eqcr->available += diff;
141874 + return diff;
141875 +}
141876 +
141877 +static inline void qm_eqcr_cce_prefetch(struct qm_portal *portal)
141878 +{
141879 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
141880 + qm_cl_touch_ro(EQCR_CI);
141881 +}
141882 +
141883 +static inline u8 qm_eqcr_cce_update(struct qm_portal *portal)
141884 +{
141885 + register struct qm_eqcr *eqcr = &portal->eqcr;
141886 + u8 diff, old_ci = eqcr->ci;
141887 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
141888 + qm_cl_invalidate(EQCR_CI);
141889 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
141890 + eqcr->available += diff;
141891 + return diff;
141892 +}
141893 +
141894 +static inline u8 qm_eqcr_get_ithresh(struct qm_portal *portal)
141895 +{
141896 + register struct qm_eqcr *eqcr = &portal->eqcr;
141897 + return eqcr->ithresh;
141898 +}
141899 +
141900 +static inline void qm_eqcr_set_ithresh(struct qm_portal *portal, u8 ithresh)
141901 +{
141902 + register struct qm_eqcr *eqcr = &portal->eqcr;
141903 + eqcr->ithresh = ithresh;
141904 + qm_out(EQCR_ITR, ithresh);
141905 +}
141906 +
141907 +static inline u8 qm_eqcr_get_avail(struct qm_portal *portal)
141908 +{
141909 + register struct qm_eqcr *eqcr = &portal->eqcr;
141910 + return eqcr->available;
141911 +}
141912 +
141913 +static inline u8 qm_eqcr_get_fill(struct qm_portal *portal)
141914 +{
141915 + register struct qm_eqcr *eqcr = &portal->eqcr;
141916 + return QM_EQCR_SIZE - 1 - eqcr->available;
141917 +}
141918 +
141919 +
141920 +/* ---------------- */
141921 +/* --- DQRR API --- */
141922 +
141923 +/* FIXME: many possible improvements;
141924 + * - look at changing the API to use pointer rather than index parameters now
141925 + * that 'cursor' is a pointer,
141926 + * - consider moving other parameters to pointer if it could help (ci)
141927 + */
141928 +
141929 +#define DQRR_CARRYCLEAR(p) \
141930 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_DQRR_SIZE << 6)))
141931 +
141932 +static inline u8 DQRR_PTR2IDX(const struct qm_dqrr_entry *e)
141933 +{
141934 + return ((uintptr_t)e >> 6) & (QM_DQRR_SIZE - 1);
141935 +}
141936 +
141937 +static inline const struct qm_dqrr_entry *DQRR_INC(
141938 + const struct qm_dqrr_entry *e)
141939 +{
141940 + return DQRR_CARRYCLEAR(e + 1);
141941 +}
141942 +
141943 +static inline void qm_dqrr_set_maxfill(struct qm_portal *portal, u8 mf)
141944 +{
141945 + qm_out(CFG, (qm_in(CFG) & 0xff0fffff) |
141946 + ((mf & (QM_DQRR_SIZE - 1)) << 20));
141947 +}
141948 +
141949 +static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num)
141950 +{
141951 + register struct qm_dqrr *dqrr = &portal->dqrr;
141952 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
141953 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
141954 + qm_out(DQRR_CI_CINH, dqrr->ci);
141955 +}
141956 +
141957 +static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num)
141958 +{
141959 + register struct qm_dqrr *dqrr = &portal->dqrr;
141960 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
141961 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
141962 + qm_cl_out(DQRR_CI, dqrr->ci);
141963 +}
141964 +
141965 +static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask)
141966 +{
141967 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
141968 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
141969 + qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */
141970 + ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */
141971 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
141972 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
141973 +}
141974 +
141975 +static inline int qm_dqrr_init(struct qm_portal *portal,
141976 + const struct qm_portal_config *config,
141977 + enum qm_dqrr_dmode dmode,
141978 + __maybe_unused enum qm_dqrr_pmode pmode,
141979 + enum qm_dqrr_cmode cmode, u8 max_fill)
141980 +{
141981 + register struct qm_dqrr *dqrr = &portal->dqrr;
141982 + u32 cfg;
141983 +
141984 + /* Make sure the DQRR will be idle when we enable */
141985 + qm_out(DQRR_SDQCR, 0);
141986 + qm_out(DQRR_VDQCR, 0);
141987 + qm_out(DQRR_PDQCR, 0);
141988 + dqrr->ring = portal->addr.addr_ce + QM_CL_DQRR;
141989 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
141990 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
141991 + dqrr->cursor = dqrr->ring + dqrr->ci;
141992 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
141993 + dqrr->vbit = (qm_in(DQRR_PI_CINH) & QM_DQRR_SIZE) ?
141994 + QM_DQRR_VERB_VBIT : 0;
141995 + dqrr->ithresh = qm_in(DQRR_ITR);
141996 +
141997 + /* Free up pending DQRR entries if any as per current DCM */
141998 + if (dqrr->fill) {
141999 + enum qm_dqrr_cmode dcm = (qm_in(CFG) >> 16) & 3;
142000 +
142001 +#ifdef CONFIG_FSL_DPA_CHECKING
142002 + dqrr->cmode = dcm;
142003 +#endif
142004 + switch (dcm) {
142005 + case qm_dqrr_cci:
142006 + qm_dqrr_cci_consume(portal, dqrr->fill);
142007 + break;
142008 + case qm_dqrr_cce:
142009 + qm_dqrr_cce_consume(portal, dqrr->fill);
142010 + break;
142011 + case qm_dqrr_cdc:
142012 + qm_dqrr_cdc_consume_n(portal, (QM_DQRR_SIZE - 1));
142013 + break;
142014 + default:
142015 + DPA_ASSERT(0);
142016 + }
142017 + }
142018 +
142019 +#ifdef CONFIG_FSL_DPA_CHECKING
142020 + dqrr->dmode = dmode;
142021 + dqrr->pmode = pmode;
142022 + dqrr->cmode = cmode;
142023 +#endif
142024 + /* Invalidate every ring entry before beginning */
142025 + for (cfg = 0; cfg < QM_DQRR_SIZE; cfg++)
142026 + dcbi(qm_cl(dqrr->ring, cfg));
142027 + cfg = (qm_in(CFG) & 0xff000f00) |
142028 + ((max_fill & (QM_DQRR_SIZE - 1)) << 20) | /* DQRR_MF */
142029 + ((dmode & 1) << 18) | /* DP */
142030 + ((cmode & 3) << 16) | /* DCM */
142031 + 0xa0 | /* RE+SE */
142032 + (0 ? 0x40 : 0) | /* Ignore RP */
142033 + (0 ? 0x10 : 0); /* Ignore SP */
142034 + qm_out(CFG, cfg);
142035 + qm_dqrr_set_maxfill(portal, max_fill);
142036 + return 0;
142037 +}
142038 +
142039 +static inline void qm_dqrr_finish(struct qm_portal *portal)
142040 +{
142041 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142042 +#ifdef CONFIG_FSL_DPA_CHECKING
142043 + if ((dqrr->cmode != qm_dqrr_cdc) &&
142044 + (dqrr->ci != DQRR_PTR2IDX(dqrr->cursor)))
142045 + pr_crit("Ignoring completed DQRR entries\n");
142046 +#endif
142047 +}
142048 +
142049 +static inline const struct qm_dqrr_entry *qm_dqrr_current(
142050 + struct qm_portal *portal)
142051 +{
142052 + register struct qm_dqrr *dqrr = &portal->dqrr;
142053 + if (!dqrr->fill)
142054 + return NULL;
142055 + return dqrr->cursor;
142056 +}
142057 +
142058 +static inline u8 qm_dqrr_cursor(struct qm_portal *portal)
142059 +{
142060 + register struct qm_dqrr *dqrr = &portal->dqrr;
142061 + return DQRR_PTR2IDX(dqrr->cursor);
142062 +}
142063 +
142064 +static inline u8 qm_dqrr_next(struct qm_portal *portal)
142065 +{
142066 + register struct qm_dqrr *dqrr = &portal->dqrr;
142067 + DPA_ASSERT(dqrr->fill);
142068 + dqrr->cursor = DQRR_INC(dqrr->cursor);
142069 + return --dqrr->fill;
142070 +}
142071 +
142072 +static inline u8 qm_dqrr_pci_update(struct qm_portal *portal)
142073 +{
142074 + register struct qm_dqrr *dqrr = &portal->dqrr;
142075 + u8 diff, old_pi = dqrr->pi;
142076 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pci);
142077 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
142078 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
142079 + dqrr->fill += diff;
142080 + return diff;
142081 +}
142082 +
142083 +static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal)
142084 +{
142085 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142086 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
142087 + qm_cl_invalidate(DQRR_PI);
142088 + qm_cl_touch_ro(DQRR_PI);
142089 +}
142090 +
142091 +static inline u8 qm_dqrr_pce_update(struct qm_portal *portal)
142092 +{
142093 + register struct qm_dqrr *dqrr = &portal->dqrr;
142094 + u8 diff, old_pi = dqrr->pi;
142095 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
142096 + dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1);
142097 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
142098 + dqrr->fill += diff;
142099 + return diff;
142100 +}
142101 +
142102 +static inline void qm_dqrr_pvb_update(struct qm_portal *portal)
142103 +{
142104 + register struct qm_dqrr *dqrr = &portal->dqrr;
142105 + const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi);
142106 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pvb);
142107 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && !defined CONFIG_FSL_PAMU
142108 + /*
142109 + * On PowerPC platforms if PAMU is not available we need to
142110 + * manually invalidate the cache. When PAMU is available the
142111 + * cache is updated by stashing operations generated by QMan
142112 + */
142113 + dcbi(res);
142114 + dcbt_ro(res);
142115 +#endif
142116 +
142117 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
142118 + * inlining doesn't try to optimise out "excess reads". */
142119 + if ((__raw_readb(&res->verb) & QM_DQRR_VERB_VBIT) == dqrr->vbit) {
142120 + dqrr->pi = (dqrr->pi + 1) & (QM_DQRR_SIZE - 1);
142121 + if (!dqrr->pi)
142122 + dqrr->vbit ^= QM_DQRR_VERB_VBIT;
142123 + dqrr->fill++;
142124 + }
142125 +}
142126 +
142127 +
142128 +static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal)
142129 +{
142130 + register struct qm_dqrr *dqrr = &portal->dqrr;
142131 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
142132 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
142133 + qm_out(DQRR_CI_CINH, dqrr->ci);
142134 +}
142135 +
142136 +static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal)
142137 +{
142138 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142139 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142140 + qm_cl_invalidate(DQRR_CI);
142141 + qm_cl_touch_rw(DQRR_CI);
142142 +}
142143 +
142144 +static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal)
142145 +{
142146 + register struct qm_dqrr *dqrr = &portal->dqrr;
142147 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142148 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
142149 + qm_cl_out(DQRR_CI, dqrr->ci);
142150 +}
142151 +
142152 +static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx,
142153 + int park)
142154 +{
142155 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142156 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142157 + DPA_ASSERT(idx < QM_DQRR_SIZE);
142158 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142159 + ((park ? 1 : 0) << 6) | /* PK */
142160 + idx); /* DCAP_CI */
142161 +}
142162 +
142163 +static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal,
142164 + const struct qm_dqrr_entry *dq,
142165 + int park)
142166 +{
142167 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142168 + u8 idx = DQRR_PTR2IDX(dq);
142169 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142170 + DPA_ASSERT((dqrr->ring + idx) == dq);
142171 + DPA_ASSERT(idx < QM_DQRR_SIZE);
142172 + qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */
142173 + ((park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */
142174 + idx); /* DQRR_DCAP::DCAP_CI */
142175 +}
142176 +
142177 +static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal)
142178 +{
142179 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142180 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142181 + return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142182 +}
142183 +
142184 +static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal)
142185 +{
142186 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142187 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142188 + qm_cl_invalidate(DQRR_CI);
142189 + qm_cl_touch_ro(DQRR_CI);
142190 +}
142191 +
142192 +static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal)
142193 +{
142194 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142195 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142196 + return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1);
142197 +}
142198 +
142199 +static inline u8 qm_dqrr_get_ci(struct qm_portal *portal)
142200 +{
142201 + register struct qm_dqrr *dqrr = &portal->dqrr;
142202 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142203 + return dqrr->ci;
142204 +}
142205 +
142206 +static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx)
142207 +{
142208 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142209 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142210 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142211 + (1 << 6) | /* PK */
142212 + (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */
142213 +}
142214 +
142215 +static inline void qm_dqrr_park_current(struct qm_portal *portal)
142216 +{
142217 + register struct qm_dqrr *dqrr = &portal->dqrr;
142218 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142219 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142220 + (1 << 6) | /* PK */
142221 + DQRR_PTR2IDX(dqrr->cursor)); /* DCAP_CI */
142222 +}
142223 +
142224 +static inline void qm_dqrr_sdqcr_set(struct qm_portal *portal, u32 sdqcr)
142225 +{
142226 + qm_out(DQRR_SDQCR, sdqcr);
142227 +}
142228 +
142229 +static inline u32 qm_dqrr_sdqcr_get(struct qm_portal *portal)
142230 +{
142231 + return qm_in(DQRR_SDQCR);
142232 +}
142233 +
142234 +static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr)
142235 +{
142236 + qm_out(DQRR_VDQCR, vdqcr);
142237 +}
142238 +
142239 +static inline u32 qm_dqrr_vdqcr_get(struct qm_portal *portal)
142240 +{
142241 + return qm_in(DQRR_VDQCR);
142242 +}
142243 +
142244 +static inline void qm_dqrr_pdqcr_set(struct qm_portal *portal, u32 pdqcr)
142245 +{
142246 + qm_out(DQRR_PDQCR, pdqcr);
142247 +}
142248 +
142249 +static inline u32 qm_dqrr_pdqcr_get(struct qm_portal *portal)
142250 +{
142251 + return qm_in(DQRR_PDQCR);
142252 +}
142253 +
142254 +static inline u8 qm_dqrr_get_ithresh(struct qm_portal *portal)
142255 +{
142256 + register struct qm_dqrr *dqrr = &portal->dqrr;
142257 + return dqrr->ithresh;
142258 +}
142259 +
142260 +static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142261 +{
142262 + qm_out(DQRR_ITR, ithresh);
142263 +}
142264 +
142265 +static inline u8 qm_dqrr_get_maxfill(struct qm_portal *portal)
142266 +{
142267 + return (qm_in(CFG) & 0x00f00000) >> 20;
142268 +}
142269 +
142270 +
142271 +/* -------------- */
142272 +/* --- MR API --- */
142273 +
142274 +#define MR_CARRYCLEAR(p) \
142275 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_MR_SIZE << 6)))
142276 +
142277 +static inline u8 MR_PTR2IDX(const struct qm_mr_entry *e)
142278 +{
142279 + return ((uintptr_t)e >> 6) & (QM_MR_SIZE - 1);
142280 +}
142281 +
142282 +static inline const struct qm_mr_entry *MR_INC(const struct qm_mr_entry *e)
142283 +{
142284 + return MR_CARRYCLEAR(e + 1);
142285 +}
142286 +
142287 +static inline int qm_mr_init(struct qm_portal *portal, enum qm_mr_pmode pmode,
142288 + enum qm_mr_cmode cmode)
142289 +{
142290 + register struct qm_mr *mr = &portal->mr;
142291 + u32 cfg;
142292 +
142293 + mr->ring = portal->addr.addr_ce + QM_CL_MR;
142294 + mr->pi = qm_in(MR_PI_CINH) & (QM_MR_SIZE - 1);
142295 + mr->ci = qm_in(MR_CI_CINH) & (QM_MR_SIZE - 1);
142296 + mr->cursor = mr->ring + mr->ci;
142297 + mr->fill = qm_cyc_diff(QM_MR_SIZE, mr->ci, mr->pi);
142298 + mr->vbit = (qm_in(MR_PI_CINH) & QM_MR_SIZE) ? QM_MR_VERB_VBIT : 0;
142299 + mr->ithresh = qm_in(MR_ITR);
142300 +#ifdef CONFIG_FSL_DPA_CHECKING
142301 + mr->pmode = pmode;
142302 + mr->cmode = cmode;
142303 +#endif
142304 + cfg = (qm_in(CFG) & 0xfffff0ff) |
142305 + ((cmode & 1) << 8); /* QCSP_CFG:MM */
142306 + qm_out(CFG, cfg);
142307 + return 0;
142308 +}
142309 +
142310 +static inline void qm_mr_finish(struct qm_portal *portal)
142311 +{
142312 + register struct qm_mr *mr = &portal->mr;
142313 + if (mr->ci != MR_PTR2IDX(mr->cursor))
142314 + pr_crit("Ignoring completed MR entries\n");
142315 +}
142316 +
142317 +static inline const struct qm_mr_entry *qm_mr_current(struct qm_portal *portal)
142318 +{
142319 + register struct qm_mr *mr = &portal->mr;
142320 + if (!mr->fill)
142321 + return NULL;
142322 + return mr->cursor;
142323 +}
142324 +
142325 +static inline u8 qm_mr_cursor(struct qm_portal *portal)
142326 +{
142327 + register struct qm_mr *mr = &portal->mr;
142328 + return MR_PTR2IDX(mr->cursor);
142329 +}
142330 +
142331 +static inline u8 qm_mr_next(struct qm_portal *portal)
142332 +{
142333 + register struct qm_mr *mr = &portal->mr;
142334 + DPA_ASSERT(mr->fill);
142335 + mr->cursor = MR_INC(mr->cursor);
142336 + return --mr->fill;
142337 +}
142338 +
142339 +static inline u8 qm_mr_pci_update(struct qm_portal *portal)
142340 +{
142341 + register struct qm_mr *mr = &portal->mr;
142342 + u8 diff, old_pi = mr->pi;
142343 + DPA_ASSERT(mr->pmode == qm_mr_pci);
142344 + mr->pi = qm_in(MR_PI_CINH);
142345 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
142346 + mr->fill += diff;
142347 + return diff;
142348 +}
142349 +
142350 +static inline void qm_mr_pce_prefetch(struct qm_portal *portal)
142351 +{
142352 + __maybe_unused register struct qm_mr *mr = &portal->mr;
142353 + DPA_ASSERT(mr->pmode == qm_mr_pce);
142354 + qm_cl_invalidate(MR_PI);
142355 + qm_cl_touch_ro(MR_PI);
142356 +}
142357 +
142358 +static inline u8 qm_mr_pce_update(struct qm_portal *portal)
142359 +{
142360 + register struct qm_mr *mr = &portal->mr;
142361 + u8 diff, old_pi = mr->pi;
142362 + DPA_ASSERT(mr->pmode == qm_mr_pce);
142363 + mr->pi = qm_cl_in(MR_PI) & (QM_MR_SIZE - 1);
142364 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
142365 + mr->fill += diff;
142366 + return diff;
142367 +}
142368 +
142369 +static inline void qm_mr_pvb_update(struct qm_portal *portal)
142370 +{
142371 + register struct qm_mr *mr = &portal->mr;
142372 + const struct qm_mr_entry *res = qm_cl(mr->ring, mr->pi);
142373 + DPA_ASSERT(mr->pmode == qm_mr_pvb);
142374 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
142375 + * inlining doesn't try to optimise out "excess reads". */
142376 + if ((__raw_readb(&res->verb) & QM_MR_VERB_VBIT) == mr->vbit) {
142377 + mr->pi = (mr->pi + 1) & (QM_MR_SIZE - 1);
142378 + if (!mr->pi)
142379 + mr->vbit ^= QM_MR_VERB_VBIT;
142380 + mr->fill++;
142381 + res = MR_INC(res);
142382 + }
142383 + dcbit_ro(res);
142384 +}
142385 +
142386 +static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num)
142387 +{
142388 + register struct qm_mr *mr = &portal->mr;
142389 + DPA_ASSERT(mr->cmode == qm_mr_cci);
142390 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
142391 + qm_out(MR_CI_CINH, mr->ci);
142392 +}
142393 +
142394 +static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal)
142395 +{
142396 + register struct qm_mr *mr = &portal->mr;
142397 + DPA_ASSERT(mr->cmode == qm_mr_cci);
142398 + mr->ci = MR_PTR2IDX(mr->cursor);
142399 + qm_out(MR_CI_CINH, mr->ci);
142400 +}
142401 +
142402 +static inline void qm_mr_cce_prefetch(struct qm_portal *portal)
142403 +{
142404 + __maybe_unused register struct qm_mr *mr = &portal->mr;
142405 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142406 + qm_cl_invalidate(MR_CI);
142407 + qm_cl_touch_rw(MR_CI);
142408 +}
142409 +
142410 +static inline void qm_mr_cce_consume(struct qm_portal *portal, u8 num)
142411 +{
142412 + register struct qm_mr *mr = &portal->mr;
142413 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142414 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
142415 + qm_cl_out(MR_CI, mr->ci);
142416 +}
142417 +
142418 +static inline void qm_mr_cce_consume_to_current(struct qm_portal *portal)
142419 +{
142420 + register struct qm_mr *mr = &portal->mr;
142421 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142422 + mr->ci = MR_PTR2IDX(mr->cursor);
142423 + qm_cl_out(MR_CI, mr->ci);
142424 +}
142425 +
142426 +static inline u8 qm_mr_get_ci(struct qm_portal *portal)
142427 +{
142428 + register struct qm_mr *mr = &portal->mr;
142429 + return mr->ci;
142430 +}
142431 +
142432 +static inline u8 qm_mr_get_ithresh(struct qm_portal *portal)
142433 +{
142434 + register struct qm_mr *mr = &portal->mr;
142435 + return mr->ithresh;
142436 +}
142437 +
142438 +static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142439 +{
142440 + qm_out(MR_ITR, ithresh);
142441 +}
142442 +
142443 +
142444 +/* ------------------------------ */
142445 +/* --- Management command API --- */
142446 +
142447 +static inline int qm_mc_init(struct qm_portal *portal)
142448 +{
142449 + register struct qm_mc *mc = &portal->mc;
142450 + mc->cr = portal->addr.addr_ce + QM_CL_CR;
142451 + mc->rr = portal->addr.addr_ce + QM_CL_RR0;
142452 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
142453 + QM_MCC_VERB_VBIT) ? 0 : 1;
142454 + mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
142455 +#ifdef CONFIG_FSL_DPA_CHECKING
142456 + mc->state = qman_mc_idle;
142457 +#endif
142458 + return 0;
142459 +}
142460 +
142461 +static inline void qm_mc_finish(struct qm_portal *portal)
142462 +{
142463 + __maybe_unused register struct qm_mc *mc = &portal->mc;
142464 + DPA_ASSERT(mc->state == qman_mc_idle);
142465 +#ifdef CONFIG_FSL_DPA_CHECKING
142466 + if (mc->state != qman_mc_idle)
142467 + pr_crit("Losing incomplete MC command\n");
142468 +#endif
142469 +}
142470 +
142471 +static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal)
142472 +{
142473 + register struct qm_mc *mc = &portal->mc;
142474 + DPA_ASSERT(mc->state == qman_mc_idle);
142475 +#ifdef CONFIG_FSL_DPA_CHECKING
142476 + mc->state = qman_mc_user;
142477 +#endif
142478 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142479 + dcbz_64(mc->cr);
142480 +#endif
142481 + return mc->cr;
142482 +}
142483 +
142484 +static inline void qm_mc_abort(struct qm_portal *portal)
142485 +{
142486 + __maybe_unused register struct qm_mc *mc = &portal->mc;
142487 + DPA_ASSERT(mc->state == qman_mc_user);
142488 +#ifdef CONFIG_FSL_DPA_CHECKING
142489 + mc->state = qman_mc_idle;
142490 +#endif
142491 +}
142492 +
142493 +static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb)
142494 +{
142495 + register struct qm_mc *mc = &portal->mc;
142496 + struct qm_mc_result *rr = mc->rr + mc->rridx;
142497 + DPA_ASSERT(mc->state == qman_mc_user);
142498 + lwsync();
142499 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
142500 + dcbf(mc->cr);
142501 + dcbit_ro(rr);
142502 +#ifdef CONFIG_FSL_DPA_CHECKING
142503 + mc->state = qman_mc_hw;
142504 +#endif
142505 +}
142506 +
142507 +static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal)
142508 +{
142509 + register struct qm_mc *mc = &portal->mc;
142510 + struct qm_mc_result *rr = mc->rr + mc->rridx;
142511 + DPA_ASSERT(mc->state == qman_mc_hw);
142512 + /* The inactive response register's verb byte always returns zero until
142513 + * its command is submitted and completed. This includes the valid-bit,
142514 + * in case you were wondering... */
142515 + if (!__raw_readb(&rr->verb)) {
142516 + dcbit_ro(rr);
142517 + return NULL;
142518 + }
142519 + mc->rridx ^= 1;
142520 + mc->vbit ^= QM_MCC_VERB_VBIT;
142521 +#ifdef CONFIG_FSL_DPA_CHECKING
142522 + mc->state = qman_mc_idle;
142523 +#endif
142524 + return rr;
142525 +}
142526 +
142527 +
142528 +/* ------------------------------------- */
142529 +/* --- Portal interrupt register API --- */
142530 +
142531 +static inline int qm_isr_init(__always_unused struct qm_portal *portal)
142532 +{
142533 + return 0;
142534 +}
142535 +
142536 +static inline void qm_isr_finish(__always_unused struct qm_portal *portal)
142537 +{
142538 +}
142539 +
142540 +static inline void qm_isr_set_iperiod(struct qm_portal *portal, u16 iperiod)
142541 +{
142542 + qm_out(ITPR, iperiod);
142543 +}
142544 +
142545 +static inline u32 __qm_isr_read(struct qm_portal *portal, enum qm_isr_reg n)
142546 +{
142547 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
142548 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 6));
142549 +#else
142550 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 2));
142551 +#endif
142552 +}
142553 +
142554 +static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n,
142555 + u32 val)
142556 +{
142557 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
142558 + __qm_out(&portal->addr, QM_REG_ISR + (n << 6), val);
142559 +#else
142560 + __qm_out(&portal->addr, QM_REG_ISR + (n << 2), val);
142561 +#endif
142562 +}
142563 +
142564 +/* Cleanup FQs */
142565 +static inline int qm_shutdown_fq(struct qm_portal **portal, int portal_count,
142566 + u32 fqid)
142567 +{
142568 +
142569 + struct qm_mc_command *mcc;
142570 + struct qm_mc_result *mcr;
142571 + u8 state;
142572 + int orl_empty, fq_empty, i, drain = 0;
142573 + u32 result;
142574 + u32 channel, wq;
142575 + u16 dest_wq;
142576 +
142577 + /* Determine the state of the FQID */
142578 + mcc = qm_mc_start(portal[0]);
142579 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
142580 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ_NP);
142581 + while (!(mcr = qm_mc_result(portal[0])))
142582 + cpu_relax();
142583 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
142584 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
142585 + if (state == QM_MCR_NP_STATE_OOS)
142586 + return 0; /* Already OOS, no need to do anymore checks */
142587 +
142588 + /* Query which channel the FQ is using */
142589 + mcc = qm_mc_start(portal[0]);
142590 + mcc->queryfq.fqid = cpu_to_be32(fqid);
142591 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ);
142592 + while (!(mcr = qm_mc_result(portal[0])))
142593 + cpu_relax();
142594 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
142595 +
142596 + /* Need to store these since the MCR gets reused */
142597 + dest_wq = be16_to_cpu(mcr->queryfq.fqd.dest_wq);
142598 + wq = dest_wq & 0x7;
142599 + channel = dest_wq>>3;
142600 +
142601 + switch (state) {
142602 + case QM_MCR_NP_STATE_TEN_SCHED:
142603 + case QM_MCR_NP_STATE_TRU_SCHED:
142604 + case QM_MCR_NP_STATE_ACTIVE:
142605 + case QM_MCR_NP_STATE_PARKED:
142606 + orl_empty = 0;
142607 + mcc = qm_mc_start(portal[0]);
142608 + mcc->alterfq.fqid = cpu_to_be32(fqid);
142609 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_RETIRE);
142610 + while (!(mcr = qm_mc_result(portal[0])))
142611 + cpu_relax();
142612 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142613 + QM_MCR_VERB_ALTER_RETIRE);
142614 + result = mcr->result; /* Make a copy as we reuse MCR below */
142615 +
142616 + if (result == QM_MCR_RESULT_PENDING) {
142617 + /* Need to wait for the FQRN in the message ring, which
142618 + will only occur once the FQ has been drained. In
142619 + order for the FQ to drain the portal needs to be set
142620 + to dequeue from the channel the FQ is scheduled on */
142621 + const struct qm_mr_entry *msg;
142622 + const struct qm_dqrr_entry *dqrr = NULL;
142623 + int found_fqrn = 0;
142624 + u16 dequeue_wq = 0;
142625 +
142626 + /* Flag that we need to drain FQ */
142627 + drain = 1;
142628 +
142629 + if (channel >= qm_channel_pool1 &&
142630 + channel < (qm_channel_pool1 + 15)) {
142631 + /* Pool channel, enable the bit in the portal */
142632 + dequeue_wq = (channel -
142633 + qm_channel_pool1 + 1)<<4 | wq;
142634 + } else if (channel < qm_channel_pool1) {
142635 + /* Dedicated channel */
142636 + dequeue_wq = wq;
142637 + } else {
142638 + pr_info("Cannot recover FQ 0x%x, it is "
142639 + "scheduled on channel 0x%x",
142640 + fqid, channel);
142641 + return -EBUSY;
142642 + }
142643 + /* Set the sdqcr to drain this channel */
142644 + if (channel < qm_channel_pool1)
142645 + for (i = 0; i < portal_count; i++)
142646 + qm_dqrr_sdqcr_set(portal[i],
142647 + QM_SDQCR_TYPE_ACTIVE |
142648 + QM_SDQCR_CHANNELS_DEDICATED);
142649 + else
142650 + for (i = 0; i < portal_count; i++)
142651 + qm_dqrr_sdqcr_set(
142652 + portal[i],
142653 + QM_SDQCR_TYPE_ACTIVE |
142654 + QM_SDQCR_CHANNELS_POOL_CONV
142655 + (channel));
142656 + while (!found_fqrn) {
142657 + /* Keep draining DQRR while checking the MR*/
142658 + for (i = 0; i < portal_count; i++) {
142659 + qm_dqrr_pvb_update(portal[i]);
142660 + dqrr = qm_dqrr_current(portal[i]);
142661 + while (dqrr) {
142662 + qm_dqrr_cdc_consume_1ptr(
142663 + portal[i], dqrr, 0);
142664 + qm_dqrr_pvb_update(portal[i]);
142665 + qm_dqrr_next(portal[i]);
142666 + dqrr = qm_dqrr_current(
142667 + portal[i]);
142668 + }
142669 + /* Process message ring too */
142670 + qm_mr_pvb_update(portal[i]);
142671 + msg = qm_mr_current(portal[i]);
142672 + while (msg) {
142673 + if ((msg->verb &
142674 + QM_MR_VERB_TYPE_MASK)
142675 + == QM_MR_VERB_FQRN)
142676 + found_fqrn = 1;
142677 + qm_mr_next(portal[i]);
142678 + qm_mr_cci_consume_to_current(
142679 + portal[i]);
142680 + qm_mr_pvb_update(portal[i]);
142681 + msg = qm_mr_current(portal[i]);
142682 + }
142683 + cpu_relax();
142684 + }
142685 + }
142686 + }
142687 + if (result != QM_MCR_RESULT_OK &&
142688 + result != QM_MCR_RESULT_PENDING) {
142689 + /* error */
142690 + pr_err("qman_retire_fq failed on FQ 0x%x, result=0x%x\n",
142691 + fqid, result);
142692 + return -1;
142693 + }
142694 + if (!(mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)) {
142695 + /* ORL had no entries, no need to wait until the
142696 + ERNs come in */
142697 + orl_empty = 1;
142698 + }
142699 + /* Retirement succeeded, check to see if FQ needs
142700 + to be drained */
142701 + if (drain || mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY) {
142702 + /* FQ is Not Empty, drain using volatile DQ commands */
142703 + fq_empty = 0;
142704 + do {
142705 + const struct qm_dqrr_entry *dqrr = NULL;
142706 + u32 vdqcr = fqid | QM_VDQCR_NUMFRAMES_SET(3);
142707 + qm_dqrr_vdqcr_set(portal[0], vdqcr);
142708 +
142709 + /* Wait for a dequeue to occur */
142710 + while (dqrr == NULL) {
142711 + qm_dqrr_pvb_update(portal[0]);
142712 + dqrr = qm_dqrr_current(portal[0]);
142713 + if (!dqrr)
142714 + cpu_relax();
142715 + }
142716 + /* Process the dequeues, making sure to
142717 + empty the ring completely */
142718 + while (dqrr) {
142719 + if (be32_to_cpu(dqrr->fqid) == fqid &&
142720 + dqrr->stat & QM_DQRR_STAT_FQ_EMPTY)
142721 + fq_empty = 1;
142722 + qm_dqrr_cdc_consume_1ptr(portal[0],
142723 + dqrr, 0);
142724 + qm_dqrr_pvb_update(portal[0]);
142725 + qm_dqrr_next(portal[0]);
142726 + dqrr = qm_dqrr_current(portal[0]);
142727 + }
142728 + } while (fq_empty == 0);
142729 + }
142730 + for (i = 0; i < portal_count; i++)
142731 + qm_dqrr_sdqcr_set(portal[i], 0);
142732 +
142733 + /* Wait for the ORL to have been completely drained */
142734 + while (orl_empty == 0) {
142735 + const struct qm_mr_entry *msg;
142736 + qm_mr_pvb_update(portal[0]);
142737 + msg = qm_mr_current(portal[0]);
142738 + while (msg) {
142739 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) ==
142740 + QM_MR_VERB_FQRL)
142741 + orl_empty = 1;
142742 + qm_mr_next(portal[0]);
142743 + qm_mr_cci_consume_to_current(portal[0]);
142744 + qm_mr_pvb_update(portal[0]);
142745 + msg = qm_mr_current(portal[0]);
142746 + }
142747 + cpu_relax();
142748 + }
142749 + mcc = qm_mc_start(portal[0]);
142750 + mcc->alterfq.fqid = cpu_to_be32(fqid);
142751 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
142752 + while (!(mcr = qm_mc_result(portal[0])))
142753 + cpu_relax();
142754 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142755 + QM_MCR_VERB_ALTER_OOS);
142756 + if (mcr->result != QM_MCR_RESULT_OK) {
142757 + pr_err("OOS after drain Failed on FQID 0x%x, result 0x%x\n",
142758 + fqid, mcr->result);
142759 + return -1;
142760 + }
142761 + return 0;
142762 + case QM_MCR_NP_STATE_RETIRED:
142763 + /* Send OOS Command */
142764 + mcc = qm_mc_start(portal[0]);
142765 + mcc->alterfq.fqid = cpu_to_be32(fqid);
142766 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
142767 + while (!(mcr = qm_mc_result(portal[0])))
142768 + cpu_relax();
142769 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142770 + QM_MCR_VERB_ALTER_OOS);
142771 + if (mcr->result) {
142772 + pr_err("OOS Failed on FQID 0x%x\n", fqid);
142773 + return -1;
142774 + }
142775 + return 0;
142776 + }
142777 + return -1;
142778 +}
142779 --- /dev/null
142780 +++ b/drivers/staging/fsl_qbman/qman_private.h
142781 @@ -0,0 +1,398 @@
142782 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
142783 + *
142784 + * Redistribution and use in source and binary forms, with or without
142785 + * modification, are permitted provided that the following conditions are met:
142786 + * * Redistributions of source code must retain the above copyright
142787 + * notice, this list of conditions and the following disclaimer.
142788 + * * Redistributions in binary form must reproduce the above copyright
142789 + * notice, this list of conditions and the following disclaimer in the
142790 + * documentation and/or other materials provided with the distribution.
142791 + * * Neither the name of Freescale Semiconductor nor the
142792 + * names of its contributors may be used to endorse or promote products
142793 + * derived from this software without specific prior written permission.
142794 + *
142795 + *
142796 + * ALTERNATIVELY, this software may be distributed under the terms of the
142797 + * GNU General Public License ("GPL") as published by the Free Software
142798 + * Foundation, either version 2 of that License or (at your option) any
142799 + * later version.
142800 + *
142801 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
142802 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
142803 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
142804 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
142805 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
142806 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
142807 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
142808 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
142809 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
142810 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
142811 + */
142812 +
142813 +#include "dpa_sys.h"
142814 +#include <linux/fsl_qman.h>
142815 +#include <linux/iommu.h>
142816 +
142817 +#if defined(CONFIG_FSL_PAMU)
142818 +#include <asm/fsl_pamu_stash.h>
142819 +#endif
142820 +
142821 +#if !defined(CONFIG_FSL_QMAN_FQ_LOOKUP) && defined(CONFIG_PPC64)
142822 +#error "_PPC64 requires _FSL_QMAN_FQ_LOOKUP"
142823 +#endif
142824 +
142825 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
142826 + /* ----------------- */
142827 + /* Congestion Groups */
142828 + /* ----------------- */
142829 +/* This wrapper represents a bit-array for the state of the 256 Qman congestion
142830 + * groups. Is also used as a *mask* for congestion groups, eg. so we ignore
142831 + * those that don't concern us. We harness the structure and accessor details
142832 + * already used in the management command to query congestion groups. */
142833 +struct qman_cgrs {
142834 + struct __qm_mcr_querycongestion q;
142835 +};
142836 +static inline void qman_cgrs_init(struct qman_cgrs *c)
142837 +{
142838 + memset(c, 0, sizeof(*c));
142839 +}
142840 +static inline void qman_cgrs_fill(struct qman_cgrs *c)
142841 +{
142842 + memset(c, 0xff, sizeof(*c));
142843 +}
142844 +static inline int qman_cgrs_get(struct qman_cgrs *c, int num)
142845 +{
142846 + return QM_MCR_QUERYCONGESTION(&c->q, num);
142847 +}
142848 +static inline void qman_cgrs_set(struct qman_cgrs *c, int num)
142849 +{
142850 + c->q.__state[__CGR_WORD(num)] |= (0x80000000 >> __CGR_SHIFT(num));
142851 +}
142852 +static inline void qman_cgrs_unset(struct qman_cgrs *c, int num)
142853 +{
142854 + c->q.__state[__CGR_WORD(num)] &= ~(0x80000000 >> __CGR_SHIFT(num));
142855 +}
142856 +static inline int qman_cgrs_next(struct qman_cgrs *c, int num)
142857 +{
142858 + while ((++num < __CGR_NUM) && !qman_cgrs_get(c, num))
142859 + ;
142860 + return num;
142861 +}
142862 +static inline void qman_cgrs_cp(struct qman_cgrs *dest,
142863 + const struct qman_cgrs *src)
142864 +{
142865 + *dest = *src;
142866 +}
142867 +static inline void qman_cgrs_and(struct qman_cgrs *dest,
142868 + const struct qman_cgrs *a, const struct qman_cgrs *b)
142869 +{
142870 + int ret;
142871 + u32 *_d = dest->q.__state;
142872 + const u32 *_a = a->q.__state;
142873 + const u32 *_b = b->q.__state;
142874 + for (ret = 0; ret < 8; ret++)
142875 + *(_d++) = *(_a++) & *(_b++);
142876 +}
142877 +static inline void qman_cgrs_xor(struct qman_cgrs *dest,
142878 + const struct qman_cgrs *a, const struct qman_cgrs *b)
142879 +{
142880 + int ret;
142881 + u32 *_d = dest->q.__state;
142882 + const u32 *_a = a->q.__state;
142883 + const u32 *_b = b->q.__state;
142884 + for (ret = 0; ret < 8; ret++)
142885 + *(_d++) = *(_a++) ^ *(_b++);
142886 +}
142887 +
142888 + /* ----------------------- */
142889 + /* CEETM Congestion Groups */
142890 + /* ----------------------- */
142891 +/* This wrapper represents a bit-array for the state of the 512 Qman CEETM
142892 + * congestion groups.
142893 + */
142894 +struct qman_ccgrs {
142895 + struct __qm_mcr_querycongestion q[2];
142896 +};
142897 +static inline void qman_ccgrs_init(struct qman_ccgrs *c)
142898 +{
142899 + memset(c, 0, sizeof(*c));
142900 +}
142901 +static inline void qman_ccgrs_fill(struct qman_ccgrs *c)
142902 +{
142903 + memset(c, 0xff, sizeof(*c));
142904 +}
142905 +static inline int qman_ccgrs_get(struct qman_ccgrs *c, int num)
142906 +{
142907 + if (num < __CGR_NUM)
142908 + return QM_MCR_QUERYCONGESTION(&c->q[0], num);
142909 + else
142910 + return QM_MCR_QUERYCONGESTION(&c->q[1], (num - __CGR_NUM));
142911 +}
142912 +static inline int qman_ccgrs_next(struct qman_ccgrs *c, int num)
142913 +{
142914 + while ((++num < __CGR_NUM) && !qman_ccgrs_get(c, num))
142915 + ;
142916 + return num;
142917 +}
142918 +static inline void qman_ccgrs_cp(struct qman_ccgrs *dest,
142919 + const struct qman_ccgrs *src)
142920 +{
142921 + *dest = *src;
142922 +}
142923 +static inline void qman_ccgrs_and(struct qman_ccgrs *dest,
142924 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
142925 +{
142926 + int ret, i;
142927 + u32 *_d;
142928 + const u32 *_a, *_b;
142929 + for (i = 0; i < 2; i++) {
142930 + _d = dest->q[i].__state;
142931 + _a = a->q[i].__state;
142932 + _b = b->q[i].__state;
142933 + for (ret = 0; ret < 8; ret++)
142934 + *(_d++) = *(_a++) & *(_b++);
142935 + }
142936 +}
142937 +static inline void qman_ccgrs_xor(struct qman_ccgrs *dest,
142938 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
142939 +{
142940 + int ret, i;
142941 + u32 *_d;
142942 + const u32 *_a, *_b;
142943 + for (i = 0; i < 2; i++) {
142944 + _d = dest->q[i].__state;
142945 + _a = a->q[i].__state;
142946 + _b = b->q[i].__state;
142947 + for (ret = 0; ret < 8; ret++)
142948 + *(_d++) = *(_a++) ^ *(_b++);
142949 + }
142950 +}
142951 +
142952 +/* used by CCSR and portal interrupt code */
142953 +enum qm_isr_reg {
142954 + qm_isr_status = 0,
142955 + qm_isr_enable = 1,
142956 + qm_isr_disable = 2,
142957 + qm_isr_inhibit = 3
142958 +};
142959 +
142960 +struct qm_portal_config {
142961 + /* Corenet portal addresses;
142962 + * [0]==cache-enabled, [1]==cache-inhibited. */
142963 + __iomem void *addr_virt[2];
142964 + struct resource addr_phys[2];
142965 + struct device dev;
142966 + struct iommu_domain *iommu_domain;
142967 + /* Allow these to be joined in lists */
142968 + struct list_head list;
142969 + /* User-visible portal configuration settings */
142970 + struct qman_portal_config public_cfg;
142971 + /* power management saved data */
142972 + u32 saved_isdr;
142973 +};
142974 +
142975 +/* Revision info (for errata and feature handling) */
142976 +#define QMAN_REV11 0x0101
142977 +#define QMAN_REV12 0x0102
142978 +#define QMAN_REV20 0x0200
142979 +#define QMAN_REV30 0x0300
142980 +#define QMAN_REV31 0x0301
142981 +#define QMAN_REV32 0x0302
142982 +
142983 +/* QMan REV_2 register contains the Cfg option */
142984 +#define QMAN_REV_CFG_0 0x0
142985 +#define QMAN_REV_CFG_1 0x1
142986 +#define QMAN_REV_CFG_2 0x2
142987 +#define QMAN_REV_CFG_3 0x3
142988 +
142989 +extern u16 qman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
142990 +extern u8 qman_ip_cfg;
142991 +extern u32 qman_clk;
142992 +extern u16 qman_portal_max;
142993 +
142994 +#ifdef CONFIG_FSL_QMAN_CONFIG
142995 +/* Hooks from qman_driver.c to qman_config.c */
142996 +int qman_init_ccsr(struct device_node *node);
142997 +void qman_liodn_fixup(u16 channel);
142998 +int qman_set_sdest(u16 channel, unsigned int cpu_idx);
142999 +size_t get_qman_fqd_size(void);
143000 +#else
143001 +static inline size_t get_qman_fqd_size(void)
143002 +{
143003 + return (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ);
143004 +}
143005 +#endif
143006 +
143007 +int qm_set_wpm(int wpm);
143008 +int qm_get_wpm(int *wpm);
143009 +
143010 +/* Hooks from qman_driver.c in to qman_high.c */
143011 +struct qman_portal *qman_create_portal(
143012 + struct qman_portal *portal,
143013 + const struct qm_portal_config *config,
143014 + const struct qman_cgrs *cgrs);
143015 +
143016 +struct qman_portal *qman_create_affine_portal(
143017 + const struct qm_portal_config *config,
143018 + const struct qman_cgrs *cgrs);
143019 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
143020 + int cpu);
143021 +const struct qm_portal_config *qman_destroy_affine_portal(void);
143022 +void qman_destroy_portal(struct qman_portal *qm);
143023 +
143024 +/* Hooks from fsl_usdpaa.c to qman_driver.c */
143025 +struct qm_portal_config *qm_get_unused_portal(void);
143026 +struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx);
143027 +
143028 +void qm_put_unused_portal(struct qm_portal_config *pcfg);
143029 +void qm_set_liodns(struct qm_portal_config *pcfg);
143030 +
143031 +/* This CGR feature is supported by h/w and required by unit-tests and the
143032 + * debugfs hooks, so is implemented in the driver. However it allows an explicit
143033 + * corruption of h/w fields by s/w that are usually incorruptible (because the
143034 + * counters are usually maintained entirely within h/w). As such, we declare
143035 + * this API internally. */
143036 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
143037 + struct qm_mcr_cgrtestwrite *result);
143038 +
143039 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
143040 +/* If the fq object pointer is greater than the size of context_b field,
143041 + * than a lookup table is required. */
143042 +int qman_setup_fq_lookup_table(size_t num_entries);
143043 +#endif
143044 +
143045 +
143046 +/*************************************************/
143047 +/* QMan s/w corenet portal, low-level i/face */
143048 +/*************************************************/
143049 +
143050 +/* Note: most functions are only used by the high-level interface, so are
143051 + * inlined from qman_low.h. The stuff below is for use by other parts of the
143052 + * driver. */
143053 +
143054 +/* For qm_dqrr_sdqcr_set(); Choose one SOURCE. Choose one COUNT. Choose one
143055 + * dequeue TYPE. Choose TOKEN (8-bit).
143056 + * If SOURCE == CHANNELS,
143057 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL(n).
143058 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
143059 + * priority.
143060 + * If SOURCE == SPECIFICWQ,
143061 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
143062 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
143063 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
143064 + * same value.
143065 + */
143066 +#define QM_SDQCR_SOURCE_CHANNELS 0x0
143067 +#define QM_SDQCR_SOURCE_SPECIFICWQ 0x40000000
143068 +#define QM_SDQCR_COUNT_EXACT1 0x0
143069 +#define QM_SDQCR_COUNT_UPTO3 0x20000000
143070 +#define QM_SDQCR_DEDICATED_PRECEDENCE 0x10000000
143071 +#define QM_SDQCR_TYPE_MASK 0x03000000
143072 +#define QM_SDQCR_TYPE_NULL 0x0
143073 +#define QM_SDQCR_TYPE_PRIO_QOS 0x01000000
143074 +#define QM_SDQCR_TYPE_ACTIVE_QOS 0x02000000
143075 +#define QM_SDQCR_TYPE_ACTIVE 0x03000000
143076 +#define QM_SDQCR_TOKEN_MASK 0x00ff0000
143077 +#define QM_SDQCR_TOKEN_SET(v) (((v) & 0xff) << 16)
143078 +#define QM_SDQCR_TOKEN_GET(v) (((v) >> 16) & 0xff)
143079 +#define QM_SDQCR_CHANNELS_DEDICATED 0x00008000
143080 +#define QM_SDQCR_SPECIFICWQ_MASK 0x000000f7
143081 +#define QM_SDQCR_SPECIFICWQ_DEDICATED 0x00000000
143082 +#define QM_SDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
143083 +#define QM_SDQCR_SPECIFICWQ_WQ(n) (n)
143084 +
143085 +/* For qm_dqrr_vdqcr_set(): use FQID(n) to fill in the frame queue ID */
143086 +#define QM_VDQCR_FQID_MASK 0x00ffffff
143087 +#define QM_VDQCR_FQID(n) ((n) & QM_VDQCR_FQID_MASK)
143088 +
143089 +/* For qm_dqrr_pdqcr_set(); Choose one MODE. Choose one COUNT.
143090 + * If MODE==SCHEDULED
143091 + * Choose SCHEDULED_CHANNELS or SCHEDULED_SPECIFICWQ. Choose one dequeue TYPE.
143092 + * If CHANNELS,
143093 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL() channels.
143094 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
143095 + * priority.
143096 + * If SPECIFICWQ,
143097 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
143098 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
143099 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
143100 + * same value.
143101 + * If MODE==UNSCHEDULED
143102 + * Choose FQID().
143103 + */
143104 +#define QM_PDQCR_MODE_SCHEDULED 0x0
143105 +#define QM_PDQCR_MODE_UNSCHEDULED 0x80000000
143106 +#define QM_PDQCR_SCHEDULED_CHANNELS 0x0
143107 +#define QM_PDQCR_SCHEDULED_SPECIFICWQ 0x40000000
143108 +#define QM_PDQCR_COUNT_EXACT1 0x0
143109 +#define QM_PDQCR_COUNT_UPTO3 0x20000000
143110 +#define QM_PDQCR_DEDICATED_PRECEDENCE 0x10000000
143111 +#define QM_PDQCR_TYPE_MASK 0x03000000
143112 +#define QM_PDQCR_TYPE_NULL 0x0
143113 +#define QM_PDQCR_TYPE_PRIO_QOS 0x01000000
143114 +#define QM_PDQCR_TYPE_ACTIVE_QOS 0x02000000
143115 +#define QM_PDQCR_TYPE_ACTIVE 0x03000000
143116 +#define QM_PDQCR_CHANNELS_DEDICATED 0x00008000
143117 +#define QM_PDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
143118 +#define QM_PDQCR_SPECIFICWQ_MASK 0x000000f7
143119 +#define QM_PDQCR_SPECIFICWQ_DEDICATED 0x00000000
143120 +#define QM_PDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
143121 +#define QM_PDQCR_SPECIFICWQ_WQ(n) (n)
143122 +#define QM_PDQCR_FQID(n) ((n) & 0xffffff)
143123 +
143124 +/* Used by all portal interrupt registers except 'inhibit'
143125 + * Channels with frame availability
143126 + */
143127 +#define QM_PIRQ_DQAVAIL 0x0000ffff
143128 +
143129 +/* The DQAVAIL interrupt fields break down into these bits; */
143130 +#define QM_DQAVAIL_PORTAL 0x8000 /* Portal channel */
143131 +#define QM_DQAVAIL_POOL(n) (0x8000 >> (n)) /* Pool channel, n==[1..15] */
143132 +#define QM_DQAVAIL_MASK 0xffff
143133 +/* This mask contains all the "irqsource" bits visible to API users */
143134 +#define QM_PIRQ_VISIBLE (QM_PIRQ_SLOW | QM_PIRQ_DQRI)
143135 +
143136 +/* These are qm_<reg>_<verb>(). So for example, qm_disable_write() means "write
143137 + * the disable register" rather than "disable the ability to write". */
143138 +#define qm_isr_status_read(qm) __qm_isr_read(qm, qm_isr_status)
143139 +#define qm_isr_status_clear(qm, m) __qm_isr_write(qm, qm_isr_status, m)
143140 +#define qm_isr_enable_read(qm) __qm_isr_read(qm, qm_isr_enable)
143141 +#define qm_isr_enable_write(qm, v) __qm_isr_write(qm, qm_isr_enable, v)
143142 +#define qm_isr_disable_read(qm) __qm_isr_read(qm, qm_isr_disable)
143143 +#define qm_isr_disable_write(qm, v) __qm_isr_write(qm, qm_isr_disable, v)
143144 +/* TODO: unfortunate name-clash here, reword? */
143145 +#define qm_isr_inhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 1)
143146 +#define qm_isr_uninhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 0)
143147 +
143148 +#ifdef CONFIG_FSL_QMAN_CONFIG
143149 +int qman_have_ccsr(void);
143150 +#else
143151 +#define qman_have_ccsr 0
143152 +#endif
143153 +
143154 +__init int qman_init(void);
143155 +__init int qman_resource_init(void);
143156 +
143157 +/* CEETM related */
143158 +#define QMAN_CEETM_MAX 2
143159 +extern u8 num_ceetms;
143160 +extern struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
143161 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
143162 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
143163 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal);
143164 +int qman_ceetm_get_prescaler(u16 *pres);
143165 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
143166 + struct qm_mcr_ceetm_cq_query *cq_query);
143167 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
143168 + struct qm_mcr_ceetm_ccgr_query *response);
143169 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num);
143170 +
143171 +extern void *affine_portals[NR_CPUS];
143172 +const struct qm_portal_config *qman_get_qm_portal_config(
143173 + struct qman_portal *portal);
143174 +
143175 +/* power management */
143176 +#ifdef CONFIG_SUSPEND
143177 +void suspend_unused_qportal(void);
143178 +void resume_unused_qportal(void);
143179 +#endif
143180 --- /dev/null
143181 +++ b/drivers/staging/fsl_qbman/qman_test.c
143182 @@ -0,0 +1,57 @@
143183 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143184 + *
143185 + * Redistribution and use in source and binary forms, with or without
143186 + * modification, are permitted provided that the following conditions are met:
143187 + * * Redistributions of source code must retain the above copyright
143188 + * notice, this list of conditions and the following disclaimer.
143189 + * * Redistributions in binary form must reproduce the above copyright
143190 + * notice, this list of conditions and the following disclaimer in the
143191 + * documentation and/or other materials provided with the distribution.
143192 + * * Neither the name of Freescale Semiconductor nor the
143193 + * names of its contributors may be used to endorse or promote products
143194 + * derived from this software without specific prior written permission.
143195 + *
143196 + *
143197 + * ALTERNATIVELY, this software may be distributed under the terms of the
143198 + * GNU General Public License ("GPL") as published by the Free Software
143199 + * Foundation, either version 2 of that License or (at your option) any
143200 + * later version.
143201 + *
143202 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143203 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143204 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143205 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143206 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143207 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143208 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143209 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143210 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143211 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143212 + */
143213 +
143214 +#include "qman_test.h"
143215 +
143216 +MODULE_AUTHOR("Geoff Thorpe");
143217 +MODULE_LICENSE("Dual BSD/GPL");
143218 +MODULE_DESCRIPTION("Qman testing");
143219 +
143220 +static int test_init(void)
143221 +{
143222 + int loop = 1;
143223 + while (loop--) {
143224 +#ifdef CONFIG_FSL_QMAN_TEST_STASH_POTATO
143225 + qman_test_hotpotato();
143226 +#endif
143227 +#ifdef CONFIG_FSL_QMAN_TEST_HIGH
143228 + qman_test_high();
143229 +#endif
143230 + }
143231 + return 0;
143232 +}
143233 +
143234 +static void test_exit(void)
143235 +{
143236 +}
143237 +
143238 +module_init(test_init);
143239 +module_exit(test_exit);
143240 --- /dev/null
143241 +++ b/drivers/staging/fsl_qbman/qman_test.h
143242 @@ -0,0 +1,45 @@
143243 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143244 + *
143245 + * Redistribution and use in source and binary forms, with or without
143246 + * modification, are permitted provided that the following conditions are met:
143247 + * * Redistributions of source code must retain the above copyright
143248 + * notice, this list of conditions and the following disclaimer.
143249 + * * Redistributions in binary form must reproduce the above copyright
143250 + * notice, this list of conditions and the following disclaimer in the
143251 + * documentation and/or other materials provided with the distribution.
143252 + * * Neither the name of Freescale Semiconductor nor the
143253 + * names of its contributors may be used to endorse or promote products
143254 + * derived from this software without specific prior written permission.
143255 + *
143256 + *
143257 + * ALTERNATIVELY, this software may be distributed under the terms of the
143258 + * GNU General Public License ("GPL") as published by the Free Software
143259 + * Foundation, either version 2 of that License or (at your option) any
143260 + * later version.
143261 + *
143262 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143263 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143264 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143265 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143266 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143267 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143268 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143269 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143270 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143271 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143272 + */
143273 +
143274 +#include <linux/kernel.h>
143275 +#include <linux/errno.h>
143276 +#include <linux/io.h>
143277 +#include <linux/slab.h>
143278 +#include <linux/module.h>
143279 +#include <linux/interrupt.h>
143280 +#include <linux/delay.h>
143281 +#include <linux/sched.h>
143282 +
143283 +#include <linux/fsl_qman.h>
143284 +
143285 +void qman_test_hotpotato(void);
143286 +void qman_test_high(void);
143287 +
143288 --- /dev/null
143289 +++ b/drivers/staging/fsl_qbman/qman_test_high.c
143290 @@ -0,0 +1,216 @@
143291 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143292 + *
143293 + * Redistribution and use in source and binary forms, with or without
143294 + * modification, are permitted provided that the following conditions are met:
143295 + * * Redistributions of source code must retain the above copyright
143296 + * notice, this list of conditions and the following disclaimer.
143297 + * * Redistributions in binary form must reproduce the above copyright
143298 + * notice, this list of conditions and the following disclaimer in the
143299 + * documentation and/or other materials provided with the distribution.
143300 + * * Neither the name of Freescale Semiconductor nor the
143301 + * names of its contributors may be used to endorse or promote products
143302 + * derived from this software without specific prior written permission.
143303 + *
143304 + *
143305 + * ALTERNATIVELY, this software may be distributed under the terms of the
143306 + * GNU General Public License ("GPL") as published by the Free Software
143307 + * Foundation, either version 2 of that License or (at your option) any
143308 + * later version.
143309 + *
143310 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143311 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143312 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143313 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143314 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143315 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143316 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143317 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143318 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143319 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143320 + */
143321 +
143322 +#include "qman_test.h"
143323 +
143324 +/*************/
143325 +/* constants */
143326 +/*************/
143327 +
143328 +#define CGR_ID 27
143329 +#define POOL_ID 2
143330 +#define FQ_FLAGS QMAN_FQ_FLAG_DYNAMIC_FQID
143331 +#define NUM_ENQUEUES 10
143332 +#define NUM_PARTIAL 4
143333 +#define PORTAL_SDQCR (QM_SDQCR_SOURCE_CHANNELS | \
143334 + QM_SDQCR_TYPE_PRIO_QOS | \
143335 + QM_SDQCR_TOKEN_SET(0x98) | \
143336 + QM_SDQCR_CHANNELS_DEDICATED | \
143337 + QM_SDQCR_CHANNELS_POOL(POOL_ID))
143338 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
143339 +#define VDQCR_FLAGS (QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH)
143340 +
143341 +/*************************************/
143342 +/* Predeclarations (eg. for fq_base) */
143343 +/*************************************/
143344 +
143345 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *,
143346 + struct qman_fq *,
143347 + const struct qm_dqrr_entry *);
143348 +static void cb_ern(struct qman_portal *, struct qman_fq *,
143349 + const struct qm_mr_entry *);
143350 +static void cb_fqs(struct qman_portal *, struct qman_fq *,
143351 + const struct qm_mr_entry *);
143352 +
143353 +/***************/
143354 +/* global vars */
143355 +/***************/
143356 +
143357 +static struct qm_fd fd, fd_dq;
143358 +static struct qman_fq fq_base = {
143359 + .cb.dqrr = cb_dqrr,
143360 + .cb.ern = cb_ern,
143361 + .cb.fqs = cb_fqs
143362 +};
143363 +static DECLARE_WAIT_QUEUE_HEAD(waitqueue);
143364 +static int retire_complete, sdqcr_complete;
143365 +
143366 +/**********************/
143367 +/* internal functions */
143368 +/**********************/
143369 +
143370 +/* Helpers for initialising and "incrementing" a frame descriptor */
143371 +static void fd_init(struct qm_fd *__fd)
143372 +{
143373 + qm_fd_addr_set64(__fd, 0xabdeadbeefLLU);
143374 + __fd->format = qm_fd_contig_big;
143375 + __fd->length29 = 0x0000ffff;
143376 + __fd->cmd = 0xfeedf00d;
143377 +}
143378 +
143379 +static void fd_inc(struct qm_fd *__fd)
143380 +{
143381 + u64 t = qm_fd_addr_get64(__fd);
143382 + int z = t >> 40;
143383 + t <<= 1;
143384 + if (z)
143385 + t |= 1;
143386 + qm_fd_addr_set64(__fd, t);
143387 + __fd->length29--;
143388 + __fd->cmd++;
143389 +}
143390 +
143391 +/* The only part of the 'fd' we can't memcmp() is the ppid */
143392 +static int fd_cmp(const struct qm_fd *a, const struct qm_fd *b)
143393 +{
143394 + int r = (qm_fd_addr_get64(a) == qm_fd_addr_get64(b)) ? 0 : -1;
143395 + if (!r)
143396 + r = a->format - b->format;
143397 + if (!r)
143398 + r = a->opaque - b->opaque;
143399 + if (!r)
143400 + r = a->cmd - b->cmd;
143401 + return r;
143402 +}
143403 +
143404 +/********/
143405 +/* test */
143406 +/********/
143407 +
143408 +static void do_enqueues(struct qman_fq *fq)
143409 +{
143410 + unsigned int loop;
143411 + for (loop = 0; loop < NUM_ENQUEUES; loop++) {
143412 + if (qman_enqueue(fq, &fd, QMAN_ENQUEUE_FLAG_WAIT |
143413 + (((loop + 1) == NUM_ENQUEUES) ?
143414 + QMAN_ENQUEUE_FLAG_WAIT_SYNC : 0)))
143415 + panic("qman_enqueue() failed\n");
143416 + fd_inc(&fd);
143417 + }
143418 +}
143419 +
143420 +void qman_test_high(void)
143421 +{
143422 + unsigned int flags;
143423 + int res;
143424 + struct qman_fq *fq = &fq_base;
143425 +
143426 + pr_info("qman_test_high starting\n");
143427 + fd_init(&fd);
143428 + fd_init(&fd_dq);
143429 +
143430 + /* Initialise (parked) FQ */
143431 + if (qman_create_fq(0, FQ_FLAGS, fq))
143432 + panic("qman_create_fq() failed\n");
143433 + if (qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, NULL))
143434 + panic("qman_init_fq() failed\n");
143435 +
143436 + /* Do enqueues + VDQCR, twice. (Parked FQ) */
143437 + do_enqueues(fq);
143438 + pr_info("VDQCR (till-empty);\n");
143439 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143440 + QM_VDQCR_NUMFRAMES_TILLEMPTY))
143441 + panic("qman_volatile_dequeue() failed\n");
143442 + do_enqueues(fq);
143443 + pr_info("VDQCR (%d of %d);\n", NUM_PARTIAL, NUM_ENQUEUES);
143444 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143445 + QM_VDQCR_NUMFRAMES_SET(NUM_PARTIAL)))
143446 + panic("qman_volatile_dequeue() failed\n");
143447 + pr_info("VDQCR (%d of %d);\n", NUM_ENQUEUES - NUM_PARTIAL,
143448 + NUM_ENQUEUES);
143449 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143450 + QM_VDQCR_NUMFRAMES_SET(NUM_ENQUEUES - NUM_PARTIAL)))
143451 + panic("qman_volatile_dequeue() failed\n");
143452 +
143453 + do_enqueues(fq);
143454 + pr_info("scheduled dequeue (till-empty)\n");
143455 + if (qman_schedule_fq(fq))
143456 + panic("qman_schedule_fq() failed\n");
143457 + wait_event(waitqueue, sdqcr_complete);
143458 +
143459 + /* Retire and OOS the FQ */
143460 + res = qman_retire_fq(fq, &flags);
143461 + if (res < 0)
143462 + panic("qman_retire_fq() failed\n");
143463 + wait_event(waitqueue, retire_complete);
143464 + if (flags & QMAN_FQ_STATE_BLOCKOOS)
143465 + panic("leaking frames\n");
143466 + if (qman_oos_fq(fq))
143467 + panic("qman_oos_fq() failed\n");
143468 + qman_destroy_fq(fq, 0);
143469 + pr_info("qman_test_high finished\n");
143470 +}
143471 +
143472 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p,
143473 + struct qman_fq *fq,
143474 + const struct qm_dqrr_entry *dq)
143475 +{
143476 + if (fd_cmp(&fd_dq, &dq->fd)) {
143477 + pr_err("BADNESS: dequeued frame doesn't match;\n");
143478 + pr_err("Expected 0x%llx, got 0x%llx\n",
143479 + (unsigned long long)fd_dq.length29,
143480 + (unsigned long long)dq->fd.length29);
143481 + BUG();
143482 + }
143483 + fd_inc(&fd_dq);
143484 + if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_cmp(&fd_dq, &fd)) {
143485 + sdqcr_complete = 1;
143486 + wake_up(&waitqueue);
143487 + }
143488 + return qman_cb_dqrr_consume;
143489 +}
143490 +
143491 +static void cb_ern(struct qman_portal *p, struct qman_fq *fq,
143492 + const struct qm_mr_entry *msg)
143493 +{
143494 + panic("cb_ern() unimplemented");
143495 +}
143496 +
143497 +static void cb_fqs(struct qman_portal *p, struct qman_fq *fq,
143498 + const struct qm_mr_entry *msg)
143499 +{
143500 + u8 verb = (msg->verb & QM_MR_VERB_TYPE_MASK);
143501 + if ((verb != QM_MR_VERB_FQRN) && (verb != QM_MR_VERB_FQRNI))
143502 + panic("unexpected FQS message");
143503 + pr_info("Retirement message received\n");
143504 + retire_complete = 1;
143505 + wake_up(&waitqueue);
143506 +}
143507 --- /dev/null
143508 +++ b/drivers/staging/fsl_qbman/qman_test_hotpotato.c
143509 @@ -0,0 +1,502 @@
143510 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
143511 + *
143512 + * Redistribution and use in source and binary forms, with or without
143513 + * modification, are permitted provided that the following conditions are met:
143514 + * * Redistributions of source code must retain the above copyright
143515 + * notice, this list of conditions and the following disclaimer.
143516 + * * Redistributions in binary form must reproduce the above copyright
143517 + * notice, this list of conditions and the following disclaimer in the
143518 + * documentation and/or other materials provided with the distribution.
143519 + * * Neither the name of Freescale Semiconductor nor the
143520 + * names of its contributors may be used to endorse or promote products
143521 + * derived from this software without specific prior written permission.
143522 + *
143523 + *
143524 + * ALTERNATIVELY, this software may be distributed under the terms of the
143525 + * GNU General Public License ("GPL") as published by the Free Software
143526 + * Foundation, either version 2 of that License or (at your option) any
143527 + * later version.
143528 + *
143529 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143530 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143531 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143532 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143533 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143534 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143535 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143536 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143537 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143538 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143539 + */
143540 +
143541 +#include <linux/kthread.h>
143542 +#include <linux/platform_device.h>
143543 +#include <linux/dma-mapping.h>
143544 +#include "qman_test.h"
143545 +
143546 +/* Algorithm:
143547 + *
143548 + * Each cpu will have HP_PER_CPU "handlers" set up, each of which incorporates
143549 + * an rx/tx pair of FQ objects (both of which are stashed on dequeue). The
143550 + * organisation of FQIDs is such that the HP_PER_CPU*NUM_CPUS handlers will
143551 + * shuttle a "hot potato" frame around them such that every forwarding action
143552 + * moves it from one cpu to another. (The use of more than one handler per cpu
143553 + * is to allow enough handlers/FQs to truly test the significance of caching -
143554 + * ie. when cache-expiries are occurring.)
143555 + *
143556 + * The "hot potato" frame content will be HP_NUM_WORDS*4 bytes in size, and the
143557 + * first and last words of the frame data will undergo a transformation step on
143558 + * each forwarding action. To achieve this, each handler will be assigned a
143559 + * 32-bit "mixer", that is produced using a 32-bit LFSR. When a frame is
143560 + * received by a handler, the mixer of the expected sender is XOR'd into all
143561 + * words of the entire frame, which is then validated against the original
143562 + * values. Then, before forwarding, the entire frame is XOR'd with the mixer of
143563 + * the current handler. Apart from validating that the frame is taking the
143564 + * expected path, this also provides some quasi-realistic overheads to each
143565 + * forwarding action - dereferencing *all* the frame data, computation, and
143566 + * conditional branching. There is a "special" handler designated to act as the
143567 + * instigator of the test by creating an enqueuing the "hot potato" frame, and
143568 + * to determine when the test has completed by counting HP_LOOPS iterations.
143569 + *
143570 + * Init phases:
143571 + *
143572 + * 1. prepare each cpu's 'hp_cpu' struct using on_each_cpu(,,1) and link them
143573 + * into 'hp_cpu_list'. Specifically, set processor_id, allocate HP_PER_CPU
143574 + * handlers and link-list them (but do no other handler setup).
143575 + *
143576 + * 2. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
143577 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
143578 + * allocate rx/tx FQIDs and mixer values to the hp_cpu's iterator handler
143579 + * and advance the iterator for the next loop. This includes a final fixup,
143580 + * which connects the last handler to the first (and which is why phase 2
143581 + * and 3 are separate).
143582 + *
143583 + * 3. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
143584 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
143585 + * initialise FQ objects and advance the iterator for the next loop.
143586 + * Moreover, do this initialisation on the cpu it applies to so that Rx FQ
143587 + * initialisation targets the correct cpu.
143588 + */
143589 +
143590 +/* helper to run something on all cpus (can't use on_each_cpu(), as that invokes
143591 + * the fn from irq context, which is too restrictive). */
143592 +struct bstrap {
143593 + void (*fn)(void);
143594 + atomic_t started;
143595 +};
143596 +static int bstrap_fn(void *__bstrap)
143597 +{
143598 + struct bstrap *bstrap = __bstrap;
143599 + atomic_inc(&bstrap->started);
143600 + bstrap->fn();
143601 + while (!kthread_should_stop())
143602 + msleep(1);
143603 + return 0;
143604 +}
143605 +static int on_all_cpus(void (*fn)(void))
143606 +{
143607 + int cpu;
143608 + for_each_cpu(cpu, cpu_online_mask) {
143609 + struct bstrap bstrap = {
143610 + .fn = fn,
143611 + .started = ATOMIC_INIT(0)
143612 + };
143613 + struct task_struct *k = kthread_create(bstrap_fn, &bstrap,
143614 + "hotpotato%d", cpu);
143615 + int ret;
143616 + if (IS_ERR(k))
143617 + return -ENOMEM;
143618 + kthread_bind(k, cpu);
143619 + wake_up_process(k);
143620 + /* If we call kthread_stop() before the "wake up" has had an
143621 + * effect, then the thread may exit with -EINTR without ever
143622 + * running the function. So poll until it's started before
143623 + * requesting it to stop. */
143624 + while (!atomic_read(&bstrap.started))
143625 + msleep(10);
143626 + ret = kthread_stop(k);
143627 + if (ret)
143628 + return ret;
143629 + }
143630 + return 0;
143631 +}
143632 +
143633 +struct hp_handler {
143634 +
143635 + /* The following data is stashed when 'rx' is dequeued; */
143636 + /* -------------- */
143637 + /* The Rx FQ, dequeues of which will stash the entire hp_handler */
143638 + struct qman_fq rx;
143639 + /* The Tx FQ we should forward to */
143640 + struct qman_fq tx;
143641 + /* The value we XOR post-dequeue, prior to validating */
143642 + u32 rx_mixer;
143643 + /* The value we XOR pre-enqueue, after validating */
143644 + u32 tx_mixer;
143645 + /* what the hotpotato address should be on dequeue */
143646 + dma_addr_t addr;
143647 + u32 *frame_ptr;
143648 +
143649 + /* The following data isn't (necessarily) stashed on dequeue; */
143650 + /* -------------- */
143651 + u32 fqid_rx, fqid_tx;
143652 + /* list node for linking us into 'hp_cpu' */
143653 + struct list_head node;
143654 + /* Just to check ... */
143655 + unsigned int processor_id;
143656 +} ____cacheline_aligned;
143657 +
143658 +struct hp_cpu {
143659 + /* identify the cpu we run on; */
143660 + unsigned int processor_id;
143661 + /* root node for the per-cpu list of handlers */
143662 + struct list_head handlers;
143663 + /* list node for linking us into 'hp_cpu_list' */
143664 + struct list_head node;
143665 + /* when repeatedly scanning 'hp_list', each time linking the n'th
143666 + * handlers together, this is used as per-cpu iterator state */
143667 + struct hp_handler *iterator;
143668 +};
143669 +
143670 +/* Each cpu has one of these */
143671 +static DEFINE_PER_CPU(struct hp_cpu, hp_cpus);
143672 +
143673 +/* links together the hp_cpu structs, in first-come first-serve order. */
143674 +static LIST_HEAD(hp_cpu_list);
143675 +static spinlock_t hp_lock = __SPIN_LOCK_UNLOCKED(hp_lock);
143676 +
143677 +static unsigned int hp_cpu_list_length;
143678 +
143679 +/* the "special" handler, that starts and terminates the test. */
143680 +static struct hp_handler *special_handler;
143681 +static int loop_counter;
143682 +
143683 +/* handlers are allocated out of this, so they're properly aligned. */
143684 +static struct kmem_cache *hp_handler_slab;
143685 +
143686 +/* this is the frame data */
143687 +static void *__frame_ptr;
143688 +static u32 *frame_ptr;
143689 +static dma_addr_t frame_dma;
143690 +
143691 +/* the main function waits on this */
143692 +static DECLARE_WAIT_QUEUE_HEAD(queue);
143693 +
143694 +#define HP_PER_CPU 2
143695 +#define HP_LOOPS 8
143696 +/* 80 bytes, like a small ethernet frame, and bleeds into a second cacheline */
143697 +#define HP_NUM_WORDS 80
143698 +/* First word of the LFSR-based frame data */
143699 +#define HP_FIRST_WORD 0xabbaf00d
143700 +
143701 +static inline u32 do_lfsr(u32 prev)
143702 +{
143703 + return (prev >> 1) ^ (-(prev & 1u) & 0xd0000001u);
143704 +}
143705 +
143706 +static void allocate_frame_data(void)
143707 +{
143708 + u32 lfsr = HP_FIRST_WORD;
143709 + int loop;
143710 + struct platform_device *pdev = platform_device_alloc("foobar", -1);
143711 + if (!pdev)
143712 + panic("platform_device_alloc() failed");
143713 + if (platform_device_add(pdev))
143714 + panic("platform_device_add() failed");
143715 + __frame_ptr = kmalloc(4 * HP_NUM_WORDS, GFP_KERNEL);
143716 + if (!__frame_ptr)
143717 + panic("kmalloc() failed");
143718 + frame_ptr = (void *)(((unsigned long)__frame_ptr + 63) &
143719 + ~(unsigned long)63);
143720 + for (loop = 0; loop < HP_NUM_WORDS; loop++) {
143721 + frame_ptr[loop] = lfsr;
143722 + lfsr = do_lfsr(lfsr);
143723 + }
143724 + frame_dma = dma_map_single(&pdev->dev, frame_ptr, 4 * HP_NUM_WORDS,
143725 + DMA_BIDIRECTIONAL);
143726 + platform_device_del(pdev);
143727 + platform_device_put(pdev);
143728 +}
143729 +
143730 +static void deallocate_frame_data(void)
143731 +{
143732 + kfree(__frame_ptr);
143733 +}
143734 +
143735 +static inline void process_frame_data(struct hp_handler *handler,
143736 + const struct qm_fd *fd)
143737 +{
143738 + u32 *p = handler->frame_ptr;
143739 + u32 lfsr = HP_FIRST_WORD;
143740 + int loop;
143741 + if (qm_fd_addr_get64(fd) != (handler->addr & 0xffffffffff)) {
143742 + pr_err("Got 0x%llx expected 0x%llx\n",
143743 + qm_fd_addr_get64(fd), handler->addr);
143744 + panic("bad frame address");
143745 + }
143746 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
143747 + *p ^= handler->rx_mixer;
143748 + if (*p != lfsr)
143749 + panic("corrupt frame data");
143750 + *p ^= handler->tx_mixer;
143751 + lfsr = do_lfsr(lfsr);
143752 + }
143753 +}
143754 +
143755 +static enum qman_cb_dqrr_result normal_dqrr(struct qman_portal *portal,
143756 + struct qman_fq *fq,
143757 + const struct qm_dqrr_entry *dqrr)
143758 +{
143759 + struct hp_handler *handler = (struct hp_handler *)fq;
143760 +
143761 + process_frame_data(handler, &dqrr->fd);
143762 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
143763 + panic("qman_enqueue() failed");
143764 + return qman_cb_dqrr_consume;
143765 +}
143766 +
143767 +static enum qman_cb_dqrr_result special_dqrr(struct qman_portal *portal,
143768 + struct qman_fq *fq,
143769 + const struct qm_dqrr_entry *dqrr)
143770 +{
143771 + struct hp_handler *handler = (struct hp_handler *)fq;
143772 +
143773 + process_frame_data(handler, &dqrr->fd);
143774 + if (++loop_counter < HP_LOOPS) {
143775 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
143776 + panic("qman_enqueue() failed");
143777 + } else {
143778 + pr_info("Received final (%dth) frame\n", loop_counter);
143779 + wake_up(&queue);
143780 + }
143781 + return qman_cb_dqrr_consume;
143782 +}
143783 +
143784 +static void create_per_cpu_handlers(void)
143785 +{
143786 + struct hp_handler *handler;
143787 + int loop;
143788 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
143789 +
143790 + hp_cpu->processor_id = smp_processor_id();
143791 + spin_lock(&hp_lock);
143792 + list_add_tail(&hp_cpu->node, &hp_cpu_list);
143793 + hp_cpu_list_length++;
143794 + spin_unlock(&hp_lock);
143795 + INIT_LIST_HEAD(&hp_cpu->handlers);
143796 + for (loop = 0; loop < HP_PER_CPU; loop++) {
143797 + handler = kmem_cache_alloc(hp_handler_slab, GFP_KERNEL);
143798 + if (!handler)
143799 + panic("kmem_cache_alloc() failed");
143800 + handler->processor_id = hp_cpu->processor_id;
143801 + handler->addr = frame_dma;
143802 + handler->frame_ptr = frame_ptr;
143803 + list_add_tail(&handler->node, &hp_cpu->handlers);
143804 + }
143805 + put_cpu_var(hp_cpus);
143806 +}
143807 +
143808 +static void destroy_per_cpu_handlers(void)
143809 +{
143810 + struct list_head *loop, *tmp;
143811 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
143812 +
143813 + spin_lock(&hp_lock);
143814 + list_del(&hp_cpu->node);
143815 + spin_unlock(&hp_lock);
143816 + list_for_each_safe(loop, tmp, &hp_cpu->handlers) {
143817 + u32 flags;
143818 + struct hp_handler *handler = list_entry(loop, struct hp_handler,
143819 + node);
143820 + if (qman_retire_fq(&handler->rx, &flags))
143821 + panic("qman_retire_fq(rx) failed");
143822 + BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS);
143823 + if (qman_oos_fq(&handler->rx))
143824 + panic("qman_oos_fq(rx) failed");
143825 + qman_destroy_fq(&handler->rx, 0);
143826 + qman_destroy_fq(&handler->tx, 0);
143827 + qman_release_fqid(handler->fqid_rx);
143828 + list_del(&handler->node);
143829 + kmem_cache_free(hp_handler_slab, handler);
143830 + }
143831 + put_cpu_var(hp_cpus);
143832 +}
143833 +
143834 +static inline u8 num_cachelines(u32 offset)
143835 +{
143836 + u8 res = (offset + (L1_CACHE_BYTES - 1))
143837 + / (L1_CACHE_BYTES);
143838 + if (res > 3)
143839 + return 3;
143840 + return res;
143841 +}
143842 +#define STASH_DATA_CL \
143843 + num_cachelines(HP_NUM_WORDS * 4)
143844 +#define STASH_CTX_CL \
143845 + num_cachelines(offsetof(struct hp_handler, fqid_rx))
143846 +
143847 +static void init_handler(void *__handler)
143848 +{
143849 + struct qm_mcc_initfq opts;
143850 + struct hp_handler *handler = __handler;
143851 + BUG_ON(handler->processor_id != smp_processor_id());
143852 + /* Set up rx */
143853 + memset(&handler->rx, 0, sizeof(handler->rx));
143854 + if (handler == special_handler)
143855 + handler->rx.cb.dqrr = special_dqrr;
143856 + else
143857 + handler->rx.cb.dqrr = normal_dqrr;
143858 + if (qman_create_fq(handler->fqid_rx, 0, &handler->rx))
143859 + panic("qman_create_fq(rx) failed");
143860 + memset(&opts, 0, sizeof(opts));
143861 + opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_CONTEXTA;
143862 + opts.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING;
143863 + opts.fqd.context_a.stashing.data_cl = STASH_DATA_CL;
143864 + opts.fqd.context_a.stashing.context_cl = STASH_CTX_CL;
143865 + if (qman_init_fq(&handler->rx, QMAN_INITFQ_FLAG_SCHED |
143866 + QMAN_INITFQ_FLAG_LOCAL, &opts))
143867 + panic("qman_init_fq(rx) failed");
143868 + /* Set up tx */
143869 + memset(&handler->tx, 0, sizeof(handler->tx));
143870 + if (qman_create_fq(handler->fqid_tx, QMAN_FQ_FLAG_NO_MODIFY,
143871 + &handler->tx))
143872 + panic("qman_create_fq(tx) failed");
143873 +}
143874 +
143875 +static void init_phase2(void)
143876 +{
143877 + int loop;
143878 + u32 fqid = 0;
143879 + u32 lfsr = 0xdeadbeef;
143880 + struct hp_cpu *hp_cpu;
143881 + struct hp_handler *handler;
143882 +
143883 + for (loop = 0; loop < HP_PER_CPU; loop++) {
143884 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
143885 + int ret;
143886 + if (!loop)
143887 + hp_cpu->iterator = list_first_entry(
143888 + &hp_cpu->handlers,
143889 + struct hp_handler, node);
143890 + else
143891 + hp_cpu->iterator = list_entry(
143892 + hp_cpu->iterator->node.next,
143893 + struct hp_handler, node);
143894 + /* Rx FQID is the previous handler's Tx FQID */
143895 + hp_cpu->iterator->fqid_rx = fqid;
143896 + /* Allocate new FQID for Tx */
143897 + ret = qman_alloc_fqid(&fqid);
143898 + if (ret)
143899 + panic("qman_alloc_fqid() failed");
143900 + hp_cpu->iterator->fqid_tx = fqid;
143901 + /* Rx mixer is the previous handler's Tx mixer */
143902 + hp_cpu->iterator->rx_mixer = lfsr;
143903 + /* Get new mixer for Tx */
143904 + lfsr = do_lfsr(lfsr);
143905 + hp_cpu->iterator->tx_mixer = lfsr;
143906 + }
143907 + }
143908 + /* Fix up the first handler (fqid_rx==0, rx_mixer=0xdeadbeef) */
143909 + hp_cpu = list_first_entry(&hp_cpu_list, struct hp_cpu, node);
143910 + handler = list_first_entry(&hp_cpu->handlers, struct hp_handler, node);
143911 + BUG_ON((handler->fqid_rx != 0) || (handler->rx_mixer != 0xdeadbeef));
143912 + handler->fqid_rx = fqid;
143913 + handler->rx_mixer = lfsr;
143914 + /* and tag it as our "special" handler */
143915 + special_handler = handler;
143916 +}
143917 +
143918 +static void init_phase3(void)
143919 +{
143920 + int loop;
143921 + struct hp_cpu *hp_cpu;
143922 +
143923 + for (loop = 0; loop < HP_PER_CPU; loop++) {
143924 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
143925 + if (!loop)
143926 + hp_cpu->iterator = list_first_entry(
143927 + &hp_cpu->handlers,
143928 + struct hp_handler, node);
143929 + else
143930 + hp_cpu->iterator = list_entry(
143931 + hp_cpu->iterator->node.next,
143932 + struct hp_handler, node);
143933 + preempt_disable();
143934 + if (hp_cpu->processor_id == smp_processor_id())
143935 + init_handler(hp_cpu->iterator);
143936 + else
143937 + smp_call_function_single(hp_cpu->processor_id,
143938 + init_handler, hp_cpu->iterator, 1);
143939 + preempt_enable();
143940 + }
143941 + }
143942 +}
143943 +
143944 +static void send_first_frame(void *ignore)
143945 +{
143946 + u32 *p = special_handler->frame_ptr;
143947 + u32 lfsr = HP_FIRST_WORD;
143948 + int loop;
143949 + struct qm_fd fd;
143950 +
143951 + BUG_ON(special_handler->processor_id != smp_processor_id());
143952 + memset(&fd, 0, sizeof(fd));
143953 + qm_fd_addr_set64(&fd, special_handler->addr);
143954 + fd.format = qm_fd_contig_big;
143955 + fd.length29 = HP_NUM_WORDS * 4;
143956 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
143957 + if (*p != lfsr)
143958 + panic("corrupt frame data");
143959 + *p ^= special_handler->tx_mixer;
143960 + lfsr = do_lfsr(lfsr);
143961 + }
143962 + pr_info("Sending first frame\n");
143963 + if (qman_enqueue(&special_handler->tx, &fd, 0))
143964 + panic("qman_enqueue() failed");
143965 +}
143966 +
143967 +void qman_test_hotpotato(void)
143968 +{
143969 + if (cpumask_weight(cpu_online_mask) < 2) {
143970 + pr_info("qman_test_hotpotato, skip - only 1 CPU\n");
143971 + return;
143972 + }
143973 +
143974 + pr_info("qman_test_hotpotato starting\n");
143975 +
143976 + hp_cpu_list_length = 0;
143977 + loop_counter = 0;
143978 + hp_handler_slab = kmem_cache_create("hp_handler_slab",
143979 + sizeof(struct hp_handler), L1_CACHE_BYTES,
143980 + SLAB_HWCACHE_ALIGN, NULL);
143981 + if (!hp_handler_slab)
143982 + panic("kmem_cache_create() failed");
143983 +
143984 + allocate_frame_data();
143985 +
143986 + /* Init phase 1 */
143987 + pr_info("Creating %d handlers per cpu...\n", HP_PER_CPU);
143988 + if (on_all_cpus(create_per_cpu_handlers))
143989 + panic("on_each_cpu() failed");
143990 + pr_info("Number of cpus: %d, total of %d handlers\n",
143991 + hp_cpu_list_length, hp_cpu_list_length * HP_PER_CPU);
143992 +
143993 + init_phase2();
143994 +
143995 + init_phase3();
143996 +
143997 + preempt_disable();
143998 + if (special_handler->processor_id == smp_processor_id())
143999 + send_first_frame(NULL);
144000 + else
144001 + smp_call_function_single(special_handler->processor_id,
144002 + send_first_frame, NULL, 1);
144003 + preempt_enable();
144004 +
144005 + wait_event(queue, loop_counter == HP_LOOPS);
144006 + deallocate_frame_data();
144007 + if (on_all_cpus(destroy_per_cpu_handlers))
144008 + panic("on_each_cpu() failed");
144009 + kmem_cache_destroy(hp_handler_slab);
144010 + pr_info("qman_test_hotpotato finished\n");
144011 +}
144012 --- /dev/null
144013 +++ b/drivers/staging/fsl_qbman/qman_utility.c
144014 @@ -0,0 +1,129 @@
144015 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
144016 + *
144017 + * Redistribution and use in source and binary forms, with or without
144018 + * modification, are permitted provided that the following conditions are met:
144019 + * * Redistributions of source code must retain the above copyright
144020 + * notice, this list of conditions and the following disclaimer.
144021 + * * Redistributions in binary form must reproduce the above copyright
144022 + * notice, this list of conditions and the following disclaimer in the
144023 + * documentation and/or other materials provided with the distribution.
144024 + * * Neither the name of Freescale Semiconductor nor the
144025 + * names of its contributors may be used to endorse or promote products
144026 + * derived from this software without specific prior written permission.
144027 + *
144028 + *
144029 + * ALTERNATIVELY, this software may be distributed under the terms of the
144030 + * GNU General Public License ("GPL") as published by the Free Software
144031 + * Foundation, either version 2 of that License or (at your option) any
144032 + * later version.
144033 + *
144034 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144035 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144036 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144037 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144038 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144039 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144040 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144041 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144042 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144043 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144044 + */
144045 +
144046 +#include "qman_private.h"
144047 +
144048 +/* ----------------- */
144049 +/* --- FQID Pool --- */
144050 +
144051 +struct qman_fqid_pool {
144052 + /* Base and size of the FQID range */
144053 + u32 fqid_base;
144054 + u32 total;
144055 + /* Number of FQIDs currently "allocated" */
144056 + u32 used;
144057 + /* Allocation optimisation. When 'used<total', it is the index of an
144058 + * available FQID. Otherwise there are no available FQIDs, and this
144059 + * will be set when the next deallocation occurs. */
144060 + u32 next;
144061 + /* A bit-field representation of the FQID range. */
144062 + unsigned long *bits;
144063 +};
144064 +
144065 +#define QLONG_BYTES sizeof(unsigned long)
144066 +#define QLONG_BITS (QLONG_BYTES * 8)
144067 +/* Number of 'longs' required for the given number of bits */
144068 +#define QNUM_LONGS(b) (((b) + QLONG_BITS - 1) / QLONG_BITS)
144069 +/* Shorthand for the number of bytes of same (kmalloc, memset, etc) */
144070 +#define QNUM_BYTES(b) (QNUM_LONGS(b) * QLONG_BYTES)
144071 +/* And in bits */
144072 +#define QNUM_BITS(b) (QNUM_LONGS(b) * QLONG_BITS)
144073 +
144074 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num)
144075 +{
144076 + struct qman_fqid_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL);
144077 + unsigned int i;
144078 +
144079 + BUG_ON(!num);
144080 + if (!pool)
144081 + return NULL;
144082 + pool->fqid_base = fqid_start;
144083 + pool->total = num;
144084 + pool->used = 0;
144085 + pool->next = 0;
144086 + pool->bits = kzalloc(QNUM_BYTES(num), GFP_KERNEL);
144087 + if (!pool->bits) {
144088 + kfree(pool);
144089 + return NULL;
144090 + }
144091 + /* If num is not an even multiple of QLONG_BITS (or even 8, for
144092 + * byte-oriented searching) then we fill the trailing bits with 1, to
144093 + * make them look allocated (permanently). */
144094 + for (i = num + 1; i < QNUM_BITS(num); i++)
144095 + set_bit(i, pool->bits);
144096 + return pool;
144097 +}
144098 +EXPORT_SYMBOL(qman_fqid_pool_create);
144099 +
144100 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool)
144101 +{
144102 + int ret = pool->used;
144103 + kfree(pool->bits);
144104 + kfree(pool);
144105 + return ret;
144106 +}
144107 +EXPORT_SYMBOL(qman_fqid_pool_destroy);
144108 +
144109 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid)
144110 +{
144111 + int ret;
144112 + if (pool->used == pool->total)
144113 + return -ENOMEM;
144114 + *fqid = pool->fqid_base + pool->next;
144115 + ret = test_and_set_bit(pool->next, pool->bits);
144116 + BUG_ON(ret);
144117 + if (++pool->used == pool->total)
144118 + return 0;
144119 + pool->next = find_next_zero_bit(pool->bits, pool->total, pool->next);
144120 + if (pool->next >= pool->total)
144121 + pool->next = find_first_zero_bit(pool->bits, pool->total);
144122 + BUG_ON(pool->next >= pool->total);
144123 + return 0;
144124 +}
144125 +EXPORT_SYMBOL(qman_fqid_pool_alloc);
144126 +
144127 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid)
144128 +{
144129 + int ret;
144130 +
144131 + fqid -= pool->fqid_base;
144132 + ret = test_and_clear_bit(fqid, pool->bits);
144133 + BUG_ON(!ret);
144134 + if (pool->used-- == pool->total)
144135 + pool->next = fqid;
144136 +}
144137 +EXPORT_SYMBOL(qman_fqid_pool_free);
144138 +
144139 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool)
144140 +{
144141 + return pool->used;
144142 +}
144143 +EXPORT_SYMBOL(qman_fqid_pool_used);
144144 --- /dev/null
144145 +++ b/include/linux/fsl_bman.h
144146 @@ -0,0 +1,532 @@
144147 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
144148 + *
144149 + * Redistribution and use in source and binary forms, with or without
144150 + * modification, are permitted provided that the following conditions are met:
144151 + * * Redistributions of source code must retain the above copyright
144152 + * notice, this list of conditions and the following disclaimer.
144153 + * * Redistributions in binary form must reproduce the above copyright
144154 + * notice, this list of conditions and the following disclaimer in the
144155 + * documentation and/or other materials provided with the distribution.
144156 + * * Neither the name of Freescale Semiconductor nor the
144157 + * names of its contributors may be used to endorse or promote products
144158 + * derived from this software without specific prior written permission.
144159 + *
144160 + *
144161 + * ALTERNATIVELY, this software may be distributed under the terms of the
144162 + * GNU General Public License ("GPL") as published by the Free Software
144163 + * Foundation, either version 2 of that License or (at your option) any
144164 + * later version.
144165 + *
144166 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144167 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144168 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144169 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144170 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144171 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144172 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144173 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144174 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144175 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144176 + */
144177 +
144178 +#ifndef FSL_BMAN_H
144179 +#define FSL_BMAN_H
144180 +
144181 +#ifdef __cplusplus
144182 +extern "C" {
144183 +#endif
144184 +
144185 +/* Last updated for v00.79 of the BG */
144186 +
144187 +/* Portal processing (interrupt) sources */
144188 +#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */
144189 +#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */
144190 +
144191 +/* This wrapper represents a bit-array for the depletion state of the 64 Bman
144192 + * buffer pools. */
144193 +struct bman_depletion {
144194 + u32 __state[2];
144195 +};
144196 +#define BMAN_DEPLETION_EMPTY { { 0x00000000, 0x00000000 } }
144197 +#define BMAN_DEPLETION_FULL { { 0xffffffff, 0xffffffff } }
144198 +#define __bmdep_word(x) ((x) >> 5)
144199 +#define __bmdep_shift(x) ((x) & 0x1f)
144200 +#define __bmdep_bit(x) (0x80000000 >> __bmdep_shift(x))
144201 +static inline void bman_depletion_init(struct bman_depletion *c)
144202 +{
144203 + c->__state[0] = c->__state[1] = 0;
144204 +}
144205 +static inline void bman_depletion_fill(struct bman_depletion *c)
144206 +{
144207 + c->__state[0] = c->__state[1] = ~0;
144208 +}
144209 +static inline int bman_depletion_get(const struct bman_depletion *c, u8 bpid)
144210 +{
144211 + return c->__state[__bmdep_word(bpid)] & __bmdep_bit(bpid);
144212 +}
144213 +static inline void bman_depletion_set(struct bman_depletion *c, u8 bpid)
144214 +{
144215 + c->__state[__bmdep_word(bpid)] |= __bmdep_bit(bpid);
144216 +}
144217 +static inline void bman_depletion_unset(struct bman_depletion *c, u8 bpid)
144218 +{
144219 + c->__state[__bmdep_word(bpid)] &= ~__bmdep_bit(bpid);
144220 +}
144221 +
144222 +/* ------------------------------------------------------- */
144223 +/* --- Bman data structures (and associated constants) --- */
144224 +
144225 +/* Represents s/w corenet portal mapped data structures */
144226 +struct bm_rcr_entry; /* RCR (Release Command Ring) entries */
144227 +struct bm_mc_command; /* MC (Management Command) command */
144228 +struct bm_mc_result; /* MC result */
144229 +
144230 +/* Code-reduction, define a wrapper for 48-bit buffers. In cases where a buffer
144231 + * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
144232 + * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used. */
144233 +struct bm_buffer {
144234 + union {
144235 + struct {
144236 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144237 + u8 __reserved1;
144238 + u8 bpid;
144239 + u16 hi; /* High 16-bits of 48-bit address */
144240 + u32 lo; /* Low 32-bits of 48-bit address */
144241 +#else
144242 + u32 lo;
144243 + u16 hi;
144244 + u8 bpid;
144245 + u8 __reserved;
144246 +#endif
144247 + };
144248 + struct {
144249 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144250 + u64 __notaddress:16;
144251 + u64 addr:48;
144252 +#else
144253 + u64 addr:48;
144254 + u64 __notaddress:16;
144255 +#endif
144256 + };
144257 + u64 opaque;
144258 + };
144259 +} __aligned(8);
144260 +static inline u64 bm_buffer_get64(const struct bm_buffer *buf)
144261 +{
144262 + return buf->addr;
144263 +}
144264 +static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
144265 +{
144266 + return (dma_addr_t)buf->addr;
144267 +}
144268 +/* Macro, so we compile better if 'v' isn't always 64-bit */
144269 +#define bm_buffer_set64(buf, v) \
144270 + do { \
144271 + struct bm_buffer *__buf931 = (buf); \
144272 + __buf931->hi = upper_32_bits(v); \
144273 + __buf931->lo = lower_32_bits(v); \
144274 + } while (0)
144275 +
144276 +/* See 1.5.3.5.4: "Release Command" */
144277 +struct bm_rcr_entry {
144278 + union {
144279 + struct {
144280 + u8 __dont_write_directly__verb;
144281 + u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */
144282 + u8 __reserved1[62];
144283 + };
144284 + struct bm_buffer bufs[8];
144285 + };
144286 +} __packed;
144287 +#define BM_RCR_VERB_VBIT 0x80
144288 +#define BM_RCR_VERB_CMD_MASK 0x70 /* one of two values; */
144289 +#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20
144290 +#define BM_RCR_VERB_CMD_BPID_MULTI 0x30
144291 +#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f /* values 1..8 */
144292 +
144293 +/* See 1.5.3.1: "Acquire Command" */
144294 +/* See 1.5.3.2: "Query Command" */
144295 +struct bm_mcc_acquire {
144296 + u8 bpid;
144297 + u8 __reserved1[62];
144298 +} __packed;
144299 +struct bm_mcc_query {
144300 + u8 __reserved2[63];
144301 +} __packed;
144302 +struct bm_mc_command {
144303 + u8 __dont_write_directly__verb;
144304 + union {
144305 + struct bm_mcc_acquire acquire;
144306 + struct bm_mcc_query query;
144307 + };
144308 +} __packed;
144309 +#define BM_MCC_VERB_VBIT 0x80
144310 +#define BM_MCC_VERB_CMD_MASK 0x70 /* where the verb contains; */
144311 +#define BM_MCC_VERB_CMD_ACQUIRE 0x10
144312 +#define BM_MCC_VERB_CMD_QUERY 0x40
144313 +#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f /* values 1..8 go here */
144314 +
144315 +/* See 1.5.3.3: "Acquire Response" */
144316 +/* See 1.5.3.4: "Query Response" */
144317 +struct bm_pool_state {
144318 + u8 __reserved1[32];
144319 + /* "availability state" and "depletion state" */
144320 + struct {
144321 + u8 __reserved1[8];
144322 + /* Access using bman_depletion_***() */
144323 + struct bman_depletion state;
144324 + } as, ds;
144325 +};
144326 +struct bm_mc_result {
144327 + union {
144328 + struct {
144329 + u8 verb;
144330 + u8 __reserved1[63];
144331 + };
144332 + union {
144333 + struct {
144334 + u8 __reserved1;
144335 + u8 bpid;
144336 + u8 __reserved2[62];
144337 + };
144338 + struct bm_buffer bufs[8];
144339 + } acquire;
144340 + struct bm_pool_state query;
144341 + };
144342 +} __packed;
144343 +#define BM_MCR_VERB_VBIT 0x80
144344 +#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK
144345 +#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE
144346 +#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY
144347 +#define BM_MCR_VERB_CMD_ERR_INVALID 0x60
144348 +#define BM_MCR_VERB_CMD_ERR_ECC 0x70
144349 +#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */
144350 +/* Determine the "availability state" of pool 'p' from a query result 'r' */
144351 +#define BM_MCR_QUERY_AVAILABILITY(r, p) \
144352 + bman_depletion_get(&r->query.as.state, p)
144353 +/* Determine the "depletion state" of pool 'p' from a query result 'r' */
144354 +#define BM_MCR_QUERY_DEPLETION(r, p) \
144355 + bman_depletion_get(&r->query.ds.state, p)
144356 +
144357 +/*******************************************************************/
144358 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
144359 +/*******************************************************************/
144360 +
144361 + /* Portal and Buffer Pools */
144362 + /* ----------------------- */
144363 +/* Represents a managed portal */
144364 +struct bman_portal;
144365 +
144366 +/* This object type represents Bman buffer pools. */
144367 +struct bman_pool;
144368 +
144369 +struct bman_portal_config {
144370 + /* This is used for any "core-affine" portals, ie. default portals
144371 + * associated to the corresponding cpu. -1 implies that there is no core
144372 + * affinity configured. */
144373 + int cpu;
144374 + /* portal interrupt line */
144375 + int irq;
144376 + /* the unique index of this portal */
144377 + u32 index;
144378 + /* Is this portal shared? (If so, it has coarser locking and demuxes
144379 + * processing on behalf of other CPUs.) */
144380 + int is_shared;
144381 + /* These are the buffer pool IDs that may be used via this portal. */
144382 + struct bman_depletion mask;
144383 +};
144384 +
144385 +/* This callback type is used when handling pool depletion entry/exit. The
144386 + * 'cb_ctx' value is the opaque value associated with the pool object in
144387 + * bman_new_pool(). 'depleted' is non-zero on depletion-entry, and zero on
144388 + * depletion-exit. */
144389 +typedef void (*bman_cb_depletion)(struct bman_portal *bm,
144390 + struct bman_pool *pool, void *cb_ctx, int depleted);
144391 +
144392 +/* This struct specifies parameters for a bman_pool object. */
144393 +struct bman_pool_params {
144394 + /* index of the buffer pool to encapsulate (0-63), ignored if
144395 + * BMAN_POOL_FLAG_DYNAMIC_BPID is set. */
144396 + u32 bpid;
144397 + /* bit-mask of BMAN_POOL_FLAG_*** options */
144398 + u32 flags;
144399 + /* depletion-entry/exit callback, if BMAN_POOL_FLAG_DEPLETION is set */
144400 + bman_cb_depletion cb;
144401 + /* opaque user value passed as a parameter to 'cb' */
144402 + void *cb_ctx;
144403 + /* depletion-entry/exit thresholds, if BMAN_POOL_FLAG_THRESH is set. NB:
144404 + * this is only allowed if BMAN_POOL_FLAG_DYNAMIC_BPID is used *and*
144405 + * when run in the control plane (which controls Bman CCSR). This array
144406 + * matches the definition of bm_pool_set(). */
144407 + u32 thresholds[4];
144408 +};
144409 +
144410 +/* Flags to bman_new_pool() */
144411 +#define BMAN_POOL_FLAG_NO_RELEASE 0x00000001 /* can't release to pool */
144412 +#define BMAN_POOL_FLAG_ONLY_RELEASE 0x00000002 /* can only release to pool */
144413 +#define BMAN_POOL_FLAG_DEPLETION 0x00000004 /* track depletion entry/exit */
144414 +#define BMAN_POOL_FLAG_DYNAMIC_BPID 0x00000008 /* (de)allocate bpid */
144415 +#define BMAN_POOL_FLAG_THRESH 0x00000010 /* set depletion thresholds */
144416 +#define BMAN_POOL_FLAG_STOCKPILE 0x00000020 /* stockpile to reduce hw ops */
144417 +
144418 +/* Flags to bman_release() */
144419 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
144420 +#define BMAN_RELEASE_FLAG_WAIT 0x00000001 /* wait if RCR is full */
144421 +#define BMAN_RELEASE_FLAG_WAIT_INT 0x00000002 /* if we wait, interruptible? */
144422 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
144423 +#define BMAN_RELEASE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
144424 +#endif
144425 +#endif
144426 +#define BMAN_RELEASE_FLAG_NOW 0x00000008 /* issue immediate release */
144427 +
144428 +/* Flags to bman_acquire() */
144429 +#define BMAN_ACQUIRE_FLAG_STOCKPILE 0x00000001 /* no hw op, stockpile only */
144430 +
144431 + /* Portal Management */
144432 + /* ----------------- */
144433 +/**
144434 + * bman_get_portal_config - get portal configuration settings
144435 + *
144436 + * This returns a read-only view of the current cpu's affine portal settings.
144437 + */
144438 +const struct bman_portal_config *bman_get_portal_config(void);
144439 +
144440 +/**
144441 + * bman_irqsource_get - return the portal work that is interrupt-driven
144442 + *
144443 + * Returns a bitmask of BM_PIRQ_**I processing sources that are currently
144444 + * enabled for interrupt handling on the current cpu's affine portal. These
144445 + * sources will trigger the portal interrupt and the interrupt handler (or a
144446 + * tasklet/bottom-half it defers to) will perform the corresponding processing
144447 + * work. The bman_poll_***() functions will only process sources that are not in
144448 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
144449 + * this always returns zero.
144450 + */
144451 +u32 bman_irqsource_get(void);
144452 +
144453 +/**
144454 + * bman_irqsource_add - add processing sources to be interrupt-driven
144455 + * @bits: bitmask of BM_PIRQ_**I processing sources
144456 + *
144457 + * Adds processing sources that should be interrupt-driven (rather than
144458 + * processed via bman_poll_***() functions). Returns zero for success, or
144459 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
144460 +int bman_irqsource_add(u32 bits);
144461 +
144462 +/**
144463 + * bman_irqsource_remove - remove processing sources from being interrupt-driven
144464 + * @bits: bitmask of BM_PIRQ_**I processing sources
144465 + *
144466 + * Removes processing sources from being interrupt-driven, so that they will
144467 + * instead be processed via bman_poll_***() functions. Returns zero for success,
144468 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
144469 +int bman_irqsource_remove(u32 bits);
144470 +
144471 +/**
144472 + * bman_affine_cpus - return a mask of cpus that have affine portals
144473 + */
144474 +const cpumask_t *bman_affine_cpus(void);
144475 +
144476 +/**
144477 + * bman_poll_slow - process anything that isn't interrupt-driven.
144478 + *
144479 + * This function does any portal processing that isn't interrupt-driven. If the
144480 + * current CPU is sharing a portal hosted on another CPU, this function will
144481 + * return -EINVAL, otherwise the return value is a bitmask of BM_PIRQ_* sources
144482 + * indicating what interrupt sources were actually processed by the call.
144483 + *
144484 + * NB, unlike the legacy wrapper bman_poll(), this function will
144485 + * deterministically check for the presence of portal processing work and do it,
144486 + * which implies some latency even if there's nothing to do. The bman_poll()
144487 + * wrapper on the other hand (like the qman_poll() wrapper) attenuates this by
144488 + * checking for (and doing) portal processing infrequently. Ie. such that
144489 + * qman_poll() and bman_poll() can be called from core-processing loops. Use
144490 + * bman_poll_slow() when you yourself are deciding when to incur the overhead of
144491 + * processing.
144492 + */
144493 +u32 bman_poll_slow(void);
144494 +
144495 +/**
144496 + * bman_poll - process anything that isn't interrupt-driven.
144497 + *
144498 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
144499 + * affine portal. This function does whatever processing is not triggered by
144500 + * interrupts. This is a legacy wrapper that can be used in core-processing
144501 + * loops but mitigates the performance overhead of portal processing by
144502 + * adaptively bypassing true portal processing most of the time. (Processing is
144503 + * done once every 10 calls if the previous processing revealed that work needed
144504 + * to be done, or once very 1000 calls if the previous processing revealed no
144505 + * work needed doing.) If you wish to control this yourself, call
144506 + * bman_poll_slow() instead, which always checks for portal processing work.
144507 + */
144508 +void bman_poll(void);
144509 +
144510 +/**
144511 + * bman_rcr_is_empty - Determine if portal's RCR is empty
144512 + *
144513 + * For use in situations where a cpu-affine caller needs to determine when all
144514 + * releases for the local portal have been processed by Bman but can't use the
144515 + * BMAN_RELEASE_FLAG_WAIT_SYNC flag to do this from the final bman_release().
144516 + * The function forces tracking of RCR consumption (which normally doesn't
144517 + * happen until release processing needs to find space to put new release
144518 + * commands), and returns zero if the ring still has unprocessed entries,
144519 + * non-zero if it is empty.
144520 + */
144521 +int bman_rcr_is_empty(void);
144522 +
144523 +/**
144524 + * bman_alloc_bpid_range - Allocate a contiguous range of BPIDs
144525 + * @result: is set by the API to the base BPID of the allocated range
144526 + * @count: the number of BPIDs required
144527 + * @align: required alignment of the allocated range
144528 + * @partial: non-zero if the API can return fewer than @count BPIDs
144529 + *
144530 + * Returns the number of buffer pools allocated, or a negative error code. If
144531 + * @partial is non zero, the allocation request may return a smaller range of
144532 + * BPs than requested (though alignment will be as requested). If @partial is
144533 + * zero, the return value will either be 'count' or negative.
144534 + */
144535 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial);
144536 +static inline int bman_alloc_bpid(u32 *result)
144537 +{
144538 + int ret = bman_alloc_bpid_range(result, 1, 0, 0);
144539 + return (ret > 0) ? 0 : ret;
144540 +}
144541 +
144542 +/**
144543 + * bman_release_bpid_range - Release the specified range of buffer pool IDs
144544 + * @bpid: the base BPID of the range to deallocate
144545 + * @count: the number of BPIDs in the range
144546 + *
144547 + * This function can also be used to seed the allocator with ranges of BPIDs
144548 + * that it can subsequently allocate from.
144549 + */
144550 +void bman_release_bpid_range(u32 bpid, unsigned int count);
144551 +static inline void bman_release_bpid(u32 bpid)
144552 +{
144553 + bman_release_bpid_range(bpid, 1);
144554 +}
144555 +
144556 +int bman_reserve_bpid_range(u32 bpid, unsigned int count);
144557 +static inline int bman_reserve_bpid(u32 bpid)
144558 +{
144559 + return bman_reserve_bpid_range(bpid, 1);
144560 +}
144561 +
144562 +void bman_seed_bpid_range(u32 bpid, unsigned int count);
144563 +
144564 +
144565 +int bman_shutdown_pool(u32 bpid);
144566 +
144567 + /* Pool management */
144568 + /* --------------- */
144569 +/**
144570 + * bman_new_pool - Allocates a Buffer Pool object
144571 + * @params: parameters specifying the buffer pool ID and behaviour
144572 + *
144573 + * Creates a pool object for the given @params. A portal and the depletion
144574 + * callback field of @params are only used if the BMAN_POOL_FLAG_DEPLETION flag
144575 + * is set. NB, the fields from @params are copied into the new pool object, so
144576 + * the structure provided by the caller can be released or reused after the
144577 + * function returns.
144578 + */
144579 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params);
144580 +
144581 +/**
144582 + * bman_free_pool - Deallocates a Buffer Pool object
144583 + * @pool: the pool object to release
144584 + *
144585 + */
144586 +void bman_free_pool(struct bman_pool *pool);
144587 +
144588 +/**
144589 + * bman_get_params - Returns a pool object's parameters.
144590 + * @pool: the pool object
144591 + *
144592 + * The returned pointer refers to state within the pool object so must not be
144593 + * modified and can no longer be read once the pool object is destroyed.
144594 + */
144595 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool);
144596 +
144597 +/**
144598 + * bman_release - Release buffer(s) to the buffer pool
144599 + * @pool: the buffer pool object to release to
144600 + * @bufs: an array of buffers to release
144601 + * @num: the number of buffers in @bufs (1-8)
144602 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
144603 + *
144604 + * Adds the given buffers to RCR entries. If the portal @p was created with the
144605 + * "COMPACT" flag, then it will be using a compaction algorithm to improve
144606 + * utilisation of RCR. As such, these buffers may join an existing ring entry
144607 + * and/or it may not be issued right away so as to allow future releases to join
144608 + * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this
144609 + * behaviour by committing the RCR entry (or entries) right away. If the RCR
144610 + * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT
144611 + * is selected, in which case it will sleep waiting for space to become
144612 + * available in RCR. If the function receives a signal before such time (and
144613 + * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise,
144614 + * it returns zero.
144615 + */
144616 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
144617 + u32 flags);
144618 +
144619 +/**
144620 + * bman_acquire - Acquire buffer(s) from a buffer pool
144621 + * @pool: the buffer pool object to acquire from
144622 + * @bufs: array for storing the acquired buffers
144623 + * @num: the number of buffers desired (@bufs is at least this big)
144624 + *
144625 + * Issues an "Acquire" command via the portal's management command interface.
144626 + * The return value will be the number of buffers obtained from the pool, or a
144627 + * negative error code if a h/w error or pool starvation was encountered. In
144628 + * the latter case, the content of @bufs is undefined.
144629 + */
144630 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
144631 + u32 flags);
144632 +
144633 +/**
144634 + * bman_flush_stockpile - Flush stockpile buffer(s) to the buffer pool
144635 + * @pool: the buffer pool object the stockpile belongs
144636 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
144637 + *
144638 + * Adds stockpile buffers to RCR entries until the stockpile is empty.
144639 + * The return value will be a negative error code if a h/w error occurred.
144640 + * If BMAN_RELEASE_FLAG_NOW flag is passed and RCR ring is full,
144641 + * -EAGAIN will be returned.
144642 + */
144643 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags);
144644 +
144645 +/**
144646 + * bman_query_pools - Query all buffer pool states
144647 + * @state: storage for the queried availability and depletion states
144648 + */
144649 +int bman_query_pools(struct bm_pool_state *state);
144650 +
144651 +#ifdef CONFIG_FSL_BMAN_CONFIG
144652 +/**
144653 + * bman_query_free_buffers - Query how many free buffers are in buffer pool
144654 + * @pool: the buffer pool object to query
144655 + *
144656 + * Return the number of the free buffers
144657 + */
144658 +u32 bman_query_free_buffers(struct bman_pool *pool);
144659 +
144660 +/**
144661 + * bman_update_pool_thresholds - Change the buffer pool's depletion thresholds
144662 + * @pool: the buffer pool object to which the thresholds will be set
144663 + * @thresholds: the new thresholds
144664 + */
144665 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds);
144666 +#endif
144667 +
144668 +/**
144669 + * The below bman_p_***() variant might be called in a situation that the cpu
144670 + * which the portal affine to is not online yet.
144671 + * @bman_portal specifies which portal the API will use.
144672 +*/
144673 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits);
144674 +#ifdef __cplusplus
144675 +}
144676 +#endif
144677 +
144678 +#endif /* FSL_BMAN_H */
144679 --- /dev/null
144680 +++ b/include/linux/fsl_qman.h
144681 @@ -0,0 +1,3888 @@
144682 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
144683 + *
144684 + * Redistribution and use in source and binary forms, with or without
144685 + * modification, are permitted provided that the following conditions are met:
144686 + * * Redistributions of source code must retain the above copyright
144687 + * notice, this list of conditions and the following disclaimer.
144688 + * * Redistributions in binary form must reproduce the above copyright
144689 + * notice, this list of conditions and the following disclaimer in the
144690 + * documentation and/or other materials provided with the distribution.
144691 + * * Neither the name of Freescale Semiconductor nor the
144692 + * names of its contributors may be used to endorse or promote products
144693 + * derived from this software without specific prior written permission.
144694 + *
144695 + *
144696 + * ALTERNATIVELY, this software may be distributed under the terms of the
144697 + * GNU General Public License ("GPL") as published by the Free Software
144698 + * Foundation, either version 2 of that License or (at your option) any
144699 + * later version.
144700 + *
144701 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144702 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144703 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144704 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144705 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144706 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144707 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144708 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144709 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144710 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144711 + */
144712 +
144713 +#ifndef FSL_QMAN_H
144714 +#define FSL_QMAN_H
144715 +
144716 +#ifdef __cplusplus
144717 +extern "C" {
144718 +#endif
144719 +
144720 +/* Last updated for v00.800 of the BG */
144721 +
144722 +/* Hardware constants */
144723 +#define QM_CHANNEL_SWPORTAL0 0
144724 +#define QMAN_CHANNEL_POOL1 0x21
144725 +#define QMAN_CHANNEL_CAAM 0x80
144726 +#define QMAN_CHANNEL_PME 0xa0
144727 +#define QMAN_CHANNEL_POOL1_REV3 0x401
144728 +#define QMAN_CHANNEL_CAAM_REV3 0x840
144729 +#define QMAN_CHANNEL_PME_REV3 0x860
144730 +#define QMAN_CHANNEL_DCE 0x8a0
144731 +#define QMAN_CHANNEL_DCE_QMANREV312 0x880
144732 +extern u16 qm_channel_pool1;
144733 +extern u16 qm_channel_caam;
144734 +extern u16 qm_channel_pme;
144735 +extern u16 qm_channel_dce;
144736 +enum qm_dc_portal {
144737 + qm_dc_portal_fman0 = 0,
144738 + qm_dc_portal_fman1 = 1,
144739 + qm_dc_portal_caam = 2,
144740 + qm_dc_portal_pme = 3,
144741 + qm_dc_portal_rman = 4,
144742 + qm_dc_portal_dce = 5
144743 +};
144744 +
144745 +/* Portal processing (interrupt) sources */
144746 +#define QM_PIRQ_CCSCI 0x00200000 /* CEETM Congestion State Change */
144747 +#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */
144748 +#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */
144749 +#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */
144750 +#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */
144751 +#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */
144752 +/* This mask contains all the interrupt sources that need handling except DQRI,
144753 + * ie. that if present should trigger slow-path processing. */
144754 +#define QM_PIRQ_SLOW (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \
144755 + QM_PIRQ_MRI | QM_PIRQ_CCSCI)
144756 +
144757 +/* --- Clock speed --- */
144758 +/* A qman driver instance may or may not know the current qman clock speed.
144759 + * However, certain CEETM calculations may not be possible if this is not known.
144760 + * The 'set' function will only succeed (return zero) if the driver did not
144761 + * already know the clock speed. Likewise, the 'get' function will only succeed
144762 + * if the driver does know the clock speed (either because it knew when booting,
144763 + * or was told via 'set'). In cases where software is running on a driver
144764 + * instance that does not know the clock speed (eg. on a hypervised data-plane),
144765 + * and the user can obtain the current qman clock speed by other means (eg. from
144766 + * a message sent from the control-plane), then the 'set' function can be used
144767 + * to enable rate-calculations in a driver where it would otherwise not be
144768 + * possible. */
144769 +int qm_get_clock(u64 *clock_hz);
144770 +int qm_set_clock(u64 clock_hz);
144771 +
144772 +/* For qman_static_dequeue_*** APIs */
144773 +#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff
144774 +/* for n in [1,15] */
144775 +#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
144776 +/* for conversion from n of qm_channel */
144777 +static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel)
144778 +{
144779 + return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1);
144780 +}
144781 +
144782 +/* For qman_volatile_dequeue(); Choose one PRECEDENCE. EXACT is optional. Use
144783 + * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use
144784 + * FQID(n) to fill in the frame queue ID. */
144785 +#define QM_VDQCR_PRECEDENCE_VDQCR 0x0
144786 +#define QM_VDQCR_PRECEDENCE_SDQCR 0x80000000
144787 +#define QM_VDQCR_EXACT 0x40000000
144788 +#define QM_VDQCR_NUMFRAMES_MASK 0x3f000000
144789 +#define QM_VDQCR_NUMFRAMES_SET(n) (((n) & 0x3f) << 24)
144790 +#define QM_VDQCR_NUMFRAMES_GET(n) (((n) >> 24) & 0x3f)
144791 +#define QM_VDQCR_NUMFRAMES_TILLEMPTY QM_VDQCR_NUMFRAMES_SET(0)
144792 +
144793 +
144794 +/* ------------------------------------------------------- */
144795 +/* --- Qman data structures (and associated constants) --- */
144796 +
144797 +/* Represents s/w corenet portal mapped data structures */
144798 +struct qm_eqcr_entry; /* EQCR (EnQueue Command Ring) entries */
144799 +struct qm_dqrr_entry; /* DQRR (DeQueue Response Ring) entries */
144800 +struct qm_mr_entry; /* MR (Message Ring) entries */
144801 +struct qm_mc_command; /* MC (Management Command) command */
144802 +struct qm_mc_result; /* MC result */
144803 +
144804 +/* See David Lapp's "Frame formats" document, "dpateam", Jan 07, 2008 */
144805 +#define QM_FD_FORMAT_SG 0x4
144806 +#define QM_FD_FORMAT_LONG 0x2
144807 +#define QM_FD_FORMAT_COMPOUND 0x1
144808 +enum qm_fd_format {
144809 + /* 'contig' implies a contiguous buffer, whereas 'sg' implies a
144810 + * scatter-gather table. 'big' implies a 29-bit length with no offset
144811 + * field, otherwise length is 20-bit and offset is 9-bit. 'compound'
144812 + * implies a s/g-like table, where each entry itself represents a frame
144813 + * (contiguous or scatter-gather) and the 29-bit "length" is
144814 + * interpreted purely for congestion calculations, ie. a "congestion
144815 + * weight". */
144816 + qm_fd_contig = 0,
144817 + qm_fd_contig_big = QM_FD_FORMAT_LONG,
144818 + qm_fd_sg = QM_FD_FORMAT_SG,
144819 + qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG,
144820 + qm_fd_compound = QM_FD_FORMAT_COMPOUND
144821 +};
144822 +
144823 +/* Capitalised versions are un-typed but can be used in static expressions */
144824 +#define QM_FD_CONTIG 0
144825 +#define QM_FD_CONTIG_BIG QM_FD_FORMAT_LONG
144826 +#define QM_FD_SG QM_FD_FORMAT_SG
144827 +#define QM_FD_SG_BIG (QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG)
144828 +#define QM_FD_COMPOUND QM_FD_FORMAT_COMPOUND
144829 +
144830 +/* See 1.5.1.1: "Frame Descriptor (FD)" */
144831 +struct qm_fd {
144832 + union {
144833 + struct {
144834 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144835 + u8 dd:2; /* dynamic debug */
144836 + u8 liodn_offset:6;
144837 + u8 bpid:8; /* Buffer Pool ID */
144838 + u8 eliodn_offset:4;
144839 + u8 __reserved:4;
144840 + u8 addr_hi; /* high 8-bits of 40-bit address */
144841 + u32 addr_lo; /* low 32-bits of 40-bit address */
144842 +#else
144843 + u32 addr_lo; /* low 32-bits of 40-bit address */
144844 + u8 addr_hi; /* high 8-bits of 40-bit address */
144845 + u8 __reserved:4;
144846 + u8 eliodn_offset:4;
144847 + u8 bpid:8; /* Buffer Pool ID */
144848 + u8 liodn_offset:6;
144849 + u8 dd:2; /* dynamic debug */
144850 +#endif
144851 + };
144852 + struct {
144853 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144854 + u64 __notaddress:24;
144855 + u64 addr:40;
144856 +#else
144857 + u64 addr:40;
144858 + u64 __notaddress:24;
144859 +#endif
144860 + };
144861 + u64 opaque_addr;
144862 + };
144863 + /* The 'format' field indicates the interpretation of the remaining 29
144864 + * bits of the 32-bit word. For packing reasons, it is duplicated in the
144865 + * other union elements. Note, union'd structs are difficult to use with
144866 + * static initialisation under gcc, in which case use the "opaque" form
144867 + * with one of the macros. */
144868 + union {
144869 + /* For easier/faster copying of this part of the fd (eg. from a
144870 + * DQRR entry to an EQCR entry) copy 'opaque' */
144871 + u32 opaque;
144872 + /* If 'format' is _contig or _sg, 20b length and 9b offset */
144873 + struct {
144874 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144875 + enum qm_fd_format format:3;
144876 + u16 offset:9;
144877 + u32 length20:20;
144878 +#else
144879 + u32 length20:20;
144880 + u16 offset:9;
144881 + enum qm_fd_format format:3;
144882 +#endif
144883 + };
144884 + /* If 'format' is _contig_big or _sg_big, 29b length */
144885 + struct {
144886 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144887 + enum qm_fd_format _format1:3;
144888 + u32 length29:29;
144889 +#else
144890 + u32 length29:29;
144891 + enum qm_fd_format _format1:3;
144892 +#endif
144893 + };
144894 + /* If 'format' is _compound, 29b "congestion weight" */
144895 + struct {
144896 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144897 + enum qm_fd_format _format2:3;
144898 + u32 cong_weight:29;
144899 +#else
144900 + u32 cong_weight:29;
144901 + enum qm_fd_format _format2:3;
144902 +#endif
144903 + };
144904 + };
144905 + union {
144906 + u32 cmd;
144907 + u32 status;
144908 + };
144909 +} __aligned(8);
144910 +#define QM_FD_DD_NULL 0x00
144911 +#define QM_FD_PID_MASK 0x3f
144912 +static inline u64 qm_fd_addr_get64(const struct qm_fd *fd)
144913 +{
144914 + return fd->addr;
144915 +}
144916 +
144917 +static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd)
144918 +{
144919 + return (dma_addr_t)fd->addr;
144920 +}
144921 +/* Macro, so we compile better if 'v' isn't always 64-bit */
144922 +#define qm_fd_addr_set64(fd, v) \
144923 + do { \
144924 + struct qm_fd *__fd931 = (fd); \
144925 + __fd931->addr = v; \
144926 + } while (0)
144927 +
144928 +/* For static initialisation of FDs (which is complicated by the use of unions
144929 + * in "struct qm_fd"), use the following macros. Note that;
144930 + * - 'dd', 'pid' and 'bpid' are ignored because there's no static initialisation
144931 + * use-case),
144932 + * - use capitalised QM_FD_*** formats for static initialisation.
144933 + */
144934 +#define QM_FD_FMT_20(cmd, addr_hi, addr_lo, fmt, off, len) \
144935 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
144936 + { (((fmt)&0x7) << 29) | (((off)&0x1ff) << 20) | ((len)&0xfffff) }, \
144937 + { cmd } }
144938 +#define QM_FD_FMT_29(cmd, addr_hi, addr_lo, fmt, len) \
144939 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
144940 + { (((fmt)&0x7) << 29) | ((len)&0x1fffffff) }, \
144941 + { cmd } }
144942 +
144943 +/* See 2.2.1.3 Multi-Core Datapath Acceleration Architecture */
144944 +#define QM_SG_OFFSET_MASK 0x1FFF
144945 +struct qm_sg_entry {
144946 + union {
144947 + struct {
144948 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144949 + u8 __reserved1[3];
144950 + u8 addr_hi; /* high 8-bits of 40-bit address */
144951 + u32 addr_lo; /* low 32-bits of 40-bit address */
144952 +#else
144953 + u32 addr_lo; /* low 32-bits of 40-bit address */
144954 + u8 addr_hi; /* high 8-bits of 40-bit address */
144955 + u8 __reserved1[3];
144956 +#endif
144957 + };
144958 + struct {
144959 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144960 + u64 __notaddress:24;
144961 + u64 addr:40;
144962 +#else
144963 + u64 addr:40;
144964 + u64 __notaddress:24;
144965 +#endif
144966 + };
144967 + u64 opaque;
144968 + };
144969 + union {
144970 + struct {
144971 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144972 + u32 extension:1; /* Extension bit */
144973 + u32 final:1; /* Final bit */
144974 + u32 length:30;
144975 +#else
144976 + u32 length:30;
144977 + u32 final:1; /* Final bit */
144978 + u32 extension:1; /* Extension bit */
144979 +#endif
144980 + };
144981 + u32 sgt_efl;
144982 + };
144983 + u8 __reserved2;
144984 + u8 bpid;
144985 + union {
144986 + struct {
144987 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144988 + u16 __reserved3:3;
144989 + u16 offset:13;
144990 +#else
144991 + u16 offset:13;
144992 + u16 __reserved3:3;
144993 +#endif
144994 + };
144995 + u16 opaque_offset;
144996 + };
144997 +} __packed;
144998 +union qm_sg_efl {
144999 + struct {
145000 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145001 + u32 extension:1; /* Extension bit */
145002 + u32 final:1; /* Final bit */
145003 + u32 length:30;
145004 +#else
145005 + u32 length:30;
145006 + u32 final:1; /* Final bit */
145007 + u32 extension:1; /* Extension bit */
145008 +#endif
145009 + };
145010 + u32 efl;
145011 +};
145012 +static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg)
145013 +{
145014 + return (dma_addr_t)be64_to_cpu(sg->opaque) & 0xffffffffffULL;
145015 +}
145016 +static inline u8 qm_sg_entry_get_ext(const struct qm_sg_entry *sg)
145017 +{
145018 + union qm_sg_efl u;
145019 +
145020 + u.efl = be32_to_cpu(sg->sgt_efl);
145021 + return u.extension;
145022 +}
145023 +static inline u8 qm_sg_entry_get_final(const struct qm_sg_entry *sg)
145024 +{
145025 + union qm_sg_efl u;
145026 +
145027 + u.efl = be32_to_cpu(sg->sgt_efl);
145028 + return u.final;
145029 +}
145030 +static inline u32 qm_sg_entry_get_len(const struct qm_sg_entry *sg)
145031 +{
145032 + union qm_sg_efl u;
145033 +
145034 + u.efl = be32_to_cpu(sg->sgt_efl);
145035 + return u.length;
145036 +}
145037 +static inline u8 qm_sg_entry_get_bpid(const struct qm_sg_entry *sg)
145038 +{
145039 + return sg->bpid;
145040 +}
145041 +static inline u16 qm_sg_entry_get_offset(const struct qm_sg_entry *sg)
145042 +{
145043 + u32 opaque_offset = be16_to_cpu(sg->opaque_offset);
145044 +
145045 + return opaque_offset & 0x1fff;
145046 +}
145047 +
145048 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145049 +#define qm_sg_entry_set64(sg, v) \
145050 + do { \
145051 + struct qm_sg_entry *__sg931 = (sg); \
145052 + __sg931->opaque = cpu_to_be64(v); \
145053 + } while (0)
145054 +#define qm_sg_entry_set_ext(sg, v) \
145055 + do { \
145056 + union qm_sg_efl __u932; \
145057 + __u932.efl = be32_to_cpu((sg)->sgt_efl); \
145058 + __u932.extension = v; \
145059 + (sg)->sgt_efl = cpu_to_be32(__u932.efl); \
145060 + } while (0)
145061 +#define qm_sg_entry_set_final(sg, v) \
145062 + do { \
145063 + union qm_sg_efl __u933; \
145064 + __u933.efl = be32_to_cpu((sg)->sgt_efl); \
145065 + __u933.final = v; \
145066 + (sg)->sgt_efl = cpu_to_be32(__u933.efl); \
145067 + } while (0)
145068 +#define qm_sg_entry_set_len(sg, v) \
145069 + do { \
145070 + union qm_sg_efl __u934; \
145071 + __u934.efl = be32_to_cpu((sg)->sgt_efl); \
145072 + __u934.length = v; \
145073 + (sg)->sgt_efl = cpu_to_be32(__u934.efl); \
145074 + } while (0)
145075 +#define qm_sg_entry_set_bpid(sg, v) \
145076 + do { \
145077 + struct qm_sg_entry *__u935 = (sg); \
145078 + __u935->bpid = v; \
145079 + } while (0)
145080 +#define qm_sg_entry_set_offset(sg, v) \
145081 + do { \
145082 + struct qm_sg_entry *__u936 = (sg); \
145083 + __u936->opaque_offset = cpu_to_be16(v); \
145084 + } while (0)
145085 +
145086 +/* See 1.5.8.1: "Enqueue Command" */
145087 +struct qm_eqcr_entry {
145088 + u8 __dont_write_directly__verb;
145089 + u8 dca;
145090 + u16 seqnum;
145091 + u32 orp; /* 24-bit */
145092 + u32 fqid; /* 24-bit */
145093 + u32 tag;
145094 + struct qm_fd fd;
145095 + u8 __reserved3[32];
145096 +} __packed;
145097 +#define QM_EQCR_VERB_VBIT 0x80
145098 +#define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */
145099 +#define QM_EQCR_VERB_CMD_ENQUEUE 0x01
145100 +#define QM_EQCR_VERB_COLOUR_MASK 0x18 /* 4 possible values; */
145101 +#define QM_EQCR_VERB_COLOUR_GREEN 0x00
145102 +#define QM_EQCR_VERB_COLOUR_YELLOW 0x08
145103 +#define QM_EQCR_VERB_COLOUR_RED 0x10
145104 +#define QM_EQCR_VERB_COLOUR_OVERRIDE 0x18
145105 +#define QM_EQCR_VERB_INTERRUPT 0x04 /* on command consumption */
145106 +#define QM_EQCR_VERB_ORP 0x02 /* enable order restoration */
145107 +#define QM_EQCR_DCA_ENABLE 0x80
145108 +#define QM_EQCR_DCA_PARK 0x40
145109 +#define QM_EQCR_DCA_IDXMASK 0x0f /* "DQRR::idx" goes here */
145110 +#define QM_EQCR_SEQNUM_NESN 0x8000 /* Advance NESN */
145111 +#define QM_EQCR_SEQNUM_NLIS 0x4000 /* More fragments to come */
145112 +#define QM_EQCR_SEQNUM_SEQMASK 0x3fff /* sequence number goes here */
145113 +#define QM_EQCR_FQID_NULL 0 /* eg. for an ORP seqnum hole */
145114 +
145115 +/* See 1.5.8.2: "Frame Dequeue Response" */
145116 +struct qm_dqrr_entry {
145117 + u8 verb;
145118 + u8 stat;
145119 + u16 seqnum; /* 15-bit */
145120 + u8 tok;
145121 + u8 __reserved2[3];
145122 + u32 fqid; /* 24-bit */
145123 + u32 contextB;
145124 + struct qm_fd fd;
145125 + u8 __reserved4[32];
145126 +};
145127 +#define QM_DQRR_VERB_VBIT 0x80
145128 +#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */
145129 +#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */
145130 +#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */
145131 +#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */
145132 +#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */
145133 +#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */
145134 +#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */
145135 +#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/
145136 +
145137 +/* See 1.5.8.3: "ERN Message Response" */
145138 +/* See 1.5.8.4: "FQ State Change Notification" */
145139 +struct qm_mr_entry {
145140 + u8 verb;
145141 + union {
145142 + struct {
145143 + u8 dca;
145144 + u16 seqnum;
145145 + u8 rc; /* Rejection Code */
145146 + u32 orp:24;
145147 + u32 fqid; /* 24-bit */
145148 + u32 tag;
145149 + struct qm_fd fd;
145150 + } __packed ern;
145151 + struct {
145152 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145153 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
145154 + u8 __reserved1:3;
145155 + enum qm_dc_portal portal:3;
145156 +#else
145157 + enum qm_dc_portal portal:3;
145158 + u8 __reserved1:3;
145159 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
145160 +#endif
145161 + u16 __reserved2;
145162 + u8 rc; /* Rejection Code */
145163 + u32 __reserved3:24;
145164 + u32 fqid; /* 24-bit */
145165 + u32 tag;
145166 + struct qm_fd fd;
145167 + } __packed dcern;
145168 + struct {
145169 + u8 fqs; /* Frame Queue Status */
145170 + u8 __reserved1[6];
145171 + u32 fqid; /* 24-bit */
145172 + u32 contextB;
145173 + u8 __reserved2[16];
145174 + } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */
145175 + };
145176 + u8 __reserved2[32];
145177 +} __packed;
145178 +#define QM_MR_VERB_VBIT 0x80
145179 +/* The "ern" VERB bits match QM_EQCR_VERB_*** so aren't reproduced here. ERNs
145180 + * originating from direct-connect portals ("dcern") use 0x20 as a verb which
145181 + * would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished from
145182 + * the other MR types by noting if the 0x20 bit is unset. */
145183 +#define QM_MR_VERB_TYPE_MASK 0x27
145184 +#define QM_MR_VERB_DC_ERN 0x20
145185 +#define QM_MR_VERB_FQRN 0x21
145186 +#define QM_MR_VERB_FQRNI 0x22
145187 +#define QM_MR_VERB_FQRL 0x23
145188 +#define QM_MR_VERB_FQPN 0x24
145189 +#define QM_MR_RC_MASK 0xf0 /* contains one of; */
145190 +#define QM_MR_RC_CGR_TAILDROP 0x00
145191 +#define QM_MR_RC_WRED 0x10
145192 +#define QM_MR_RC_ERROR 0x20
145193 +#define QM_MR_RC_ORPWINDOW_EARLY 0x30
145194 +#define QM_MR_RC_ORPWINDOW_LATE 0x40
145195 +#define QM_MR_RC_FQ_TAILDROP 0x50
145196 +#define QM_MR_RC_ORPWINDOW_RETIRED 0x60
145197 +#define QM_MR_RC_ORP_ZERO 0x70
145198 +#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
145199 +#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
145200 +#define QM_MR_DCERN_COLOUR_GREEN 0x00
145201 +#define QM_MR_DCERN_COLOUR_YELLOW 0x01
145202 +#define QM_MR_DCERN_COLOUR_RED 0x02
145203 +#define QM_MR_DCERN_COLOUR_OVERRIDE 0x03
145204 +
145205 +/* An identical structure of FQD fields is present in the "Init FQ" command and
145206 + * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type.
145207 + * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the
145208 + * latter has two inlines to assist with converting to/from the mant+exp
145209 + * representation. */
145210 +struct qm_fqd_stashing {
145211 + /* See QM_STASHING_EXCL_<...> */
145212 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145213 + u8 exclusive;
145214 + u8 __reserved1:2;
145215 + /* Numbers of cachelines */
145216 + u8 annotation_cl:2;
145217 + u8 data_cl:2;
145218 + u8 context_cl:2;
145219 +#else
145220 + u8 context_cl:2;
145221 + u8 data_cl:2;
145222 + u8 annotation_cl:2;
145223 + u8 __reserved1:2;
145224 + u8 exclusive;
145225 +#endif
145226 +} __packed;
145227 +struct qm_fqd_taildrop {
145228 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145229 + u16 __reserved1:3;
145230 + u16 mant:8;
145231 + u16 exp:5;
145232 +#else
145233 + u16 exp:5;
145234 + u16 mant:8;
145235 + u16 __reserved1:3;
145236 +#endif
145237 +} __packed;
145238 +struct qm_fqd_oac {
145239 + /* See QM_OAC_<...> */
145240 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145241 + u8 oac:2; /* "Overhead Accounting Control" */
145242 + u8 __reserved1:6;
145243 +#else
145244 + u8 __reserved1:6;
145245 + u8 oac:2; /* "Overhead Accounting Control" */
145246 +#endif
145247 + /* Two's-complement value (-128 to +127) */
145248 + signed char oal; /* "Overhead Accounting Length" */
145249 +} __packed;
145250 +struct qm_fqd {
145251 + union {
145252 + u8 orpc;
145253 + struct {
145254 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145255 + u8 __reserved1:2;
145256 + u8 orprws:3;
145257 + u8 oa:1;
145258 + u8 olws:2;
145259 +#else
145260 + u8 olws:2;
145261 + u8 oa:1;
145262 + u8 orprws:3;
145263 + u8 __reserved1:2;
145264 +#endif
145265 + } __packed;
145266 + };
145267 + u8 cgid;
145268 + u16 fq_ctrl; /* See QM_FQCTRL_<...> */
145269 + union {
145270 + u16 dest_wq;
145271 + struct {
145272 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145273 + u16 channel:13; /* qm_channel */
145274 + u16 wq:3;
145275 +#else
145276 + u16 wq:3;
145277 + u16 channel:13; /* qm_channel */
145278 +#endif
145279 + } __packed dest;
145280 + };
145281 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145282 + u16 __reserved2:1;
145283 + u16 ics_cred:15;
145284 +#else
145285 + u16 __reserved2:1;
145286 + u16 ics_cred:15;
145287 +#endif
145288 + /* For "Initialize Frame Queue" commands, the write-enable mask
145289 + * determines whether 'td' or 'oac_init' is observed. For query
145290 + * commands, this field is always 'td', and 'oac_query' (below) reflects
145291 + * the Overhead ACcounting values. */
145292 + union {
145293 + struct qm_fqd_taildrop td;
145294 + struct qm_fqd_oac oac_init;
145295 + };
145296 + u32 context_b;
145297 + union {
145298 + /* Treat it as 64-bit opaque */
145299 + u64 opaque;
145300 + struct {
145301 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145302 + u32 hi;
145303 + u32 lo;
145304 +#else
145305 + u32 lo;
145306 + u32 hi;
145307 +#endif
145308 + };
145309 + /* Treat it as s/w portal stashing config */
145310 + /* See 1.5.6.7.1: "FQD Context_A field used for [...] */
145311 + struct {
145312 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145313 + struct qm_fqd_stashing stashing;
145314 + /* 48-bit address of FQ context to
145315 + * stash, must be cacheline-aligned */
145316 + u16 context_hi;
145317 + u32 context_lo;
145318 +#else
145319 + u32 context_lo;
145320 + u16 context_hi;
145321 + struct qm_fqd_stashing stashing;
145322 +#endif
145323 + } __packed;
145324 + } context_a;
145325 + struct qm_fqd_oac oac_query;
145326 +} __packed;
145327 +/* 64-bit converters for context_hi/lo */
145328 +static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd)
145329 +{
145330 + return ((u64)fqd->context_a.context_hi << 32) |
145331 + (u64)fqd->context_a.context_lo;
145332 +}
145333 +static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd)
145334 +{
145335 + return (dma_addr_t)qm_fqd_stashing_get64(fqd);
145336 +}
145337 +static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd)
145338 +{
145339 + return ((u64)fqd->context_a.hi << 32) |
145340 + (u64)fqd->context_a.lo;
145341 +}
145342 +/* Macro, so we compile better when 'v' isn't necessarily 64-bit */
145343 +#define qm_fqd_stashing_set64(fqd, v) \
145344 + do { \
145345 + struct qm_fqd *__fqd931 = (fqd); \
145346 + __fqd931->context_a.context_hi = upper_32_bits(v); \
145347 + __fqd931->context_a.context_lo = lower_32_bits(v); \
145348 + } while (0)
145349 +#define qm_fqd_context_a_set64(fqd, v) \
145350 + do { \
145351 + struct qm_fqd *__fqd931 = (fqd); \
145352 + __fqd931->context_a.hi = upper_32_bits(v); \
145353 + __fqd931->context_a.lo = lower_32_bits(v); \
145354 + } while (0)
145355 +/* convert a threshold value into mant+exp representation */
145356 +static inline int qm_fqd_taildrop_set(struct qm_fqd_taildrop *td, u32 val,
145357 + int roundup)
145358 +{
145359 + u32 e = 0;
145360 + int oddbit = 0;
145361 + if (val > 0xe0000000)
145362 + return -ERANGE;
145363 + while (val > 0xff) {
145364 + oddbit = val & 1;
145365 + val >>= 1;
145366 + e++;
145367 + if (roundup && oddbit)
145368 + val++;
145369 + }
145370 + td->exp = e;
145371 + td->mant = val;
145372 + return 0;
145373 +}
145374 +/* and the other direction */
145375 +static inline u32 qm_fqd_taildrop_get(const struct qm_fqd_taildrop *td)
145376 +{
145377 + return (u32)td->mant << td->exp;
145378 +}
145379 +
145380 +/* See 1.5.2.2: "Frame Queue Descriptor (FQD)" */
145381 +/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */
145382 +#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */
145383 +#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */
145384 +#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */
145385 +#define QM_FQCTRL_ORP 0x0100 /* ORP Enable */
145386 +#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */
145387 +#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */
145388 +#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */
145389 +#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */
145390 +#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */
145391 +#define QM_FQCTRL_PREFERINCACHE 0x0001 /* Aggressively cache FQD */
145392 +#define QM_FQCTRL_LOCKINCACHE QM_FQCTRL_PREFERINCACHE /* older naming */
145393 +
145394 +/* See 1.5.6.7.1: "FQD Context_A field used for [...] */
145395 +/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */
145396 +#define QM_STASHING_EXCL_ANNOTATION 0x04
145397 +#define QM_STASHING_EXCL_DATA 0x02
145398 +#define QM_STASHING_EXCL_CTX 0x01
145399 +
145400 +/* See 1.5.5.3: "Intra Class Scheduling" */
145401 +/* FQD field 'OAC' (Overhead ACcounting) uses these constants */
145402 +#define QM_OAC_ICS 0x2 /* Accounting for Intra-Class Scheduling */
145403 +#define QM_OAC_CG 0x1 /* Accounting for Congestion Groups */
145404 +
145405 +/* See 1.5.8.4: "FQ State Change Notification" */
145406 +/* This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields
145407 + * and associated commands/responses. The WRED parameters are calculated from
145408 + * these fields as follows;
145409 + * MaxTH = MA * (2 ^ Mn)
145410 + * Slope = SA / (2 ^ Sn)
145411 + * MaxP = 4 * (Pn + 1)
145412 + */
145413 +struct qm_cgr_wr_parm {
145414 + union {
145415 + u32 word;
145416 + struct {
145417 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145418 + u32 MA:8;
145419 + u32 Mn:5;
145420 + u32 SA:7; /* must be between 64-127 */
145421 + u32 Sn:6;
145422 + u32 Pn:6;
145423 +#else
145424 + u32 Pn:6;
145425 + u32 Sn:6;
145426 + u32 SA:7; /* must be between 64-127 */
145427 + u32 Mn:5;
145428 + u32 MA:8;
145429 +#endif
145430 + } __packed;
145431 + };
145432 +} __packed;
145433 +/* This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding
145434 + * management commands, this is padded to a 16-bit structure field, so that's
145435 + * how we represent it here. The congestion state threshold is calculated from
145436 + * these fields as follows;
145437 + * CS threshold = TA * (2 ^ Tn)
145438 + */
145439 +struct qm_cgr_cs_thres {
145440 + union {
145441 + u16 hword;
145442 + struct {
145443 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145444 + u16 __reserved:3;
145445 + u16 TA:8;
145446 + u16 Tn:5;
145447 +#else
145448 + u16 Tn:5;
145449 + u16 TA:8;
145450 + u16 __reserved:3;
145451 +#endif
145452 + } __packed;
145453 + };
145454 +} __packed;
145455 +/* This identical structure of CGR fields is present in the "Init/Modify CGR"
145456 + * commands and the "Query CGR" result. It's suctioned out here into its own
145457 + * struct. */
145458 +struct __qm_mc_cgr {
145459 + struct qm_cgr_wr_parm wr_parm_g;
145460 + struct qm_cgr_wr_parm wr_parm_y;
145461 + struct qm_cgr_wr_parm wr_parm_r;
145462 + u8 wr_en_g; /* boolean, use QM_CGR_EN */
145463 + u8 wr_en_y; /* boolean, use QM_CGR_EN */
145464 + u8 wr_en_r; /* boolean, use QM_CGR_EN */
145465 + u8 cscn_en; /* boolean, use QM_CGR_EN */
145466 + union {
145467 + struct {
145468 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145469 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
145470 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
145471 +#else
145472 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
145473 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
145474 +#endif
145475 + };
145476 + u32 cscn_targ; /* use QM_CGR_TARG_* */
145477 + };
145478 + u8 cstd_en; /* boolean, use QM_CGR_EN */
145479 + u8 cs; /* boolean, only used in query response */
145480 + union {
145481 + /* use qm_cgr_cs_thres_set64() */
145482 + struct qm_cgr_cs_thres cs_thres;
145483 + u16 __cs_thres;
145484 + };
145485 + u8 mode; /* QMAN_CGR_MODE_FRAME not supported in rev1.0 */
145486 +} __packed;
145487 +#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en */
145488 +#define QM_CGR_TARG_UDP_CTRL_WRITE_BIT 0x8000 /* value written to portal bit*/
145489 +#define QM_CGR_TARG_UDP_CTRL_DCP 0x4000 /* 0: SWP, 1: DCP */
145490 +#define QM_CGR_TARG_PORTAL(n) (0x80000000 >> (n)) /* s/w portal, 0-9 */
145491 +#define QM_CGR_TARG_FMAN0 0x00200000 /* direct-connect portal: fman0 */
145492 +#define QM_CGR_TARG_FMAN1 0x00100000 /* : fman1 */
145493 +/* Convert CGR thresholds to/from "cs_thres" format */
145494 +static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th)
145495 +{
145496 + return (u64)th->TA << th->Tn;
145497 +}
145498 +static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val,
145499 + int roundup)
145500 +{
145501 + u32 e = 0;
145502 + int oddbit = 0;
145503 + while (val > 0xff) {
145504 + oddbit = val & 1;
145505 + val >>= 1;
145506 + e++;
145507 + if (roundup && oddbit)
145508 + val++;
145509 + }
145510 + th->Tn = e;
145511 + th->TA = val;
145512 + return 0;
145513 +}
145514 +
145515 +/* See 1.5.8.5.1: "Initialize FQ" */
145516 +/* See 1.5.8.5.2: "Query FQ" */
145517 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
145518 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
145519 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
145520 +/* See 1.5.8.6.2: "CGR Test Write" */
145521 +/* See 1.5.8.6.3: "Query CGR" */
145522 +/* See 1.5.8.6.4: "Query Congestion Group State" */
145523 +struct qm_mcc_initfq {
145524 + u8 __reserved1;
145525 + u16 we_mask; /* Write Enable Mask */
145526 + u32 fqid; /* 24-bit */
145527 + u16 count; /* Initialises 'count+1' FQDs */
145528 + struct qm_fqd fqd; /* the FQD fields go here */
145529 + u8 __reserved3[30];
145530 +} __packed;
145531 +struct qm_mcc_queryfq {
145532 + u8 __reserved1[3];
145533 + u32 fqid; /* 24-bit */
145534 + u8 __reserved2[56];
145535 +} __packed;
145536 +struct qm_mcc_queryfq_np {
145537 + u8 __reserved1[3];
145538 + u32 fqid; /* 24-bit */
145539 + u8 __reserved2[56];
145540 +} __packed;
145541 +struct qm_mcc_alterfq {
145542 + u8 __reserved1[3];
145543 + u32 fqid; /* 24-bit */
145544 + u8 __reserved2;
145545 + u8 count; /* number of consecutive FQID */
145546 + u8 __reserved3[10];
145547 + u32 context_b; /* frame queue context b */
145548 + u8 __reserved4[40];
145549 +} __packed;
145550 +struct qm_mcc_initcgr {
145551 + u8 __reserved1;
145552 + u16 we_mask; /* Write Enable Mask */
145553 + struct __qm_mc_cgr cgr; /* CGR fields */
145554 + u8 __reserved2[2];
145555 + u8 cgid;
145556 + u8 __reserved4[32];
145557 +} __packed;
145558 +struct qm_mcc_cgrtestwrite {
145559 + u8 __reserved1[2];
145560 + u8 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
145561 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
145562 + u8 __reserved2[23];
145563 + u8 cgid;
145564 + u8 __reserved3[32];
145565 +} __packed;
145566 +struct qm_mcc_querycgr {
145567 + u8 __reserved1[30];
145568 + u8 cgid;
145569 + u8 __reserved2[32];
145570 +} __packed;
145571 +struct qm_mcc_querycongestion {
145572 + u8 __reserved[63];
145573 +} __packed;
145574 +struct qm_mcc_querywq {
145575 + u8 __reserved;
145576 + /* select channel if verb != QUERYWQ_DEDICATED */
145577 + union {
145578 + u16 channel_wq; /* ignores wq (3 lsbits) */
145579 + struct {
145580 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145581 + u16 id:13; /* qm_channel */
145582 + u16 __reserved1:3;
145583 +#else
145584 + u16 __reserved1:3;
145585 + u16 id:13; /* qm_channel */
145586 +#endif
145587 + } __packed channel;
145588 + };
145589 + u8 __reserved2[60];
145590 +} __packed;
145591 +
145592 +struct qm_mcc_ceetm_lfqmt_config {
145593 + u8 __reserved1[4];
145594 + u32 lfqid:24;
145595 + u8 __reserved2[2];
145596 + u16 cqid;
145597 + u8 __reserved3[2];
145598 + u16 dctidx;
145599 + u8 __reserved4[48];
145600 +} __packed;
145601 +
145602 +struct qm_mcc_ceetm_lfqmt_query {
145603 + u8 __reserved1[4];
145604 + u32 lfqid:24;
145605 + u8 __reserved2[56];
145606 +} __packed;
145607 +
145608 +struct qm_mcc_ceetm_cq_config {
145609 + u8 __reserved1;
145610 + u16 cqid;
145611 + u8 dcpid;
145612 + u8 __reserved2;
145613 + u16 ccgid;
145614 + u8 __reserved3[56];
145615 +} __packed;
145616 +
145617 +struct qm_mcc_ceetm_cq_query {
145618 + u8 __reserved1;
145619 + u16 cqid;
145620 + u8 dcpid;
145621 + u8 __reserved2[59];
145622 +} __packed;
145623 +
145624 +struct qm_mcc_ceetm_dct_config {
145625 + u8 __reserved1;
145626 + u16 dctidx;
145627 + u8 dcpid;
145628 + u8 __reserved2[15];
145629 + u32 context_b;
145630 + u64 context_a;
145631 + u8 __reserved3[32];
145632 +} __packed;
145633 +
145634 +struct qm_mcc_ceetm_dct_query {
145635 + u8 __reserved1;
145636 + u16 dctidx;
145637 + u8 dcpid;
145638 + u8 __reserved2[59];
145639 +} __packed;
145640 +
145641 +struct qm_mcc_ceetm_class_scheduler_config {
145642 + u8 __reserved1;
145643 + u16 cqcid;
145644 + u8 dcpid;
145645 + u8 __reserved2[6];
145646 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145647 + u8 gpc_reserved:1;
145648 + u8 gpc_combine_flag:1;
145649 + u8 gpc_prio_b:3;
145650 + u8 gpc_prio_a:3;
145651 +#else
145652 + u8 gpc_prio_a:3;
145653 + u8 gpc_prio_b:3;
145654 + u8 gpc_combine_flag:1;
145655 + u8 gpc_reserved:1;
145656 +#endif
145657 + u16 crem;
145658 + u16 erem;
145659 + u8 w[8];
145660 + u8 __reserved3[40];
145661 +} __packed;
145662 +
145663 +struct qm_mcc_ceetm_class_scheduler_query {
145664 + u8 __reserved1;
145665 + u16 cqcid;
145666 + u8 dcpid;
145667 + u8 __reserved2[59];
145668 +} __packed;
145669 +
145670 +#define CEETM_COMMAND_CHANNEL_MAPPING (0 << 12)
145671 +#define CEETM_COMMAND_SP_MAPPING (1 << 12)
145672 +#define CEETM_COMMAND_CHANNEL_SHAPER (2 << 12)
145673 +#define CEETM_COMMAND_LNI_SHAPER (3 << 12)
145674 +#define CEETM_COMMAND_TCFC (4 << 12)
145675 +
145676 +#define CEETM_CCGRID_MASK 0x01FF
145677 +#define CEETM_CCGR_CM_CONFIGURE (0 << 14)
145678 +#define CEETM_CCGR_DN_CONFIGURE (1 << 14)
145679 +#define CEETM_CCGR_TEST_WRITE (2 << 14)
145680 +#define CEETM_CCGR_CM_QUERY (0 << 14)
145681 +#define CEETM_CCGR_DN_QUERY (1 << 14)
145682 +#define CEETM_CCGR_DN_QUERY_FLUSH (2 << 14)
145683 +#define CEETM_QUERY_CONGESTION_STATE (3 << 14)
145684 +
145685 +struct qm_mcc_ceetm_mapping_shaper_tcfc_config {
145686 + u8 __reserved1;
145687 + u16 cid;
145688 + u8 dcpid;
145689 + union {
145690 + struct {
145691 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145692 + u8 map_shaped:1;
145693 + u8 map_reserved:4;
145694 + u8 map_lni_id:3;
145695 +#else
145696 + u8 map_lni_id:3;
145697 + u8 map_reserved:4;
145698 + u8 map_shaped:1;
145699 +#endif
145700 + u8 __reserved2[58];
145701 + } __packed channel_mapping;
145702 + struct {
145703 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145704 + u8 map_reserved:5;
145705 + u8 map_lni_id:3;
145706 +#else
145707 + u8 map_lni_id:3;
145708 + u8 map_reserved:5;
145709 +#endif
145710 + u8 __reserved2[58];
145711 + } __packed sp_mapping;
145712 + struct {
145713 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145714 + u8 cpl:1;
145715 + u8 cpl_reserved:2;
145716 + u8 oal:5;
145717 +#else
145718 + u8 oal:5;
145719 + u8 cpl_reserved:2;
145720 + u8 cpl:1;
145721 +#endif
145722 + u32 crtcr:24;
145723 + u32 ertcr:24;
145724 + u16 crtbl;
145725 + u16 ertbl;
145726 + u8 mps; /* This will be hardcoded by driver with 60 */
145727 + u8 __reserved2[47];
145728 + } __packed shaper_config;
145729 + struct {
145730 + u8 __reserved2[11];
145731 + u64 lnitcfcc;
145732 + u8 __reserved3[40];
145733 + } __packed tcfc_config;
145734 + };
145735 +} __packed;
145736 +
145737 +struct qm_mcc_ceetm_mapping_shaper_tcfc_query {
145738 + u8 __reserved1;
145739 + u16 cid;
145740 + u8 dcpid;
145741 + u8 __reserved2[59];
145742 +} __packed;
145743 +
145744 +struct qm_mcc_ceetm_ccgr_config {
145745 + u8 __reserved1;
145746 + u16 ccgrid;
145747 + u8 dcpid;
145748 + u8 __reserved2;
145749 + u16 we_mask;
145750 + union {
145751 + struct {
145752 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145753 + u8 ctl_reserved:1;
145754 + u8 ctl_wr_en_g:1;
145755 + u8 ctl_wr_en_y:1;
145756 + u8 ctl_wr_en_r:1;
145757 + u8 ctl_td_en:1;
145758 + u8 ctl_td_mode:1;
145759 + u8 ctl_cscn_en:1;
145760 + u8 ctl_mode:1;
145761 +#else
145762 + u8 ctl_mode:1;
145763 + u8 ctl_cscn_en:1;
145764 + u8 ctl_td_mode:1;
145765 + u8 ctl_td_en:1;
145766 + u8 ctl_wr_en_r:1;
145767 + u8 ctl_wr_en_y:1;
145768 + u8 ctl_wr_en_g:1;
145769 + u8 ctl_reserved:1;
145770 +#endif
145771 + u8 cdv;
145772 + u16 cscn_tupd;
145773 + u8 oal;
145774 + u8 __reserved3;
145775 + struct qm_cgr_cs_thres cs_thres;
145776 + struct qm_cgr_cs_thres cs_thres_x;
145777 + struct qm_cgr_cs_thres td_thres;
145778 + struct qm_cgr_wr_parm wr_parm_g;
145779 + struct qm_cgr_wr_parm wr_parm_y;
145780 + struct qm_cgr_wr_parm wr_parm_r;
145781 + } __packed cm_config;
145782 + struct {
145783 + u8 dnc;
145784 + u8 dn0;
145785 + u8 dn1;
145786 + u64 dnba:40;
145787 + u8 __reserved3[2];
145788 + u16 dnth_0;
145789 + u8 __reserved4[2];
145790 + u16 dnth_1;
145791 + u8 __reserved5[8];
145792 + } __packed dn_config;
145793 + struct {
145794 + u8 __reserved3[3];
145795 + u64 i_cnt:40;
145796 + u8 __reserved4[16];
145797 + } __packed test_write;
145798 + };
145799 + u8 __reserved5[32];
145800 +} __packed;
145801 +
145802 +struct qm_mcc_ceetm_ccgr_query {
145803 + u8 __reserved1;
145804 + u16 ccgrid;
145805 + u8 dcpid;
145806 + u8 __reserved2[59];
145807 +} __packed;
145808 +
145809 +struct qm_mcc_ceetm_cq_peek_pop_xsfdrread {
145810 + u8 __reserved1;
145811 + u16 cqid;
145812 + u8 dcpid;
145813 + u8 ct;
145814 + u16 xsfdr;
145815 + u8 __reserved2[56];
145816 +} __packed;
145817 +
145818 +#define CEETM_QUERY_DEQUEUE_STATISTICS 0x00
145819 +#define CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS 0x01
145820 +#define CEETM_WRITE_DEQUEUE_STATISTICS 0x02
145821 +#define CEETM_QUERY_REJECT_STATISTICS 0x03
145822 +#define CEETM_QUERY_REJECT_CLEAR_STATISTICS 0x04
145823 +#define CEETM_WRITE_REJECT_STATISTICS 0x05
145824 +struct qm_mcc_ceetm_statistics_query_write {
145825 + u8 __reserved1;
145826 + u16 cid;
145827 + u8 dcpid;
145828 + u8 ct;
145829 + u8 __reserved2[13];
145830 + u64 frm_cnt:40;
145831 + u8 __reserved3[2];
145832 + u64 byte_cnt:48;
145833 + u8 __reserved[32];
145834 +} __packed;
145835 +
145836 +struct qm_mc_command {
145837 + u8 __dont_write_directly__verb;
145838 + union {
145839 + struct qm_mcc_initfq initfq;
145840 + struct qm_mcc_queryfq queryfq;
145841 + struct qm_mcc_queryfq_np queryfq_np;
145842 + struct qm_mcc_alterfq alterfq;
145843 + struct qm_mcc_initcgr initcgr;
145844 + struct qm_mcc_cgrtestwrite cgrtestwrite;
145845 + struct qm_mcc_querycgr querycgr;
145846 + struct qm_mcc_querycongestion querycongestion;
145847 + struct qm_mcc_querywq querywq;
145848 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
145849 + struct qm_mcc_ceetm_lfqmt_query lfqmt_query;
145850 + struct qm_mcc_ceetm_cq_config cq_config;
145851 + struct qm_mcc_ceetm_cq_query cq_query;
145852 + struct qm_mcc_ceetm_dct_config dct_config;
145853 + struct qm_mcc_ceetm_dct_query dct_query;
145854 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
145855 + struct qm_mcc_ceetm_class_scheduler_query csch_query;
145856 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config mst_config;
145857 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query mst_query;
145858 + struct qm_mcc_ceetm_ccgr_config ccgr_config;
145859 + struct qm_mcc_ceetm_ccgr_query ccgr_query;
145860 + struct qm_mcc_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
145861 + struct qm_mcc_ceetm_statistics_query_write stats_query_write;
145862 + };
145863 +} __packed;
145864 +#define QM_MCC_VERB_VBIT 0x80
145865 +#define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */
145866 +#define QM_MCC_VERB_INITFQ_PARKED 0x40
145867 +#define QM_MCC_VERB_INITFQ_SCHED 0x41
145868 +#define QM_MCC_VERB_QUERYFQ 0x44
145869 +#define QM_MCC_VERB_QUERYFQ_NP 0x45 /* "non-programmable" fields */
145870 +#define QM_MCC_VERB_QUERYWQ 0x46
145871 +#define QM_MCC_VERB_QUERYWQ_DEDICATED 0x47
145872 +#define QM_MCC_VERB_ALTER_SCHED 0x48 /* Schedule FQ */
145873 +#define QM_MCC_VERB_ALTER_FE 0x49 /* Force Eligible FQ */
145874 +#define QM_MCC_VERB_ALTER_RETIRE 0x4a /* Retire FQ */
145875 +#define QM_MCC_VERB_ALTER_OOS 0x4b /* Take FQ out of service */
145876 +#define QM_MCC_VERB_ALTER_FQXON 0x4d /* FQ XON */
145877 +#define QM_MCC_VERB_ALTER_FQXOFF 0x4e /* FQ XOFF */
145878 +#define QM_MCC_VERB_INITCGR 0x50
145879 +#define QM_MCC_VERB_MODIFYCGR 0x51
145880 +#define QM_MCC_VERB_CGRTESTWRITE 0x52
145881 +#define QM_MCC_VERB_QUERYCGR 0x58
145882 +#define QM_MCC_VERB_QUERYCONGESTION 0x59
145883 +/* INITFQ-specific flags */
145884 +#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */
145885 +#define QM_INITFQ_WE_OAC 0x0100
145886 +#define QM_INITFQ_WE_ORPC 0x0080
145887 +#define QM_INITFQ_WE_CGID 0x0040
145888 +#define QM_INITFQ_WE_FQCTRL 0x0020
145889 +#define QM_INITFQ_WE_DESTWQ 0x0010
145890 +#define QM_INITFQ_WE_ICSCRED 0x0008
145891 +#define QM_INITFQ_WE_TDTHRESH 0x0004
145892 +#define QM_INITFQ_WE_CONTEXTB 0x0002
145893 +#define QM_INITFQ_WE_CONTEXTA 0x0001
145894 +/* INITCGR/MODIFYCGR-specific flags */
145895 +#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */
145896 +#define QM_CGR_WE_WR_PARM_G 0x0400
145897 +#define QM_CGR_WE_WR_PARM_Y 0x0200
145898 +#define QM_CGR_WE_WR_PARM_R 0x0100
145899 +#define QM_CGR_WE_WR_EN_G 0x0080
145900 +#define QM_CGR_WE_WR_EN_Y 0x0040
145901 +#define QM_CGR_WE_WR_EN_R 0x0020
145902 +#define QM_CGR_WE_CSCN_EN 0x0010
145903 +#define QM_CGR_WE_CSCN_TARG 0x0008
145904 +#define QM_CGR_WE_CSTD_EN 0x0004
145905 +#define QM_CGR_WE_CS_THRES 0x0002
145906 +#define QM_CGR_WE_MODE 0x0001
145907 +
145908 +/* See 1.5.9.7 CEETM Management Commands */
145909 +#define QM_CEETM_VERB_LFQMT_CONFIG 0x70
145910 +#define QM_CEETM_VERB_LFQMT_QUERY 0x71
145911 +#define QM_CEETM_VERB_CQ_CONFIG 0x72
145912 +#define QM_CEETM_VERB_CQ_QUERY 0x73
145913 +#define QM_CEETM_VERB_DCT_CONFIG 0x74
145914 +#define QM_CEETM_VERB_DCT_QUERY 0x75
145915 +#define QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG 0x76
145916 +#define QM_CEETM_VERB_CLASS_SCHEDULER_QUERY 0x77
145917 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG 0x78
145918 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY 0x79
145919 +#define QM_CEETM_VERB_CCGR_CONFIG 0x7A
145920 +#define QM_CEETM_VERB_CCGR_QUERY 0x7B
145921 +#define QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD 0x7C
145922 +#define QM_CEETM_VERB_STATISTICS_QUERY_WRITE 0x7D
145923 +
145924 +/* See 1.5.8.5.1: "Initialize FQ" */
145925 +/* See 1.5.8.5.2: "Query FQ" */
145926 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
145927 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
145928 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
145929 +/* See 1.5.8.6.2: "CGR Test Write" */
145930 +/* See 1.5.8.6.3: "Query CGR" */
145931 +/* See 1.5.8.6.4: "Query Congestion Group State" */
145932 +struct qm_mcr_initfq {
145933 + u8 __reserved1[62];
145934 +} __packed;
145935 +struct qm_mcr_queryfq {
145936 + u8 __reserved1[8];
145937 + struct qm_fqd fqd; /* the FQD fields are here */
145938 + u8 __reserved2[30];
145939 +} __packed;
145940 +struct qm_mcr_queryfq_np {
145941 + u8 __reserved1;
145942 + u8 state; /* QM_MCR_NP_STATE_*** */
145943 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145944 + u8 __reserved2;
145945 + u32 fqd_link:24;
145946 + u16 __reserved3:2;
145947 + u16 odp_seq:14;
145948 + u16 __reserved4:2;
145949 + u16 orp_nesn:14;
145950 + u16 __reserved5:1;
145951 + u16 orp_ea_hseq:15;
145952 + u16 __reserved6:1;
145953 + u16 orp_ea_tseq:15;
145954 + u8 __reserved7;
145955 + u32 orp_ea_hptr:24;
145956 + u8 __reserved8;
145957 + u32 orp_ea_tptr:24;
145958 + u8 __reserved9;
145959 + u32 pfdr_hptr:24;
145960 + u8 __reserved10;
145961 + u32 pfdr_tptr:24;
145962 + u8 __reserved11[5];
145963 + u8 __reserved12:7;
145964 + u8 is:1;
145965 + u16 ics_surp;
145966 + u32 byte_cnt;
145967 + u8 __reserved13;
145968 + u32 frm_cnt:24;
145969 + u32 __reserved14;
145970 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
145971 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
145972 + u16 __reserved15;
145973 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
145974 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
145975 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
145976 +#else
145977 + u8 __reserved2;
145978 + u32 fqd_link:24;
145979 +
145980 + u16 odp_seq:14;
145981 + u16 __reserved3:2;
145982 +
145983 + u16 orp_nesn:14;
145984 + u16 __reserved4:2;
145985 +
145986 + u16 orp_ea_hseq:15;
145987 + u16 __reserved5:1;
145988 +
145989 + u16 orp_ea_tseq:15;
145990 + u16 __reserved6:1;
145991 +
145992 + u8 __reserved7;
145993 + u32 orp_ea_hptr:24;
145994 +
145995 + u8 __reserved8;
145996 + u32 orp_ea_tptr:24;
145997 +
145998 + u8 __reserved9;
145999 + u32 pfdr_hptr:24;
146000 +
146001 + u8 __reserved10;
146002 + u32 pfdr_tptr:24;
146003 +
146004 + u8 __reserved11[5];
146005 + u8 is:1;
146006 + u8 __reserved12:7;
146007 + u16 ics_surp;
146008 + u32 byte_cnt;
146009 + u8 __reserved13;
146010 + u32 frm_cnt:24;
146011 + u32 __reserved14;
146012 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
146013 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
146014 + u16 __reserved15;
146015 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
146016 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
146017 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
146018 +#endif
146019 +} __packed;
146020 +
146021 +
146022 +struct qm_mcr_alterfq {
146023 + u8 fqs; /* Frame Queue Status */
146024 + u8 __reserved1[61];
146025 +} __packed;
146026 +struct qm_mcr_initcgr {
146027 + u8 __reserved1[62];
146028 +} __packed;
146029 +struct qm_mcr_cgrtestwrite {
146030 + u16 __reserved1;
146031 + struct __qm_mc_cgr cgr; /* CGR fields */
146032 + u8 __reserved2[3];
146033 + u32 __reserved3:24;
146034 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146035 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146036 + u32 __reserved4:24;
146037 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146038 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146039 + u16 lgt; /* Last Group Tick */
146040 + u16 wr_prob_g;
146041 + u16 wr_prob_y;
146042 + u16 wr_prob_r;
146043 + u8 __reserved5[8];
146044 +} __packed;
146045 +struct qm_mcr_querycgr {
146046 + u16 __reserved1;
146047 + struct __qm_mc_cgr cgr; /* CGR fields */
146048 + u8 __reserved2[3];
146049 + union {
146050 + struct {
146051 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146052 + u32 __reserved3:24;
146053 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146054 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146055 +#else
146056 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146057 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146058 + u32 __reserved3:24;
146059 +#endif
146060 + };
146061 + u64 i_bcnt;
146062 + };
146063 + union {
146064 + struct {
146065 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146066 + u32 __reserved4:24;
146067 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146068 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146069 +#else
146070 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146071 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146072 + u32 __reserved4:24;
146073 +#endif
146074 + };
146075 + u64 a_bcnt;
146076 + };
146077 + union {
146078 + u32 cscn_targ_swp[4];
146079 + u8 __reserved5[16];
146080 + };
146081 +} __packed;
146082 +static inline u64 qm_mcr_querycgr_i_get64(const struct qm_mcr_querycgr *q)
146083 +{
146084 + return be64_to_cpu(q->i_bcnt);
146085 +}
146086 +static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q)
146087 +{
146088 + return be64_to_cpu(q->a_bcnt);
146089 +}
146090 +static inline u64 qm_mcr_cgrtestwrite_i_get64(
146091 + const struct qm_mcr_cgrtestwrite *q)
146092 +{
146093 + return be64_to_cpu(((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo);
146094 +}
146095 +static inline u64 qm_mcr_cgrtestwrite_a_get64(
146096 + const struct qm_mcr_cgrtestwrite *q)
146097 +{
146098 + return be64_to_cpu(((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo);
146099 +}
146100 +/* Macro, so we compile better if 'v' isn't always 64-bit */
146101 +#define qm_mcr_querycgr_i_set64(q, v) \
146102 + do { \
146103 + struct qm_mcr_querycgr *__q931 = (fd); \
146104 + __q931->i_bcnt_hi = upper_32_bits(v); \
146105 + __q931->i_bcnt_lo = lower_32_bits(v); \
146106 + } while (0)
146107 +#define qm_mcr_querycgr_a_set64(q, v) \
146108 + do { \
146109 + struct qm_mcr_querycgr *__q931 = (fd); \
146110 + __q931->a_bcnt_hi = upper_32_bits(v); \
146111 + __q931->a_bcnt_lo = lower_32_bits(v); \
146112 + } while (0)
146113 +struct __qm_mcr_querycongestion {
146114 + u32 __state[8];
146115 +};
146116 +struct qm_mcr_querycongestion {
146117 + u8 __reserved[30];
146118 + /* Access this struct using QM_MCR_QUERYCONGESTION() */
146119 + struct __qm_mcr_querycongestion state;
146120 +} __packed;
146121 +struct qm_mcr_querywq {
146122 + union {
146123 + u16 channel_wq; /* ignores wq (3 lsbits) */
146124 + struct {
146125 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146126 + u16 id:13; /* qm_channel */
146127 + u16 __reserved:3;
146128 +#else
146129 + u16 __reserved:3;
146130 + u16 id:13; /* qm_channel */
146131 +#endif
146132 + } __packed channel;
146133 + };
146134 + u8 __reserved[28];
146135 + u32 wq_len[8];
146136 +} __packed;
146137 +
146138 +/* QMAN CEETM Management Command Response */
146139 +struct qm_mcr_ceetm_lfqmt_config {
146140 + u8 __reserved1[62];
146141 +} __packed;
146142 +struct qm_mcr_ceetm_lfqmt_query {
146143 + u8 __reserved1[8];
146144 + u16 cqid;
146145 + u8 __reserved2[2];
146146 + u16 dctidx;
146147 + u8 __reserved3[2];
146148 + u16 ccgid;
146149 + u8 __reserved4[44];
146150 +} __packed;
146151 +
146152 +struct qm_mcr_ceetm_cq_config {
146153 + u8 __reserved1[62];
146154 +} __packed;
146155 +
146156 +struct qm_mcr_ceetm_cq_query {
146157 + u8 __reserved1[4];
146158 + u16 ccgid;
146159 + u16 state;
146160 + u32 pfdr_hptr:24;
146161 + u32 pfdr_tptr:24;
146162 + u16 od1_xsfdr;
146163 + u16 od2_xsfdr;
146164 + u16 od3_xsfdr;
146165 + u16 od4_xsfdr;
146166 + u16 od5_xsfdr;
146167 + u16 od6_xsfdr;
146168 + u16 ra1_xsfdr;
146169 + u16 ra2_xsfdr;
146170 + u8 __reserved2;
146171 + u32 frm_cnt:24;
146172 + u8 __reserved333[28];
146173 +} __packed;
146174 +
146175 +struct qm_mcr_ceetm_dct_config {
146176 + u8 __reserved1[62];
146177 +} __packed;
146178 +
146179 +struct qm_mcr_ceetm_dct_query {
146180 + u8 __reserved1[18];
146181 + u32 context_b;
146182 + u64 context_a;
146183 + u8 __reserved2[32];
146184 +} __packed;
146185 +
146186 +struct qm_mcr_ceetm_class_scheduler_config {
146187 + u8 __reserved1[62];
146188 +} __packed;
146189 +
146190 +struct qm_mcr_ceetm_class_scheduler_query {
146191 + u8 __reserved1[9];
146192 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146193 + u8 gpc_reserved:1;
146194 + u8 gpc_combine_flag:1;
146195 + u8 gpc_prio_b:3;
146196 + u8 gpc_prio_a:3;
146197 +#else
146198 + u8 gpc_prio_a:3;
146199 + u8 gpc_prio_b:3;
146200 + u8 gpc_combine_flag:1;
146201 + u8 gpc_reserved:1;
146202 +#endif
146203 + u16 crem;
146204 + u16 erem;
146205 + u8 w[8];
146206 + u8 __reserved2[5];
146207 + u32 wbfslist:24;
146208 + u32 d8;
146209 + u32 d9;
146210 + u32 d10;
146211 + u32 d11;
146212 + u32 d12;
146213 + u32 d13;
146214 + u32 d14;
146215 + u32 d15;
146216 +} __packed;
146217 +
146218 +struct qm_mcr_ceetm_mapping_shaper_tcfc_config {
146219 + u16 cid;
146220 + u8 __reserved2[60];
146221 +} __packed;
146222 +
146223 +struct qm_mcr_ceetm_mapping_shaper_tcfc_query {
146224 + u16 cid;
146225 + u8 __reserved1;
146226 + union {
146227 + struct {
146228 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146229 + u8 map_shaped:1;
146230 + u8 map_reserved:4;
146231 + u8 map_lni_id:3;
146232 +#else
146233 + u8 map_lni_id:3;
146234 + u8 map_reserved:4;
146235 + u8 map_shaped:1;
146236 +#endif
146237 + u8 __reserved2[58];
146238 + } __packed channel_mapping_query;
146239 + struct {
146240 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146241 + u8 map_reserved:5;
146242 + u8 map_lni_id:3;
146243 +#else
146244 + u8 map_lni_id:3;
146245 + u8 map_reserved:5;
146246 +#endif
146247 + u8 __reserved2[58];
146248 + } __packed sp_mapping_query;
146249 + struct {
146250 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146251 + u8 cpl:1;
146252 + u8 cpl_reserved:2;
146253 + u8 oal:5;
146254 +#else
146255 + u8 oal:5;
146256 + u8 cpl_reserved:2;
146257 + u8 cpl:1;
146258 +#endif
146259 + u32 crtcr:24;
146260 + u32 ertcr:24;
146261 + u16 crtbl;
146262 + u16 ertbl;
146263 + u8 mps;
146264 + u8 __reserved2[15];
146265 + u32 crat;
146266 + u32 erat;
146267 + u8 __reserved3[24];
146268 + } __packed shaper_query;
146269 + struct {
146270 + u8 __reserved1[11];
146271 + u64 lnitcfcc;
146272 + u8 __reserved3[40];
146273 + } __packed tcfc_query;
146274 + };
146275 +} __packed;
146276 +
146277 +struct qm_mcr_ceetm_ccgr_config {
146278 + u8 __reserved1[46];
146279 + union {
146280 + u8 __reserved2[8];
146281 + struct {
146282 + u16 timestamp;
146283 + u16 wr_porb_g;
146284 + u16 wr_prob_y;
146285 + u16 wr_prob_r;
146286 + } __packed test_write;
146287 + };
146288 + u8 __reserved3[8];
146289 +} __packed;
146290 +
146291 +struct qm_mcr_ceetm_ccgr_query {
146292 + u8 __reserved1[6];
146293 + union {
146294 + struct {
146295 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146296 + u8 ctl_reserved:1;
146297 + u8 ctl_wr_en_g:1;
146298 + u8 ctl_wr_en_y:1;
146299 + u8 ctl_wr_en_r:1;
146300 + u8 ctl_td_en:1;
146301 + u8 ctl_td_mode:1;
146302 + u8 ctl_cscn_en:1;
146303 + u8 ctl_mode:1;
146304 +#else
146305 + u8 ctl_mode:1;
146306 + u8 ctl_cscn_en:1;
146307 + u8 ctl_td_mode:1;
146308 + u8 ctl_td_en:1;
146309 + u8 ctl_wr_en_r:1;
146310 + u8 ctl_wr_en_y:1;
146311 + u8 ctl_wr_en_g:1;
146312 + u8 ctl_reserved:1;
146313 +#endif
146314 + u8 cdv;
146315 + u8 __reserved2[2];
146316 + u8 oal;
146317 + u8 __reserved3;
146318 + struct qm_cgr_cs_thres cs_thres;
146319 + struct qm_cgr_cs_thres cs_thres_x;
146320 + struct qm_cgr_cs_thres td_thres;
146321 + struct qm_cgr_wr_parm wr_parm_g;
146322 + struct qm_cgr_wr_parm wr_parm_y;
146323 + struct qm_cgr_wr_parm wr_parm_r;
146324 + u16 cscn_targ_dcp;
146325 + u8 dcp_lsn;
146326 + u64 i_cnt:40;
146327 + u8 __reserved4[3];
146328 + u64 a_cnt:40;
146329 + u32 cscn_targ_swp[4];
146330 + } __packed cm_query;
146331 + struct {
146332 + u8 dnc;
146333 + u8 dn0;
146334 + u8 dn1;
146335 + u64 dnba:40;
146336 + u8 __reserved2[2];
146337 + u16 dnth_0;
146338 + u8 __reserved3[2];
146339 + u16 dnth_1;
146340 + u8 __reserved4[10];
146341 + u16 dnacc_0;
146342 + u8 __reserved5[2];
146343 + u16 dnacc_1;
146344 + u8 __reserved6[24];
146345 + } __packed dn_query;
146346 + struct {
146347 + u8 __reserved2[24];
146348 + struct __qm_mcr_querycongestion state;
146349 + } __packed congestion_state;
146350 +
146351 + };
146352 +} __packed;
146353 +
146354 +struct qm_mcr_ceetm_cq_peek_pop_xsfdrread {
146355 + u8 stat;
146356 + u8 __reserved1[11];
146357 + u16 dctidx;
146358 + struct qm_fd fd;
146359 + u8 __reserved2[32];
146360 +} __packed;
146361 +
146362 +struct qm_mcr_ceetm_statistics_query {
146363 + u8 __reserved1[17];
146364 + u64 frm_cnt:40;
146365 + u8 __reserved2[2];
146366 + u64 byte_cnt:48;
146367 + u8 __reserved3[32];
146368 +} __packed;
146369 +
146370 +struct qm_mc_result {
146371 + u8 verb;
146372 + u8 result;
146373 + union {
146374 + struct qm_mcr_initfq initfq;
146375 + struct qm_mcr_queryfq queryfq;
146376 + struct qm_mcr_queryfq_np queryfq_np;
146377 + struct qm_mcr_alterfq alterfq;
146378 + struct qm_mcr_initcgr initcgr;
146379 + struct qm_mcr_cgrtestwrite cgrtestwrite;
146380 + struct qm_mcr_querycgr querycgr;
146381 + struct qm_mcr_querycongestion querycongestion;
146382 + struct qm_mcr_querywq querywq;
146383 + struct qm_mcr_ceetm_lfqmt_config lfqmt_config;
146384 + struct qm_mcr_ceetm_lfqmt_query lfqmt_query;
146385 + struct qm_mcr_ceetm_cq_config cq_config;
146386 + struct qm_mcr_ceetm_cq_query cq_query;
146387 + struct qm_mcr_ceetm_dct_config dct_config;
146388 + struct qm_mcr_ceetm_dct_query dct_query;
146389 + struct qm_mcr_ceetm_class_scheduler_config csch_config;
146390 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
146391 + struct qm_mcr_ceetm_mapping_shaper_tcfc_config mst_config;
146392 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query mst_query;
146393 + struct qm_mcr_ceetm_ccgr_config ccgr_config;
146394 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
146395 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
146396 + struct qm_mcr_ceetm_statistics_query stats_query;
146397 + };
146398 +} __packed;
146399 +
146400 +#define QM_MCR_VERB_RRID 0x80
146401 +#define QM_MCR_VERB_MASK QM_MCC_VERB_MASK
146402 +#define QM_MCR_VERB_INITFQ_PARKED QM_MCC_VERB_INITFQ_PARKED
146403 +#define QM_MCR_VERB_INITFQ_SCHED QM_MCC_VERB_INITFQ_SCHED
146404 +#define QM_MCR_VERB_QUERYFQ QM_MCC_VERB_QUERYFQ
146405 +#define QM_MCR_VERB_QUERYFQ_NP QM_MCC_VERB_QUERYFQ_NP
146406 +#define QM_MCR_VERB_QUERYWQ QM_MCC_VERB_QUERYWQ
146407 +#define QM_MCR_VERB_QUERYWQ_DEDICATED QM_MCC_VERB_QUERYWQ_DEDICATED
146408 +#define QM_MCR_VERB_ALTER_SCHED QM_MCC_VERB_ALTER_SCHED
146409 +#define QM_MCR_VERB_ALTER_FE QM_MCC_VERB_ALTER_FE
146410 +#define QM_MCR_VERB_ALTER_RETIRE QM_MCC_VERB_ALTER_RETIRE
146411 +#define QM_MCR_VERB_ALTER_OOS QM_MCC_VERB_ALTER_OOS
146412 +#define QM_MCR_RESULT_NULL 0x00
146413 +#define QM_MCR_RESULT_OK 0xf0
146414 +#define QM_MCR_RESULT_ERR_FQID 0xf1
146415 +#define QM_MCR_RESULT_ERR_FQSTATE 0xf2
146416 +#define QM_MCR_RESULT_ERR_NOTEMPTY 0xf3 /* OOS fails if FQ is !empty */
146417 +#define QM_MCR_RESULT_ERR_BADCHANNEL 0xf4
146418 +#define QM_MCR_RESULT_PENDING 0xf8
146419 +#define QM_MCR_RESULT_ERR_BADCOMMAND 0xff
146420 +#define QM_MCR_NP_STATE_FE 0x10
146421 +#define QM_MCR_NP_STATE_R 0x08
146422 +#define QM_MCR_NP_STATE_MASK 0x07 /* Reads FQD::STATE; */
146423 +#define QM_MCR_NP_STATE_OOS 0x00
146424 +#define QM_MCR_NP_STATE_RETIRED 0x01
146425 +#define QM_MCR_NP_STATE_TEN_SCHED 0x02
146426 +#define QM_MCR_NP_STATE_TRU_SCHED 0x03
146427 +#define QM_MCR_NP_STATE_PARKED 0x04
146428 +#define QM_MCR_NP_STATE_ACTIVE 0x05
146429 +#define QM_MCR_NP_PTR_MASK 0x07ff /* for RA[12] & OD[123] */
146430 +#define QM_MCR_NP_RA1_NRA(v) (((v) >> 14) & 0x3) /* FQD::NRA */
146431 +#define QM_MCR_NP_RA2_IT(v) (((v) >> 14) & 0x1) /* FQD::IT */
146432 +#define QM_MCR_NP_OD1_NOD(v) (((v) >> 14) & 0x3) /* FQD::NOD */
146433 +#define QM_MCR_NP_OD3_NPC(v) (((v) >> 14) & 0x3) /* FQD::NPC */
146434 +#define QM_MCR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
146435 +#define QM_MCR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
146436 +/* This extracts the state for congestion group 'n' from a query response.
146437 + * Eg.
146438 + * u8 cgr = [...];
146439 + * struct qm_mc_result *res = [...];
146440 + * printf("congestion group %d congestion state: %d\n", cgr,
146441 + * QM_MCR_QUERYCONGESTION(&res->querycongestion.state, cgr));
146442 + */
146443 +#define __CGR_WORD(num) (num >> 5)
146444 +#define __CGR_SHIFT(num) (num & 0x1f)
146445 +#define __CGR_NUM (sizeof(struct __qm_mcr_querycongestion) << 3)
146446 +static inline int QM_MCR_QUERYCONGESTION(struct __qm_mcr_querycongestion *p,
146447 + u8 cgr)
146448 +{
146449 + return p->__state[__CGR_WORD(cgr)] & (0x80000000 >> __CGR_SHIFT(cgr));
146450 +}
146451 +
146452 +
146453 +/*********************/
146454 +/* Utility interface */
146455 +/*********************/
146456 +
146457 +/* Represents an allocator over a range of FQIDs. NB, accesses are not locked,
146458 + * spinlock them yourself if needed. */
146459 +struct qman_fqid_pool;
146460 +
146461 +/* Create/destroy a FQID pool, num must be a multiple of 32. NB, _destroy()
146462 + * always succeeds, but returns non-zero if there were "leaked" FQID
146463 + * allocations. */
146464 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num);
146465 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool);
146466 +/* Alloc/free a FQID from the range. _alloc() returns zero for success. */
146467 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid);
146468 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid);
146469 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool);
146470 +
146471 +/*******************************************************************/
146472 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
146473 +/*******************************************************************/
146474 +
146475 + /* Portal and Frame Queues */
146476 + /* ----------------------- */
146477 +/* Represents a managed portal */
146478 +struct qman_portal;
146479 +
146480 +/* This object type represents Qman frame queue descriptors (FQD), it is
146481 + * cacheline-aligned, and initialised by qman_create_fq(). The structure is
146482 + * defined further down. */
146483 +struct qman_fq;
146484 +
146485 +/* This object type represents a Qman congestion group, it is defined further
146486 + * down. */
146487 +struct qman_cgr;
146488 +
146489 +struct qman_portal_config {
146490 + /* If the caller enables DQRR stashing (and thus wishes to operate the
146491 + * portal from only one cpu), this is the logical CPU that the portal
146492 + * will stash to. Whether stashing is enabled or not, this setting is
146493 + * also used for any "core-affine" portals, ie. default portals
146494 + * associated to the corresponding cpu. -1 implies that there is no core
146495 + * affinity configured. */
146496 + int cpu;
146497 + /* portal interrupt line */
146498 + int irq;
146499 + /* the unique index of this portal */
146500 + u32 index;
146501 + /* Is this portal shared? (If so, it has coarser locking and demuxes
146502 + * processing on behalf of other CPUs.) */
146503 + int is_shared;
146504 + /* The portal's dedicated channel id, use this value for initialising
146505 + * frame queues to target this portal when scheduled. */
146506 + u16 channel;
146507 + /* A mask of which pool channels this portal has dequeue access to
146508 + * (using QM_SDQCR_CHANNELS_POOL(n) for the bitmask) */
146509 + u32 pools;
146510 +};
146511 +
146512 +/* This enum, and the callback type that returns it, are used when handling
146513 + * dequeued frames via DQRR. Note that for "null" callbacks registered with the
146514 + * portal object (for handling dequeues that do not demux because contextB is
146515 + * NULL), the return value *MUST* be qman_cb_dqrr_consume. */
146516 +enum qman_cb_dqrr_result {
146517 + /* DQRR entry can be consumed */
146518 + qman_cb_dqrr_consume,
146519 + /* Like _consume, but requests parking - FQ must be held-active */
146520 + qman_cb_dqrr_park,
146521 + /* Does not consume, for DCA mode only. This allows out-of-order
146522 + * consumes by explicit calls to qman_dca() and/or the use of implicit
146523 + * DCA via EQCR entries. */
146524 + qman_cb_dqrr_defer,
146525 + /* Stop processing without consuming this ring entry. Exits the current
146526 + * qman_poll_dqrr() or interrupt-handling, as appropriate. If within an
146527 + * interrupt handler, the callback would typically call
146528 + * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value,
146529 + * otherwise the interrupt will reassert immediately. */
146530 + qman_cb_dqrr_stop,
146531 + /* Like qman_cb_dqrr_stop, but consumes the current entry. */
146532 + qman_cb_dqrr_consume_stop
146533 +};
146534 +typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm,
146535 + struct qman_fq *fq,
146536 + const struct qm_dqrr_entry *dqrr);
146537 +
146538 +/* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They
146539 + * are always consumed after the callback returns. */
146540 +typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq,
146541 + const struct qm_mr_entry *msg);
146542 +
146543 +/* This callback type is used when handling DCP ERNs */
146544 +typedef void (*qman_cb_dc_ern)(struct qman_portal *qm,
146545 + const struct qm_mr_entry *msg);
146546 +
146547 +/* s/w-visible states. Ie. tentatively scheduled + truly scheduled + active +
146548 + * held-active + held-suspended are just "sched". Things like "retired" will not
146549 + * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until
146550 + * then, to indicate it's completing and to gate attempts to retry the retire
146551 + * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's
146552 + * technically impossible in the case of enqueue DCAs (which refer to DQRR ring
146553 + * index rather than the FQ that ring entry corresponds to), so repeated park
146554 + * commands are allowed (if you're silly enough to try) but won't change FQ
146555 + * state, and the resulting park notifications move FQs from "sched" to
146556 + * "parked". */
146557 +enum qman_fq_state {
146558 + qman_fq_state_oos,
146559 + qman_fq_state_parked,
146560 + qman_fq_state_sched,
146561 + qman_fq_state_retired
146562 +};
146563 +
146564 +/* Frame queue objects (struct qman_fq) are stored within memory passed to
146565 + * qman_create_fq(), as this allows stashing of caller-provided demux callback
146566 + * pointers at no extra cost to stashing of (driver-internal) FQ state. If the
146567 + * caller wishes to add per-FQ state and have it benefit from dequeue-stashing,
146568 + * they should;
146569 + *
146570 + * (a) extend the qman_fq structure with their state; eg.
146571 + *
146572 + * // myfq is allocated and driver_fq callbacks filled in;
146573 + * struct my_fq {
146574 + * struct qman_fq base;
146575 + * int an_extra_field;
146576 + * [ ... add other fields to be associated with each FQ ...]
146577 + * } *myfq = some_my_fq_allocator();
146578 + * struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base);
146579 + *
146580 + * // in a dequeue callback, access extra fields from 'fq' via a cast;
146581 + * struct my_fq *myfq = (struct my_fq *)fq;
146582 + * do_something_with(myfq->an_extra_field);
146583 + * [...]
146584 + *
146585 + * (b) when and if configuring the FQ for context stashing, specify how ever
146586 + * many cachelines are required to stash 'struct my_fq', to accelerate not
146587 + * only the Qman driver but the callback as well.
146588 + */
146589 +
146590 +struct qman_fq_cb {
146591 + qman_cb_dqrr dqrr; /* for dequeued frames */
146592 + qman_cb_mr ern; /* for s/w ERNs */
146593 + qman_cb_mr fqs; /* frame-queue state changes*/
146594 +};
146595 +
146596 +struct qman_fq {
146597 + /* Caller of qman_create_fq() provides these demux callbacks */
146598 + struct qman_fq_cb cb;
146599 + /* These are internal to the driver, don't touch. In particular, they
146600 + * may change, be removed, or extended (so you shouldn't rely on
146601 + * sizeof(qman_fq) being a constant). */
146602 + spinlock_t fqlock;
146603 + u32 fqid;
146604 + volatile unsigned long flags;
146605 + enum qman_fq_state state;
146606 + int cgr_groupid;
146607 + struct rb_node node;
146608 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
146609 + u32 key;
146610 +#endif
146611 +};
146612 +
146613 +/* This callback type is used when handling congestion group entry/exit.
146614 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. */
146615 +typedef void (*qman_cb_cgr)(struct qman_portal *qm,
146616 + struct qman_cgr *cgr, int congested);
146617 +
146618 +struct qman_cgr {
146619 + /* Set these prior to qman_create_cgr() */
146620 + u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/
146621 + qman_cb_cgr cb;
146622 + /* These are private to the driver */
146623 + u16 chan; /* portal channel this object is created on */
146624 + struct list_head node;
146625 +};
146626 +
146627 +/* Flags to qman_create_fq() */
146628 +#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */
146629 +#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */
146630 +#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */
146631 +#define QMAN_FQ_FLAG_LOCKED 0x00000008 /* multi-core locking */
146632 +#define QMAN_FQ_FLAG_AS_IS 0x00000010 /* query h/w state */
146633 +#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */
146634 +
146635 +/* Flags to qman_destroy_fq() */
146636 +#define QMAN_FQ_DESTROY_PARKED 0x00000001 /* FQ can be parked or OOS */
146637 +
146638 +/* Flags from qman_fq_state() */
146639 +#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */
146640 +#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */
146641 +#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */
146642 +#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */
146643 +#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */
146644 +#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */
146645 +
146646 +/* Flags to qman_init_fq() */
146647 +#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */
146648 +#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */
146649 +
146650 +/* Flags to qman_volatile_dequeue() */
146651 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
146652 +#define QMAN_VOLATILE_FLAG_WAIT 0x00000001 /* wait if VDQCR is in use */
146653 +#define QMAN_VOLATILE_FLAG_WAIT_INT 0x00000002 /* if wait, interruptible? */
146654 +#define QMAN_VOLATILE_FLAG_FINISH 0x00000004 /* wait till VDQCR completes */
146655 +#endif
146656 +
146657 +/* Flags to qman_enqueue(). NB, the strange numbering is to align with hardware,
146658 + * bit-wise. (NB: the PME API is sensitive to these precise numberings too, so
146659 + * any change here should be audited in PME.) */
146660 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
146661 +#define QMAN_ENQUEUE_FLAG_WAIT 0x00010000 /* wait if EQCR is full */
146662 +#define QMAN_ENQUEUE_FLAG_WAIT_INT 0x00020000 /* if wait, interruptible? */
146663 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
146664 +#define QMAN_ENQUEUE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
146665 +#endif
146666 +#endif
146667 +#define QMAN_ENQUEUE_FLAG_WATCH_CGR 0x00080000 /* watch congestion state */
146668 +#define QMAN_ENQUEUE_FLAG_DCA 0x00008000 /* perform enqueue-DCA */
146669 +#define QMAN_ENQUEUE_FLAG_DCA_PARK 0x00004000 /* If DCA, requests park */
146670 +#define QMAN_ENQUEUE_FLAG_DCA_PTR(p) /* If DCA, p is DQRR entry */ \
146671 + (((u32)(p) << 2) & 0x00000f00)
146672 +#define QMAN_ENQUEUE_FLAG_C_GREEN 0x00000000 /* choose one C_*** flag */
146673 +#define QMAN_ENQUEUE_FLAG_C_YELLOW 0x00000008
146674 +#define QMAN_ENQUEUE_FLAG_C_RED 0x00000010
146675 +#define QMAN_ENQUEUE_FLAG_C_OVERRIDE 0x00000018
146676 +/* For the ORP-specific qman_enqueue_orp() variant;
146677 + * - this flag indicates "Not Last In Sequence", ie. all but the final fragment
146678 + * of a frame. */
146679 +#define QMAN_ENQUEUE_FLAG_NLIS 0x01000000
146680 +/* - this flag performs no enqueue but fills in an ORP sequence number that
146681 + * would otherwise block it (eg. if a frame has been dropped). */
146682 +#define QMAN_ENQUEUE_FLAG_HOLE 0x02000000
146683 +/* - this flag performs no enqueue but advances NESN to the given sequence
146684 + * number. */
146685 +#define QMAN_ENQUEUE_FLAG_NESN 0x04000000
146686 +
146687 +/* Flags to qman_modify_cgr() */
146688 +#define QMAN_CGR_FLAG_USE_INIT 0x00000001
146689 +#define QMAN_CGR_MODE_FRAME 0x00000001
146690 +
146691 + /* Portal Management */
146692 + /* ----------------- */
146693 +/**
146694 + * qman_get_portal_config - get portal configuration settings
146695 + *
146696 + * This returns a read-only view of the current cpu's affine portal settings.
146697 + */
146698 +const struct qman_portal_config *qman_get_portal_config(void);
146699 +
146700 +/**
146701 + * qman_irqsource_get - return the portal work that is interrupt-driven
146702 + *
146703 + * Returns a bitmask of QM_PIRQ_**I processing sources that are currently
146704 + * enabled for interrupt handling on the current cpu's affine portal. These
146705 + * sources will trigger the portal interrupt and the interrupt handler (or a
146706 + * tasklet/bottom-half it defers to) will perform the corresponding processing
146707 + * work. The qman_poll_***() functions will only process sources that are not in
146708 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
146709 + * this always returns zero.
146710 + */
146711 +u32 qman_irqsource_get(void);
146712 +
146713 +/**
146714 + * qman_irqsource_add - add processing sources to be interrupt-driven
146715 + * @bits: bitmask of QM_PIRQ_**I processing sources
146716 + *
146717 + * Adds processing sources that should be interrupt-driven (rather than
146718 + * processed via qman_poll_***() functions). Returns zero for success, or
146719 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU.
146720 + */
146721 +int qman_irqsource_add(u32 bits);
146722 +
146723 +/**
146724 + * qman_irqsource_remove - remove processing sources from being interrupt-driven
146725 + * @bits: bitmask of QM_PIRQ_**I processing sources
146726 + *
146727 + * Removes processing sources from being interrupt-driven, so that they will
146728 + * instead be processed via qman_poll_***() functions. Returns zero for success,
146729 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU.
146730 + */
146731 +int qman_irqsource_remove(u32 bits);
146732 +
146733 +/**
146734 + * qman_affine_cpus - return a mask of cpus that have affine portals
146735 + */
146736 +const cpumask_t *qman_affine_cpus(void);
146737 +
146738 +/**
146739 + * qman_affine_channel - return the channel ID of an portal
146740 + * @cpu: the cpu whose affine portal is the subject of the query
146741 + *
146742 + * If @cpu is -1, the affine portal for the current CPU will be used. It is a
146743 + * bug to call this function for any value of @cpu (other than -1) that is not a
146744 + * member of the mask returned from qman_affine_cpus().
146745 + */
146746 +u16 qman_affine_channel(int cpu);
146747 +
146748 +/**
146749 + * qman_get_affine_portal - return the portal pointer affine to cpu
146750 + * @cpu: the cpu whose affine portal is the subject of the query
146751 + *
146752 + */
146753 +void *qman_get_affine_portal(int cpu);
146754 +
146755 +/**
146756 + * qman_poll_dqrr - process DQRR (fast-path) entries
146757 + * @limit: the maximum number of DQRR entries to process
146758 + *
146759 + * Use of this function requires that DQRR processing not be interrupt-driven.
146760 + * Ie. the value returned by qman_irqsource_get() should not include
146761 + * QM_PIRQ_DQRI. If the current CPU is sharing a portal hosted on another CPU,
146762 + * this function will return -EINVAL, otherwise the return value is >=0 and
146763 + * represents the number of DQRR entries processed.
146764 + */
146765 +int qman_poll_dqrr(unsigned int limit);
146766 +
146767 +/**
146768 + * qman_poll_slow - process anything (except DQRR) that isn't interrupt-driven.
146769 + *
146770 + * This function does any portal processing that isn't interrupt-driven. If the
146771 + * current CPU is sharing a portal hosted on another CPU, this function will
146772 + * return (u32)-1, otherwise the return value is a bitmask of QM_PIRQ_* sources
146773 + * indicating what interrupt sources were actually processed by the call.
146774 + */
146775 +u32 qman_poll_slow(void);
146776 +
146777 +/**
146778 + * qman_poll - legacy wrapper for qman_poll_dqrr() and qman_poll_slow()
146779 + *
146780 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
146781 + * affine portal. There are two classes of portal processing in question;
146782 + * fast-path (which involves demuxing dequeue ring (DQRR) entries and tracking
146783 + * enqueue ring (EQCR) consumption), and slow-path (which involves EQCR
146784 + * thresholds, congestion state changes, etc). This function does whatever
146785 + * processing is not triggered by interrupts.
146786 + *
146787 + * Note, if DQRR and some slow-path processing are poll-driven (rather than
146788 + * interrupt-driven) then this function uses a heuristic to determine how often
146789 + * to run slow-path processing - as slow-path processing introduces at least a
146790 + * minimum latency each time it is run, whereas fast-path (DQRR) processing is
146791 + * close to zero-cost if there is no work to be done. Applications can tune this
146792 + * behaviour themselves by using qman_poll_dqrr() and qman_poll_slow() directly
146793 + * rather than going via this wrapper.
146794 + */
146795 +void qman_poll(void);
146796 +
146797 +/**
146798 + * qman_stop_dequeues - Stop h/w dequeuing to the s/w portal
146799 + *
146800 + * Disables DQRR processing of the portal. This is reference-counted, so
146801 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
146802 + * truly re-enable dequeuing.
146803 + */
146804 +void qman_stop_dequeues(void);
146805 +
146806 +/**
146807 + * qman_start_dequeues - (Re)start h/w dequeuing to the s/w portal
146808 + *
146809 + * Enables DQRR processing of the portal. This is reference-counted, so
146810 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
146811 + * truly re-enable dequeuing.
146812 + */
146813 +void qman_start_dequeues(void);
146814 +
146815 +/**
146816 + * qman_static_dequeue_add - Add pool channels to the portal SDQCR
146817 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
146818 + *
146819 + * Adds a set of pool channels to the portal's static dequeue command register
146820 + * (SDQCR). The requested pools are limited to those the portal has dequeue
146821 + * access to.
146822 + */
146823 +void qman_static_dequeue_add(u32 pools);
146824 +
146825 +/**
146826 + * qman_static_dequeue_del - Remove pool channels from the portal SDQCR
146827 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
146828 + *
146829 + * Removes a set of pool channels from the portal's static dequeue command
146830 + * register (SDQCR). The requested pools are limited to those the portal has
146831 + * dequeue access to.
146832 + */
146833 +void qman_static_dequeue_del(u32 pools);
146834 +
146835 +/**
146836 + * qman_static_dequeue_get - return the portal's current SDQCR
146837 + *
146838 + * Returns the portal's current static dequeue command register (SDQCR). The
146839 + * entire register is returned, so if only the currently-enabled pool channels
146840 + * are desired, mask the return value with QM_SDQCR_CHANNELS_POOL_MASK.
146841 + */
146842 +u32 qman_static_dequeue_get(void);
146843 +
146844 +/**
146845 + * qman_dca - Perform a Discrete Consumption Acknowledgement
146846 + * @dq: the DQRR entry to be consumed
146847 + * @park_request: indicates whether the held-active @fq should be parked
146848 + *
146849 + * Only allowed in DCA-mode portals, for DQRR entries whose handler callback had
146850 + * previously returned 'qman_cb_dqrr_defer'. NB, as with the other APIs, this
146851 + * does not take a 'portal' argument but implies the core affine portal from the
146852 + * cpu that is currently executing the function. For reasons of locking, this
146853 + * function must be called from the same CPU as that which processed the DQRR
146854 + * entry in the first place.
146855 + */
146856 +void qman_dca(struct qm_dqrr_entry *dq, int park_request);
146857 +
146858 +/**
146859 + * qman_eqcr_is_empty - Determine if portal's EQCR is empty
146860 + *
146861 + * For use in situations where a cpu-affine caller needs to determine when all
146862 + * enqueues for the local portal have been processed by Qman but can't use the
146863 + * QMAN_ENQUEUE_FLAG_WAIT_SYNC flag to do this from the final qman_enqueue().
146864 + * The function forces tracking of EQCR consumption (which normally doesn't
146865 + * happen until enqueue processing needs to find space to put new enqueue
146866 + * commands), and returns zero if the ring still has unprocessed entries,
146867 + * non-zero if it is empty.
146868 + */
146869 +int qman_eqcr_is_empty(void);
146870 +
146871 +/**
146872 + * qman_set_dc_ern - Set the handler for DCP enqueue rejection notifications
146873 + * @handler: callback for processing DCP ERNs
146874 + * @affine: whether this handler is specific to the locally affine portal
146875 + *
146876 + * If a hardware block's interface to Qman (ie. its direct-connect portal, or
146877 + * DCP) is configured not to receive enqueue rejections, then any enqueues
146878 + * through that DCP that are rejected will be sent to a given software portal.
146879 + * If @affine is non-zero, then this handler will only be used for DCP ERNs
146880 + * received on the portal affine to the current CPU. If multiple CPUs share a
146881 + * portal and they all call this function, they will be setting the handler for
146882 + * the same portal! If @affine is zero, then this handler will be global to all
146883 + * portals handled by this instance of the driver. Only those portals that do
146884 + * not have their own affine handler will use the global handler.
146885 + */
146886 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine);
146887 +
146888 + /* FQ management */
146889 + /* ------------- */
146890 +/**
146891 + * qman_create_fq - Allocates a FQ
146892 + * @fqid: the index of the FQD to encapsulate, must be "Out of Service"
146893 + * @flags: bit-mask of QMAN_FQ_FLAG_*** options
146894 + * @fq: memory for storing the 'fq', with callbacks filled in
146895 + *
146896 + * Creates a frame queue object for the given @fqid, unless the
146897 + * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is
146898 + * dynamically allocated (or the function fails if none are available). Once
146899 + * created, the caller should not touch the memory at 'fq' except as extended to
146900 + * adjacent memory for user-defined fields (see the definition of "struct
146901 + * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to
146902 + * pre-existing frame-queues that aren't to be otherwise interfered with, it
146903 + * prevents all other modifications to the frame queue. The TO_DCPORTAL flag
146904 + * causes the driver to honour any contextB modifications requested in the
146905 + * qm_init_fq() API, as this indicates the frame queue will be consumed by a
146906 + * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by
146907 + * software portals, the contextB field is controlled by the driver and can't be
146908 + * modified by the caller. If the AS_IS flag is specified, management commands
146909 + * will be used on portal @p to query state for frame queue @fqid and construct
146910 + * a frame queue object based on that, rather than assuming/requiring that it be
146911 + * Out of Service.
146912 + */
146913 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq);
146914 +
146915 +/**
146916 + * qman_destroy_fq - Deallocates a FQ
146917 + * @fq: the frame queue object to release
146918 + * @flags: bit-mask of QMAN_FQ_FREE_*** options
146919 + *
146920 + * The memory for this frame queue object ('fq' provided in qman_create_fq()) is
146921 + * not deallocated but the caller regains ownership, to do with as desired. The
146922 + * FQ must be in the 'out-of-service' state unless the QMAN_FQ_FREE_PARKED flag
146923 + * is specified, in which case it may also be in the 'parked' state.
146924 + */
146925 +void qman_destroy_fq(struct qman_fq *fq, u32 flags);
146926 +
146927 +/**
146928 + * qman_fq_fqid - Queries the frame queue ID of a FQ object
146929 + * @fq: the frame queue object to query
146930 + */
146931 +u32 qman_fq_fqid(struct qman_fq *fq);
146932 +
146933 +/**
146934 + * qman_fq_state - Queries the state of a FQ object
146935 + * @fq: the frame queue object to query
146936 + * @state: pointer to state enum to return the FQ scheduling state
146937 + * @flags: pointer to state flags to receive QMAN_FQ_STATE_*** bitmask
146938 + *
146939 + * Queries the state of the FQ object, without performing any h/w commands.
146940 + * This captures the state, as seen by the driver, at the time the function
146941 + * executes.
146942 + */
146943 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags);
146944 +
146945 +/**
146946 + * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled"
146947 + * @fq: the frame queue object to modify, must be 'parked' or new.
146948 + * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options
146949 + * @opts: the FQ-modification settings, as defined in the low-level API
146950 + *
146951 + * The @opts parameter comes from the low-level portal API. Select
146952 + * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled
146953 + * rather than parked. NB, @opts can be NULL.
146954 + *
146955 + * Note that some fields and options within @opts may be ignored or overwritten
146956 + * by the driver;
146957 + * 1. the 'count' and 'fqid' fields are always ignored (this operation only
146958 + * affects one frame queue: @fq).
146959 + * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated
146960 + * 'fqd' structure's 'context_b' field are sometimes overwritten;
146961 + * - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is
146962 + * initialised to a value used by the driver for demux.
146963 + * - if context_b is initialised for demux, so is context_a in case stashing
146964 + * is requested (see item 4).
146965 + * (So caller control of context_b is only possible for TO_DCPORTAL frame queue
146966 + * objects.)
146967 + * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's
146968 + * 'dest::channel' field will be overwritten to match the portal used to issue
146969 + * the command. If the WE_DESTWQ write-enable bit had already been set by the
146970 + * caller, the channel workqueue will be left as-is, otherwise the write-enable
146971 + * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag
146972 + * isn't set, the destination channel/workqueue fields and the write-enable bit
146973 + * are left as-is.
146974 + * 4. if the driver overwrites context_a/b for demux, then if
146975 + * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite
146976 + * context_a.address fields and will leave the stashing fields provided by the
146977 + * user alone, otherwise it will zero out the context_a.stashing fields.
146978 + */
146979 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts);
146980 +
146981 +/**
146982 + * qman_schedule_fq - Schedules a FQ
146983 + * @fq: the frame queue object to schedule, must be 'parked'
146984 + *
146985 + * Schedules the frame queue, which must be Parked, which takes it to
146986 + * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level.
146987 + */
146988 +int qman_schedule_fq(struct qman_fq *fq);
146989 +
146990 +/**
146991 + * qman_retire_fq - Retires a FQ
146992 + * @fq: the frame queue object to retire
146993 + * @flags: FQ flags (as per qman_fq_state) if retirement completes immediately
146994 + *
146995 + * Retires the frame queue. This returns zero if it succeeds immediately, +1 if
146996 + * the retirement was started asynchronously, otherwise it returns negative for
146997 + * failure. When this function returns zero, @flags is set to indicate whether
146998 + * the retired FQ is empty and/or whether it has any ORL fragments (to show up
146999 + * as ERNs). Otherwise the corresponding flags will be known when a subsequent
147000 + * FQRN message shows up on the portal's message ring.
147001 + *
147002 + * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or
147003 + * Active state), the completion will be via the message ring as a FQRN - but
147004 + * the corresponding callback may occur before this function returns!! Ie. the
147005 + * caller should be prepared to accept the callback as the function is called,
147006 + * not only once it has returned.
147007 + */
147008 +int qman_retire_fq(struct qman_fq *fq, u32 *flags);
147009 +
147010 +/**
147011 + * qman_oos_fq - Puts a FQ "out of service"
147012 + * @fq: the frame queue object to be put out-of-service, must be 'retired'
147013 + *
147014 + * The frame queue must be retired and empty, and if any order restoration list
147015 + * was released as ERNs at the time of retirement, they must all be consumed.
147016 + */
147017 +int qman_oos_fq(struct qman_fq *fq);
147018 +
147019 +/**
147020 + * qman_fq_flow_control - Set the XON/XOFF state of a FQ
147021 + * @fq: the frame queue object to be set to XON/XOFF state, must not be 'oos',
147022 + * or 'retired' or 'parked' state
147023 + * @xon: boolean to set fq in XON or XOFF state
147024 + *
147025 + * The frame should be in Tentatively Scheduled state or Truly Schedule sate,
147026 + * otherwise the IFSI interrupt will be asserted.
147027 + */
147028 +int qman_fq_flow_control(struct qman_fq *fq, int xon);
147029 +
147030 +/**
147031 + * qman_query_fq - Queries FQD fields (via h/w query command)
147032 + * @fq: the frame queue object to be queried
147033 + * @fqd: storage for the queried FQD fields
147034 + */
147035 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd);
147036 +
147037 +/**
147038 + * qman_query_fq_np - Queries non-programmable FQD fields
147039 + * @fq: the frame queue object to be queried
147040 + * @np: storage for the queried FQD fields
147041 + */
147042 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np);
147043 +
147044 +/**
147045 + * qman_query_wq - Queries work queue lengths
147046 + * @query_dedicated: If non-zero, query length of WQs in the channel dedicated
147047 + * to this software portal. Otherwise, query length of WQs in a
147048 + * channel specified in wq.
147049 + * @wq: storage for the queried WQs lengths. Also specified the channel to
147050 + * to query if query_dedicated is zero.
147051 + */
147052 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq);
147053 +
147054 +/**
147055 + * qman_volatile_dequeue - Issue a volatile dequeue command
147056 + * @fq: the frame queue object to dequeue from
147057 + * @flags: a bit-mask of QMAN_VOLATILE_FLAG_*** options
147058 + * @vdqcr: bit mask of QM_VDQCR_*** options, as per qm_dqrr_vdqcr_set()
147059 + *
147060 + * Attempts to lock access to the portal's VDQCR volatile dequeue functionality.
147061 + * The function will block and sleep if QMAN_VOLATILE_FLAG_WAIT is specified and
147062 + * the VDQCR is already in use, otherwise returns non-zero for failure. If
147063 + * QMAN_VOLATILE_FLAG_FINISH is specified, the function will only return once
147064 + * the VDQCR command has finished executing (ie. once the callback for the last
147065 + * DQRR entry resulting from the VDQCR command has been called). If not using
147066 + * the FINISH flag, completion can be determined either by detecting the
147067 + * presence of the QM_DQRR_STAT_UNSCHEDULED and QM_DQRR_STAT_DQCR_EXPIRED bits
147068 + * in the "stat" field of the "struct qm_dqrr_entry" passed to the FQ's dequeue
147069 + * callback, or by waiting for the QMAN_FQ_STATE_VDQCR bit to disappear from the
147070 + * "flags" retrieved from qman_fq_state().
147071 + */
147072 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags, u32 vdqcr);
147073 +
147074 +/**
147075 + * qman_enqueue - Enqueue a frame to a frame queue
147076 + * @fq: the frame queue object to enqueue to
147077 + * @fd: a descriptor of the frame to be enqueued
147078 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147079 + *
147080 + * Fills an entry in the EQCR of portal @qm to enqueue the frame described by
147081 + * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid'
147082 + * field is ignored. The return value is non-zero on error, such as ring full
147083 + * (and FLAG_WAIT not specified), congestion avoidance (FLAG_WATCH_CGR
147084 + * specified), etc. If the ring is full and FLAG_WAIT is specified, this
147085 + * function will block. If FLAG_INTERRUPT is set, the EQCI bit of the portal
147086 + * interrupt will assert when Qman consumes the EQCR entry (subject to "status
147087 + * disable", "enable", and "inhibit" registers). If FLAG_DCA is set, Qman will
147088 + * perform an implied "discrete consumption acknowledgement" on the dequeue
147089 + * ring's (DQRR) entry, at the ring index specified by the FLAG_DCA_IDX(x)
147090 + * macro. (As an alternative to issuing explicit DCA actions on DQRR entries,
147091 + * this implicit DCA can delay the release of a "held active" frame queue
147092 + * corresponding to a DQRR entry until Qman consumes the EQCR entry - providing
147093 + * order-preservation semantics in packet-forwarding scenarios.) If FLAG_DCA is
147094 + * set, then FLAG_DCA_PARK can also be set to imply that the DQRR consumption
147095 + * acknowledgement should "park request" the "held active" frame queue. Ie.
147096 + * when the portal eventually releases that frame queue, it will be left in the
147097 + * Parked state rather than Tentatively Scheduled or Truly Scheduled. If the
147098 + * portal is watching congestion groups, the QMAN_ENQUEUE_FLAG_WATCH_CGR flag
147099 + * is requested, and the FQ is a member of a congestion group, then this
147100 + * function returns -EAGAIN if the congestion group is currently congested.
147101 + * Note, this does not eliminate ERNs, as the async interface means we can be
147102 + * sending enqueue commands to an un-congested FQ that becomes congested before
147103 + * the enqueue commands are processed, but it does minimise needless thrashing
147104 + * of an already busy hardware resource by throttling many of the to-be-dropped
147105 + * enqueues "at the source".
147106 + */
147107 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags);
147108 +
147109 +typedef int (*qman_cb_precommit) (void *arg);
147110 +/**
147111 + * qman_enqueue_precommit - Enqueue a frame to a frame queue and call cb
147112 + * @fq: the frame queue object to enqueue to
147113 + * @fd: a descriptor of the frame to be enqueued
147114 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147115 + * @cb: user supplied callback function to invoke before writing commit verb.
147116 + * @cb_arg: callback function argument
147117 + *
147118 + * This is similar to qman_enqueue except that it will invoke a user supplied
147119 + * callback function just before writng the commit verb. This is useful
147120 + * when the user want to do something *just before* enqueuing the request and
147121 + * the enqueue can't fail.
147122 + */
147123 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
147124 + u32 flags, qman_cb_precommit cb, void *cb_arg);
147125 +
147126 +/**
147127 + * qman_enqueue_orp - Enqueue a frame to a frame queue using an ORP
147128 + * @fq: the frame queue object to enqueue to
147129 + * @fd: a descriptor of the frame to be enqueued
147130 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147131 + * @orp: the frame queue object used as an order restoration point.
147132 + * @orp_seqnum: the sequence number of this frame in the order restoration path
147133 + *
147134 + * Similar to qman_enqueue(), but with the addition of an Order Restoration
147135 + * Point (@orp) and corresponding sequence number (@orp_seqnum) for this
147136 + * enqueue operation to employ order restoration. Each frame queue object acts
147137 + * as an Order Definition Point (ODP) by providing each frame dequeued from it
147138 + * with an incrementing sequence number, this value is generally ignored unless
147139 + * that sequence of dequeued frames will need order restoration later. Each
147140 + * frame queue object also encapsulates an Order Restoration Point (ORP), which
147141 + * is a re-assembly context for re-ordering frames relative to their sequence
147142 + * numbers as they are enqueued. The ORP does not have to be within the frame
147143 + * queue that receives the enqueued frame, in fact it is usually the frame
147144 + * queue from which the frames were originally dequeued. For the purposes of
147145 + * order restoration, multiple frames (or "fragments") can be enqueued for a
147146 + * single sequence number by setting the QMAN_ENQUEUE_FLAG_NLIS flag for all
147147 + * enqueues except the final fragment of a given sequence number. Ordering
147148 + * between sequence numbers is guaranteed, even if fragments of different
147149 + * sequence numbers are interlaced with one another. Fragments of the same
147150 + * sequence number will retain the order in which they are enqueued. If no
147151 + * enqueue is to performed, QMAN_ENQUEUE_FLAG_HOLE indicates that the given
147152 + * sequence number is to be "skipped" by the ORP logic (eg. if a frame has been
147153 + * dropped from a sequence), or QMAN_ENQUEUE_FLAG_NESN indicates that the given
147154 + * sequence number should become the ORP's "Next Expected Sequence Number".
147155 + *
147156 + * Side note: a frame queue object can be used purely as an ORP, without
147157 + * carrying any frames at all. Care should be taken not to deallocate a frame
147158 + * queue object that is being actively used as an ORP, as a future allocation
147159 + * of the frame queue object may start using the internal ORP before the
147160 + * previous use has finished.
147161 + */
147162 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
147163 + struct qman_fq *orp, u16 orp_seqnum);
147164 +
147165 +/**
147166 + * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs
147167 + * @result: is set by the API to the base FQID of the allocated range
147168 + * @count: the number of FQIDs required
147169 + * @align: required alignment of the allocated range
147170 + * @partial: non-zero if the API can return fewer than @count FQIDs
147171 + *
147172 + * Returns the number of frame queues allocated, or a negative error code. If
147173 + * @partial is non zero, the allocation request may return a smaller range of
147174 + * FQs than requested (though alignment will be as requested). If @partial is
147175 + * zero, the return value will either be 'count' or negative.
147176 + */
147177 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial);
147178 +static inline int qman_alloc_fqid(u32 *result)
147179 +{
147180 + int ret = qman_alloc_fqid_range(result, 1, 0, 0);
147181 + return (ret > 0) ? 0 : ret;
147182 +}
147183 +
147184 +/**
147185 + * qman_release_fqid_range - Release the specified range of frame queue IDs
147186 + * @fqid: the base FQID of the range to deallocate
147187 + * @count: the number of FQIDs in the range
147188 + *
147189 + * This function can also be used to seed the allocator with ranges of FQIDs
147190 + * that it can subsequently allocate from.
147191 + */
147192 +void qman_release_fqid_range(u32 fqid, unsigned int count);
147193 +static inline void qman_release_fqid(u32 fqid)
147194 +{
147195 + qman_release_fqid_range(fqid, 1);
147196 +}
147197 +
147198 +void qman_seed_fqid_range(u32 fqid, unsigned int count);
147199 +
147200 +
147201 +int qman_shutdown_fq(u32 fqid);
147202 +
147203 +/**
147204 + * qman_reserve_fqid_range - Reserve the specified range of frame queue IDs
147205 + * @fqid: the base FQID of the range to deallocate
147206 + * @count: the number of FQIDs in the range
147207 + */
147208 +int qman_reserve_fqid_range(u32 fqid, unsigned int count);
147209 +static inline int qman_reserve_fqid(u32 fqid)
147210 +{
147211 + return qman_reserve_fqid_range(fqid, 1);
147212 +}
147213 +
147214 + /* Pool-channel management */
147215 + /* ----------------------- */
147216 +/**
147217 + * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs
147218 + * @result: is set by the API to the base pool-channel ID of the allocated range
147219 + * @count: the number of pool-channel IDs required
147220 + * @align: required alignment of the allocated range
147221 + * @partial: non-zero if the API can return fewer than @count
147222 + *
147223 + * Returns the number of pool-channel IDs allocated, or a negative error code.
147224 + * If @partial is non zero, the allocation request may return a smaller range of
147225 + * than requested (though alignment will be as requested). If @partial is zero,
147226 + * the return value will either be 'count' or negative.
147227 + */
147228 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial);
147229 +static inline int qman_alloc_pool(u32 *result)
147230 +{
147231 + int ret = qman_alloc_pool_range(result, 1, 0, 0);
147232 + return (ret > 0) ? 0 : ret;
147233 +}
147234 +
147235 +/**
147236 + * qman_release_pool_range - Release the specified range of pool-channel IDs
147237 + * @id: the base pool-channel ID of the range to deallocate
147238 + * @count: the number of pool-channel IDs in the range
147239 + */
147240 +void qman_release_pool_range(u32 id, unsigned int count);
147241 +static inline void qman_release_pool(u32 id)
147242 +{
147243 + qman_release_pool_range(id, 1);
147244 +}
147245 +
147246 +/**
147247 + * qman_reserve_pool_range - Reserve the specified range of pool-channel IDs
147248 + * @id: the base pool-channel ID of the range to reserve
147249 + * @count: the number of pool-channel IDs in the range
147250 + */
147251 +int qman_reserve_pool_range(u32 id, unsigned int count);
147252 +static inline int qman_reserve_pool(u32 id)
147253 +{
147254 + return qman_reserve_pool_range(id, 1);
147255 +}
147256 +
147257 +void qman_seed_pool_range(u32 id, unsigned int count);
147258 +
147259 + /* CGR management */
147260 + /* -------------- */
147261 +/**
147262 + * qman_create_cgr - Register a congestion group object
147263 + * @cgr: the 'cgr' object, with fields filled in
147264 + * @flags: QMAN_CGR_FLAG_* values
147265 + * @opts: optional state of CGR settings
147266 + *
147267 + * Registers this object to receiving congestion entry/exit callbacks on the
147268 + * portal affine to the cpu portal on which this API is executed. If opts is
147269 + * NULL then only the callback (cgr->cb) function is registered. If @flags
147270 + * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset
147271 + * any unspecified parameters) will be used rather than a modify hw hardware
147272 + * (which only modifies the specified parameters).
147273 + */
147274 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
147275 + struct qm_mcc_initcgr *opts);
147276 +
147277 +/**
147278 + * qman_create_cgr_to_dcp - Register a congestion group object to DCP portal
147279 + * @cgr: the 'cgr' object, with fields filled in
147280 + * @flags: QMAN_CGR_FLAG_* values
147281 + * @dcp_portal: the DCP portal to which the cgr object is registered.
147282 + * @opts: optional state of CGR settings
147283 + *
147284 + */
147285 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
147286 + struct qm_mcc_initcgr *opts);
147287 +
147288 +/**
147289 + * qman_delete_cgr - Deregisters a congestion group object
147290 + * @cgr: the 'cgr' object to deregister
147291 + *
147292 + * "Unplugs" this CGR object from the portal affine to the cpu on which this API
147293 + * is executed. This must be excuted on the same affine portal on which it was
147294 + * created.
147295 + */
147296 +int qman_delete_cgr(struct qman_cgr *cgr);
147297 +
147298 +/**
147299 + * qman_delete_cgr_safe - Deregisters a congestion group object from any CPU
147300 + * @cgr: the 'cgr' object to deregister
147301 + *
147302 + * This will select the proper CPU and run there qman_delete_cgr().
147303 + */
147304 +void qman_delete_cgr_safe(struct qman_cgr *cgr);
147305 +
147306 +/**
147307 + * qman_modify_cgr - Modify CGR fields
147308 + * @cgr: the 'cgr' object to modify
147309 + * @flags: QMAN_CGR_FLAG_* values
147310 + * @opts: the CGR-modification settings
147311 + *
147312 + * The @opts parameter comes from the low-level portal API, and can be NULL.
147313 + * Note that some fields and options within @opts may be ignored or overwritten
147314 + * by the driver, in particular the 'cgrid' field is ignored (this operation
147315 + * only affects the given CGR object). If @flags contains
147316 + * QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset any
147317 + * unspecified parameters) will be used rather than a modify hw hardware (which
147318 + * only modifies the specified parameters).
147319 + */
147320 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
147321 + struct qm_mcc_initcgr *opts);
147322 +
147323 +/**
147324 +* qman_query_cgr - Queries CGR fields
147325 +* @cgr: the 'cgr' object to query
147326 +* @result: storage for the queried congestion group record
147327 +*/
147328 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *result);
147329 +
147330 +/**
147331 + * qman_query_congestion - Queries the state of all congestion groups
147332 + * @congestion: storage for the queried state of all congestion groups
147333 + */
147334 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion);
147335 +
147336 +/**
147337 + * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs
147338 + * @result: is set by the API to the base CGR ID of the allocated range
147339 + * @count: the number of CGR IDs required
147340 + * @align: required alignment of the allocated range
147341 + * @partial: non-zero if the API can return fewer than @count
147342 + *
147343 + * Returns the number of CGR IDs allocated, or a negative error code.
147344 + * If @partial is non zero, the allocation request may return a smaller range of
147345 + * than requested (though alignment will be as requested). If @partial is zero,
147346 + * the return value will either be 'count' or negative.
147347 + */
147348 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial);
147349 +static inline int qman_alloc_cgrid(u32 *result)
147350 +{
147351 + int ret = qman_alloc_cgrid_range(result, 1, 0, 0);
147352 + return (ret > 0) ? 0 : ret;
147353 +}
147354 +
147355 +/**
147356 + * qman_release_cgrid_range - Release the specified range of CGR IDs
147357 + * @id: the base CGR ID of the range to deallocate
147358 + * @count: the number of CGR IDs in the range
147359 + */
147360 +void qman_release_cgrid_range(u32 id, unsigned int count);
147361 +static inline void qman_release_cgrid(u32 id)
147362 +{
147363 + qman_release_cgrid_range(id, 1);
147364 +}
147365 +
147366 +/**
147367 + * qman_reserve_cgrid_range - Reserve the specified range of CGR ID
147368 + * @id: the base CGR ID of the range to reserve
147369 + * @count: the number of CGR IDs in the range
147370 + */
147371 +int qman_reserve_cgrid_range(u32 id, unsigned int count);
147372 +static inline int qman_reserve_cgrid(u32 id)
147373 +{
147374 + return qman_reserve_cgrid_range(id, 1);
147375 +}
147376 +
147377 +void qman_seed_cgrid_range(u32 id, unsigned int count);
147378 +
147379 +
147380 + /* Helpers */
147381 + /* ------- */
147382 +/**
147383 + * qman_poll_fq_for_init - Check if an FQ has been initialised from OOS
147384 + * @fqid: the FQID that will be initialised by other s/w
147385 + *
147386 + * In many situations, a FQID is provided for communication between s/w
147387 + * entities, and whilst the consumer is responsible for initialising and
147388 + * scheduling the FQ, the producer(s) generally create a wrapper FQ object using
147389 + * and only call qman_enqueue() (no FQ initialisation, scheduling, etc). Ie;
147390 + * qman_create_fq(..., QMAN_FQ_FLAG_NO_MODIFY, ...);
147391 + * However, data can not be enqueued to the FQ until it is initialised out of
147392 + * the OOS state - this function polls for that condition. It is particularly
147393 + * useful for users of IPC functions - each endpoint's Rx FQ is the other
147394 + * endpoint's Tx FQ, so each side can initialise and schedule their Rx FQ object
147395 + * and then use this API on the (NO_MODIFY) Tx FQ object in order to
147396 + * synchronise. The function returns zero for success, +1 if the FQ is still in
147397 + * the OOS state, or negative if there was an error.
147398 + */
147399 +static inline int qman_poll_fq_for_init(struct qman_fq *fq)
147400 +{
147401 + struct qm_mcr_queryfq_np np;
147402 + int err;
147403 + err = qman_query_fq_np(fq, &np);
147404 + if (err)
147405 + return err;
147406 + if ((np.state & QM_MCR_NP_STATE_MASK) == QM_MCR_NP_STATE_OOS)
147407 + return 1;
147408 + return 0;
147409 +}
147410 +
147411 + /* -------------- */
147412 + /* CEETM :: types */
147413 + /* -------------- */
147414 +/**
147415 + * Token Rate Structure
147416 + * Shaping rates are based on a "credit" system and a pre-configured h/w
147417 + * internal timer. The following type represents a shaper "rate" parameter as a
147418 + * fractional number of "tokens". Here's how it works. This (fractional) number
147419 + * of tokens is added to the shaper's "credit" every time the h/w timer elapses
147420 + * (up to a limit which is set by another shaper parameter). Every time a frame
147421 + * is enqueued through a shaper, the shaper deducts as many tokens as there are
147422 + * bytes of data in the enqueued frame. A shaper will not allow itself to
147423 + * enqueue any frames if its token count is negative. As such;
147424 + *
147425 + * The rate at which data is enqueued is limited by the
147426 + * rate at which tokens are added.
147427 + *
147428 + * Therefore if the user knows the period between these h/w timer updates in
147429 + * seconds, they can calculate the maximum traffic rate of the shaper (in
147430 + * bytes-per-second) from the token rate. And vice versa, they can calculate
147431 + * the token rate to use in order to achieve a given traffic rate.
147432 + */
147433 +struct qm_ceetm_rate {
147434 + /* The token rate is; whole + (fraction/8192) */
147435 + u32 whole:11; /* 0..2047 */
147436 + u32 fraction:13; /* 0..8191 */
147437 +};
147438 +
147439 +struct qm_ceetm_weight_code {
147440 + /* The weight code is; 5 msbits + 3 lsbits */
147441 + u8 y:5;
147442 + u8 x:3;
147443 +};
147444 +
147445 +struct qm_ceetm {
147446 + unsigned int idx;
147447 + struct list_head sub_portals;
147448 + struct list_head lnis;
147449 + unsigned int sp_range[2];
147450 + unsigned int lni_range[2];
147451 +};
147452 +
147453 +struct qm_ceetm_sp {
147454 + struct list_head node;
147455 + unsigned int idx;
147456 + unsigned int dcp_idx;
147457 + int is_claimed;
147458 + struct qm_ceetm_lni *lni;
147459 +};
147460 +
147461 +/* Logical Network Interface */
147462 +struct qm_ceetm_lni {
147463 + struct list_head node;
147464 + unsigned int idx;
147465 + unsigned int dcp_idx;
147466 + int is_claimed;
147467 + struct qm_ceetm_sp *sp;
147468 + struct list_head channels;
147469 + int shaper_enable;
147470 + int shaper_couple;
147471 + int oal;
147472 + struct qm_ceetm_rate cr_token_rate;
147473 + struct qm_ceetm_rate er_token_rate;
147474 + u16 cr_token_bucket_limit;
147475 + u16 er_token_bucket_limit;
147476 +};
147477 +
147478 +/* Class Queue Channel */
147479 +struct qm_ceetm_channel {
147480 + struct list_head node;
147481 + unsigned int idx;
147482 + unsigned int lni_idx;
147483 + unsigned int dcp_idx;
147484 + struct list_head class_queues;
147485 + struct list_head ccgs;
147486 + u8 shaper_enable;
147487 + u8 shaper_couple;
147488 + struct qm_ceetm_rate cr_token_rate;
147489 + struct qm_ceetm_rate er_token_rate;
147490 + u16 cr_token_bucket_limit;
147491 + u16 er_token_bucket_limit;
147492 +};
147493 +
147494 +struct qm_ceetm_ccg;
147495 +
147496 +/* This callback type is used when handling congestion entry/exit. The
147497 + * 'cb_ctx' value is the opaque value associated with ccg object.
147498 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit.
147499 + */
147500 +typedef void (*qman_cb_ccgr)(struct qm_ceetm_ccg *ccg, void *cb_ctx,
147501 + int congested);
147502 +
147503 +/* Class Congestion Group */
147504 +struct qm_ceetm_ccg {
147505 + struct qm_ceetm_channel *parent;
147506 + struct list_head node;
147507 + struct list_head cb_node;
147508 + qman_cb_ccgr cb;
147509 + void *cb_ctx;
147510 + unsigned int idx;
147511 +};
147512 +
147513 +/* Class Queue */
147514 +struct qm_ceetm_cq {
147515 + struct qm_ceetm_channel *parent;
147516 + struct qm_ceetm_ccg *ccg;
147517 + struct list_head node;
147518 + unsigned int idx;
147519 + int is_claimed;
147520 + struct list_head bound_lfqids;
147521 + struct list_head binding_node;
147522 +};
147523 +
147524 +/* Logical Frame Queue */
147525 +struct qm_ceetm_lfq {
147526 + struct qm_ceetm_channel *parent;
147527 + struct list_head node;
147528 + unsigned int idx;
147529 + unsigned int dctidx;
147530 + u64 context_a;
147531 + u32 context_b;
147532 + qman_cb_mr ern;
147533 +};
147534 +
147535 +/**
147536 + * qman_ceetm_bps2tokenrate - Given a desired rate 'bps' measured in bps
147537 + * (ie. bits-per-second), compute the 'token_rate' fraction that best
147538 + * approximates that rate.
147539 + * @bps: the desired shaper rate in bps.
147540 + * @token_rate: the output token rate computed with the given kbps.
147541 + * @rounding: dictates how to round if an exact conversion is not possible; if
147542 + * it is negative then 'token_rate' will round down to the highest value that
147543 + * does not exceed the desired rate, if it is positive then 'token_rate' will
147544 + * round up to the lowest value that is greater than or equal to the desired
147545 + * rate, and if it is zero then it will round to the nearest approximation,
147546 + * whether that be up or down.
147547 + *
147548 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
147549 + */
147550 +int qman_ceetm_bps2tokenrate(u64 bps,
147551 + struct qm_ceetm_rate *token_rate,
147552 + int rounding);
147553 +
147554 +/**
147555 + * qman_ceetm_tokenrate2bps - Given a 'token_rate', compute the
147556 + * corresponding number of 'bps'.
147557 + * @token_rate: the input desired token_rate fraction.
147558 + * @bps: the output shaper rate in bps computed with the give token rate.
147559 + * @rounding: has the same semantics as the previous function.
147560 + *
147561 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
147562 + */
147563 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate,
147564 + u64 *bps,
147565 + int rounding);
147566 +
147567 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
147568 + int partial);
147569 +static inline int qman_alloc_ceetm0_channel(u32 *result)
147570 +{
147571 + int ret = qman_alloc_ceetm0_channel_range(result, 1, 0, 0);
147572 + return (ret > 0) ? 0 : ret;
147573 +}
147574 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count);
147575 +static inline void qman_release_ceetm0_channelid(u32 channelid)
147576 +{
147577 + qman_release_ceetm0_channel_range(channelid, 1);
147578 +}
147579 +
147580 +int qman_reserve_ceetm0_channel_range(u32 channelid, u32 count);
147581 +static inline int qman_reserve_ceetm0_channelid(u32 channelid)
147582 +{
147583 + return qman_reserve_ceetm0_channel_range(channelid, 1);
147584 +}
147585 +
147586 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count);
147587 +
147588 +
147589 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
147590 + int partial);
147591 +static inline int qman_alloc_ceetm1_channel(u32 *result)
147592 +{
147593 + int ret = qman_alloc_ceetm1_channel_range(result, 1, 0, 0);
147594 + return (ret > 0) ? 0 : ret;
147595 +}
147596 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count);
147597 +static inline void qman_release_ceetm1_channelid(u32 channelid)
147598 +{
147599 + qman_release_ceetm1_channel_range(channelid, 1);
147600 +}
147601 +int qman_reserve_ceetm1_channel_range(u32 channelid, u32 count);
147602 +static inline int qman_reserve_ceetm1_channelid(u32 channelid)
147603 +{
147604 + return qman_reserve_ceetm1_channel_range(channelid, 1);
147605 +}
147606 +
147607 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count);
147608 +
147609 +
147610 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
147611 + int partial);
147612 +static inline int qman_alloc_ceetm0_lfqid(u32 *result)
147613 +{
147614 + int ret = qman_alloc_ceetm0_lfqid_range(result, 1, 0, 0);
147615 + return (ret > 0) ? 0 : ret;
147616 +}
147617 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count);
147618 +static inline void qman_release_ceetm0_lfqid(u32 lfqid)
147619 +{
147620 + qman_release_ceetm0_lfqid_range(lfqid, 1);
147621 +}
147622 +int qman_reserve_ceetm0_lfqid_range(u32 lfqid, u32 count);
147623 +static inline int qman_reserve_ceetm0_lfqid(u32 lfqid)
147624 +{
147625 + return qman_reserve_ceetm0_lfqid_range(lfqid, 1);
147626 +}
147627 +
147628 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count);
147629 +
147630 +
147631 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
147632 + int partial);
147633 +static inline int qman_alloc_ceetm1_lfqid(u32 *result)
147634 +{
147635 + int ret = qman_alloc_ceetm1_lfqid_range(result, 1, 0, 0);
147636 + return (ret > 0) ? 0 : ret;
147637 +}
147638 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count);
147639 +static inline void qman_release_ceetm1_lfqid(u32 lfqid)
147640 +{
147641 + qman_release_ceetm1_lfqid_range(lfqid, 1);
147642 +}
147643 +int qman_reserve_ceetm1_lfqid_range(u32 lfqid, u32 count);
147644 +static inline int qman_reserve_ceetm1_lfqid(u32 lfqid)
147645 +{
147646 + return qman_reserve_ceetm1_lfqid_range(lfqid, 1);
147647 +}
147648 +
147649 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count);
147650 +
147651 +
147652 + /* ----------------------------- */
147653 + /* CEETM :: sub-portals */
147654 + /* ----------------------------- */
147655 +
147656 +/**
147657 + * qman_ceetm_sp_claim - Claims the given sub-portal, provided it is available
147658 + * to us and configured for traffic-management.
147659 + * @sp: the returned sub-portal object, if successful.
147660 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
147661 + * instance),
147662 + * @sp_idx" is the desired sub-portal index from 0 to 15.
147663 + *
147664 + * Returns zero for success, or -ENODEV if the sub-portal is in use, or -EINVAL
147665 + * if the sp_idx is out of range.
147666 + *
147667 + * Note that if there are multiple driver domains (eg. a linux kernel versus
147668 + * user-space drivers in USDPAA, or multiple guests running under a hypervisor)
147669 + * then a sub-portal may be accessible by more than one instance of a qman
147670 + * driver and so it may be claimed multiple times. If this is the case, it is
147671 + * up to the system architect to prevent conflicting configuration actions
147672 + * coming from the different driver domains. The qman drivers do not have any
147673 + * behind-the-scenes coordination to prevent this from happening.
147674 + */
147675 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp,
147676 + enum qm_dc_portal dcp_idx,
147677 + unsigned int sp_idx);
147678 +
147679 +/**
147680 + * qman_ceetm_sp_release - Releases a previously claimed sub-portal.
147681 + * @sp: the sub-portal to be released.
147682 + *
147683 + * Returns 0 for success, or -EBUSY for failure if the dependencies are not
147684 + * released.
147685 + */
147686 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp);
147687 +
147688 + /* ----------------------------------- */
147689 + /* CEETM :: logical network interfaces */
147690 + /* ----------------------------------- */
147691 +
147692 +/**
147693 + * qman_ceetm_lni_claim - Claims an unclaimed LNI.
147694 + * @lni: the returned LNI object, if successful.
147695 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
147696 + * instance)
147697 + * @lni_idx: is the desired LNI index.
147698 + *
147699 + * Returns zero for success, or -EINVAL on failure, which will happen if the LNI
147700 + * is not available or has already been claimed (and not yet successfully
147701 + * released), or lni_dix is out of range.
147702 + *
147703 + * Note that there may be multiple driver domains (or instances) that need to
147704 + * transmit out the same LNI, so this claim is only guaranteeing exclusivity
147705 + * within the domain of the driver being called. See qman_ceetm_sp_claim() and
147706 + * qman_ceetm_sp_get_lni() for more information.
147707 + */
147708 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni,
147709 + enum qm_dc_portal dcp_id,
147710 + unsigned int lni_idx);
147711 +
147712 +/**
147713 + * qman_ceetm_lni_releaes - Releases a previously claimed LNI.
147714 + * @lni: the lni needs to be released.
147715 + *
147716 + * This will only succeed if all dependent objects have been released.
147717 + * Returns zero for success, or -EBUSY if the dependencies are not released.
147718 + */
147719 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni);
147720 +
147721 +/**
147722 + * qman_ceetm_sp_set_lni
147723 + * qman_ceetm_sp_get_lni - Set/get the LNI that the sub-portal is currently
147724 + * mapped to.
147725 + * @sp: the given sub-portal.
147726 + * @lni(in "set"function): the LNI object which the sp will be mappaed to.
147727 + * @lni_idx(in "get" function): the LNI index which the sp is mapped to.
147728 + *
147729 + * Returns zero for success, or -EINVAL for the "set" function when this sp-lni
147730 + * mapping has been set, or configure mapping command returns error, and
147731 + * -EINVAL for "get" function when this sp-lni mapping is not set or the query
147732 + * mapping command returns error.
147733 + *
147734 + * This may be useful in situations where multiple driver domains have access
147735 + * to the same sub-portals in order to all be able to transmit out the same
147736 + * physical interface (perhaps they're on different IP addresses or VPNs, so
147737 + * Fman is splitting Rx traffic and here we need to converge Tx traffic). In
147738 + * that case, a control-plane is likely to use qman_ceetm_lni_claim() followed
147739 + * by qman_ceetm_sp_set_lni() to configure the sub-portal, and other domains
147740 + * are likely to use qman_ceetm_sp_get_lni() followed by qman_ceetm_lni_claim()
147741 + * in order to determine the LNI that the control-plane had assigned. This is
147742 + * why the "get" returns an index, whereas the "set" takes an (already claimed)
147743 + * LNI object.
147744 + */
147745 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp,
147746 + struct qm_ceetm_lni *lni);
147747 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp,
147748 + unsigned int *lni_idx);
147749 +
147750 +/**
147751 + * qman_ceetm_lni_enable_shaper
147752 + * qman_ceetm_lni_disable_shaper - Enables/disables shaping on the LNI.
147753 + * @lni: the given LNI.
147754 + * @coupled: indicates whether CR and ER are coupled.
147755 + * @oal: the overhead accounting length which is added to the actual length of
147756 + * each frame when performing shaper calculations.
147757 + *
147758 + * When the number of (unused) committed-rate tokens reach the committed-rate
147759 + * token limit, 'coupled' indicates whether surplus tokens should be added to
147760 + * the excess-rate token count (up to the excess-rate token limit).
147761 + * When LNI is claimed, the shaper is disabled by default. The enable function
147762 + * will turn on this shaper for this lni.
147763 + * Whenever a claimed LNI is first enabled for shaping, its committed and
147764 + * excess token rates and limits are zero, so will need to be changed to do
147765 + * anything useful. The shaper can subsequently be enabled/disabled without
147766 + * resetting the shaping parameters, but the shaping parameters will be reset
147767 + * when the LNI is released.
147768 + *
147769 + * Returns zero for success, or errno for "enable" function in the cases as:
147770 + * a) -EINVAL if the shaper is already enabled,
147771 + * b) -EIO if the configure shaper command returns error.
147772 + * For "disable" function, returns:
147773 + * a) -EINVAL if the shaper is has already disabled.
147774 + * b) -EIO if calling configure shaper command returns error.
147775 + */
147776 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
147777 + int oal);
147778 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni);
147779 +
147780 +/**
147781 + * qman_ceetm_lni_is_shaper_enabled - Check LNI shaper status
147782 + * @lni: the give LNI
147783 + */
147784 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni);
147785 +
147786 +/**
147787 + * qman_ceetm_lni_set_commit_rate
147788 + * qman_ceetm_lni_get_commit_rate
147789 + * qman_ceetm_lni_set_excess_rate
147790 + * qman_ceetm_lni_get_excess_rate - Set/get the shaper CR/ER token rate and
147791 + * token limit for the given LNI.
147792 + * @lni: the given LNI.
147793 + * @token_rate: the desired token rate for "set" fuction, or the token rate of
147794 + * the LNI queried by "get" function.
147795 + * @token_limit: the desired token bucket limit for "set" function, or the token
147796 + * limit of the given LNI queried by "get" function.
147797 + *
147798 + * Returns zero for success. The "set" function returns -EINVAL if the given
147799 + * LNI is unshapped or -EIO if the configure shaper command returns error.
147800 + * The "get" function returns -EINVAL if the token rate or the token limit is
147801 + * not set or the query command returns error.
147802 + */
147803 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
147804 + const struct qm_ceetm_rate *token_rate,
147805 + u16 token_limit);
147806 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
147807 + struct qm_ceetm_rate *token_rate,
147808 + u16 *token_limit);
147809 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
147810 + const struct qm_ceetm_rate *token_rate,
147811 + u16 token_limit);
147812 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
147813 + struct qm_ceetm_rate *token_rate,
147814 + u16 *token_limit);
147815 +/**
147816 + * qman_ceetm_lni_set_commit_rate_bps
147817 + * qman_ceetm_lni_get_commit_rate_bps
147818 + * qman_ceetm_lni_set_excess_rate_bps
147819 + * qman_ceetm_lni_get_excess_rate_bps - Set/get the shaper CR/ER rate
147820 + * and token limit for the given LNI.
147821 + * @lni: the given LNI.
147822 + * @bps: the desired shaping rate in bps for "set" fuction, or the shaping rate
147823 + * of the LNI queried by "get" function.
147824 + * @token_limit: the desired token bucket limit for "set" function, or the token
147825 + * limit of the given LNI queried by "get" function.
147826 + *
147827 + * Returns zero for success. The "set" function returns -EINVAL if the given
147828 + * LNI is unshapped or -EIO if the configure shaper command returns error.
147829 + * The "get" function returns -EINVAL if the token rate or the token limit is
147830 + * not set or the query command returns error.
147831 + */
147832 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
147833 + u64 bps,
147834 + u16 token_limit);
147835 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
147836 + u64 *bps, u16 *token_limit);
147837 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
147838 + u64 bps,
147839 + u16 token_limit);
147840 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
147841 + u64 *bps, u16 *token_limit);
147842 +
147843 +/**
147844 + * qman_ceetm_lni_set_tcfcc
147845 + * qman_ceetm_lni_get_tcfcc - Configure/query "Traffic Class Flow Control".
147846 + * @lni: the given LNI.
147847 + * @cq_level: is between 0 and 15, representing individual class queue levels
147848 + * (CQ0 to CQ7 for every channel) and grouped class queue levels (CQ8 to CQ15
147849 + * for every channel).
147850 + * @traffic_class: is between 0 and 7 when associating a given class queue level
147851 + * to a traffic class, or -1 when disabling traffic class flow control for this
147852 + * class queue level.
147853 + *
147854 + * Return zero for success, or -EINVAL if the cq_level or traffic_class is out
147855 + * of range as indicated above, or -EIO if the configure/query tcfcc command
147856 + * returns error.
147857 + *
147858 + * Refer to the section of QMan CEETM traffic class flow control in the
147859 + * Reference Manual.
147860 + */
147861 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
147862 + unsigned int cq_level,
147863 + int traffic_class);
147864 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni,
147865 + unsigned int cq_level,
147866 + int *traffic_class);
147867 +
147868 + /* ----------------------------- */
147869 + /* CEETM :: class queue channels */
147870 + /* ----------------------------- */
147871 +
147872 +/**
147873 + * qman_ceetm_channel_claim - Claims an unclaimed CQ channel that is mapped to
147874 + * the given LNI.
147875 + * @channel: the returned class queue channel object, if successful.
147876 + * @lni: the LNI that the channel belongs to.
147877 + *
147878 + * Channels are always initially "unshaped".
147879 + *
147880 + * Return zero for success, or -ENODEV if there is no channel available(all 32
147881 + * channels are claimed) or -EINVAL if the channel mapping command returns
147882 + * error.
147883 + */
147884 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
147885 + struct qm_ceetm_lni *lni);
147886 +
147887 +/**
147888 + * qman_ceetm_channel_release - Releases a previously claimed CQ channel.
147889 + * @channel: the channel needs to be released.
147890 + *
147891 + * Returns zero for success, or -EBUSY if the dependencies are still in use.
147892 + *
147893 + * Note any shaping of the channel will be cleared to leave it in an unshaped
147894 + * state.
147895 + */
147896 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel);
147897 +
147898 +/**
147899 + * qman_ceetm_channel_enable_shaper
147900 + * qman_ceetm_channel_disable_shaper - Enables/disables shaping on the channel.
147901 + * @channel: the given channel.
147902 + * @coupled: indicates whether surplus CR tokens should be added to the
147903 + * excess-rate token count (up to the excess-rate token limit) when the number
147904 + * of (unused) committed-rate tokens reach the committed_rate token limit.
147905 + *
147906 + * Whenever a claimed channel is first enabled for shaping, its committed and
147907 + * excess token rates and limits are zero, so will need to be changed to do
147908 + * anything useful. The shaper can subsequently be enabled/disabled without
147909 + * resetting the shaping parameters, but the shaping parameters will be reset
147910 + * when the channel is released.
147911 + *
147912 + * Return 0 for success, or -EINVAL for failure, in the case that the channel
147913 + * shaper has been enabled/disabled or the management command returns error.
147914 + */
147915 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
147916 + int coupled);
147917 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel);
147918 +
147919 +/**
147920 + * qman_ceetm_channel_is_shaper_enabled - Check channel shaper status.
147921 + * @channel: the give channel.
147922 + */
147923 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel);
147924 +
147925 +/**
147926 + * qman_ceetm_channel_set_commit_rate
147927 + * qman_ceetm_channel_get_commit_rate
147928 + * qman_ceetm_channel_set_excess_rate
147929 + * qman_ceetm_channel_get_excess_rate - Set/get channel CR/ER shaper parameters.
147930 + * @channel: the given channel.
147931 + * @token_rate: the desired token rate for "set" function, or the queried token
147932 + * rate for "get" function.
147933 + * @token_limit: the desired token limit for "set" function, or the queried
147934 + * token limit for "get" function.
147935 + *
147936 + * Return zero for success. The "set" function returns -EINVAL if the channel
147937 + * is unshaped, or -EIO if the configure shapper command returns error. The
147938 + * "get" function returns -EINVAL if token rate of token limit is not set, or
147939 + * the query shaper command returns error.
147940 + */
147941 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
147942 + const struct qm_ceetm_rate *token_rate,
147943 + u16 token_limit);
147944 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
147945 + struct qm_ceetm_rate *token_rate,
147946 + u16 *token_limit);
147947 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
147948 + const struct qm_ceetm_rate *token_rate,
147949 + u16 token_limit);
147950 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
147951 + struct qm_ceetm_rate *token_rate,
147952 + u16 *token_limit);
147953 +/**
147954 + * qman_ceetm_channel_set_commit_rate_bps
147955 + * qman_ceetm_channel_get_commit_rate_bps
147956 + * qman_ceetm_channel_set_excess_rate_bps
147957 + * qman_ceetm_channel_get_excess_rate_bps - Set/get channel CR/ER shaper
147958 + * parameters.
147959 + * @channel: the given channel.
147960 + * @token_rate: the desired shaper rate in bps for "set" function, or the
147961 + * shaper rate in bps for "get" function.
147962 + * @token_limit: the desired token limit for "set" function, or the queried
147963 + * token limit for "get" function.
147964 + *
147965 + * Return zero for success. The "set" function returns -EINVAL if the channel
147966 + * is unshaped, or -EIO if the configure shapper command returns error. The
147967 + * "get" function returns -EINVAL if token rate of token limit is not set, or
147968 + * the query shaper command returns error.
147969 + */
147970 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
147971 + u64 bps, u16 token_limit);
147972 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
147973 + u64 *bps, u16 *token_limit);
147974 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
147975 + u64 bps, u16 token_limit);
147976 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
147977 + u64 *bps, u16 *token_limit);
147978 +
147979 +/**
147980 + * qman_ceetm_channel_set_weight
147981 + * qman_ceetm_channel_get_weight - Set/get the weight for unshaped channel
147982 + * @channel: the given channel.
147983 + * @token_limit: the desired token limit as the weight of the unshaped channel
147984 + * for "set" function, or the queried token limit for "get" function.
147985 + *
147986 + * The algorithm of unshaped fair queuing (uFQ) is used for unshaped channel.
147987 + * It allows the unshaped channels to be included in the CR time eligible list,
147988 + * and thus use the configured CR token limit value as their fair queuing
147989 + * weight.
147990 + *
147991 + * Return zero for success, or -EINVAL if the channel is a shaped channel or
147992 + * the management command returns error.
147993 + */
147994 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
147995 + u16 token_limit);
147996 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
147997 + u16 *token_limit);
147998 +
147999 +/**
148000 + * qman_ceetm_channel_set_group
148001 + * qman_ceetm_channel_get_group - Set/get the grouping of the class scheduler.
148002 + * @channel: the given channel.
148003 + * @group_b: indicates whether there is group B in this channel.
148004 + * @prio_a: the priority of group A.
148005 + * @prio_b: the priority of group B.
148006 + *
148007 + * There are 8 individual class queues (CQ0-CQ7), and 8 grouped class queues
148008 + * (CQ8-CQ15). If 'group_b' is zero, then all the grouped class queues are in
148009 + * group A, otherwise they are split into group A (CQ8-11) and group B
148010 + * (CQ12-C15). The individual class queues and the group(s) are in strict
148011 + * priority order relative to each other. Within the group(s), the scheduling
148012 + * is not strict priority order, but the result of scheduling within a group
148013 + * is in strict priority order relative to the other class queues in the
148014 + * channel. 'prio_a' and 'prio_b' control the priority order of the groups
148015 + * relative to the individual class queues, and take values from 0-7. Eg. if
148016 + * 'group_b' is non-zero, 'prio_a' is 2 and 'prio_b' is 6, then the strict
148017 + * priority order would be;
148018 + * CQ0, CQ1, CQ2, GROUPA, CQ3, CQ4, CQ5, CQ6, GROUPB, CQ7
148019 + *
148020 + * Return 0 for success. For "set" function, returns -EINVAL if prio_a or
148021 + * prio_b are out of the range 0 - 7 (priority of group A or group B can not
148022 + * be 0, CQ0 is always the highest class queue in this channel.), or -EIO if
148023 + * the configure scheduler command returns error. For "get" function, return
148024 + * -EINVAL if the query scheduler command returns error.
148025 + */
148026 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel,
148027 + int group_b,
148028 + unsigned int prio_a,
148029 + unsigned int prio_b);
148030 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel,
148031 + int *group_b,
148032 + unsigned int *prio_a,
148033 + unsigned int *prio_b);
148034 +
148035 +/**
148036 + * qman_ceetm_channel_set_group_cr_eligibility
148037 + * qman_ceetm_channel_set_group_er_eligibility - Set channel group eligibility
148038 + * @channel: the given channel object
148039 + * @group_b: indicates whether there is group B in this channel.
148040 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
148041 + *
148042 + * Return zero for success, or -EINVAL if eligibility setting fails.
148043 +*/
148044 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
148045 + *channel, int group_b, int cre);
148046 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
148047 + *channel, int group_b, int ere);
148048 +
148049 +/**
148050 + * qman_ceetm_channel_set_cq_cr_eligibility
148051 + * qman_ceetm_channel_set_cq_er_eligibility - Set channel cq eligibility
148052 + * @channel: the given channel object
148053 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
148054 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
148055 + *
148056 + * Return zero for success, or -EINVAL if eligibility setting fails.
148057 +*/
148058 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
148059 + unsigned int idx, int cre);
148060 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
148061 + unsigned int idx, int ere);
148062 +
148063 + /* --------------------- */
148064 + /* CEETM :: class queues */
148065 + /* --------------------- */
148066 +
148067 +/**
148068 + * qman_ceetm_cq_claim - Claims an individual class queue.
148069 + * @cq: the returned class queue object, if successful.
148070 + * @channel: the class queue channel.
148071 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
148072 + * @ccg: represents the class congestion group that this class queue should be
148073 + * subscribed to, or NULL if no congestion group membership is desired.
148074 + *
148075 + * Returns zero for success, or -EINVAL if @idx is out of range 0 - 7 or
148076 + * if this class queue has been claimed, or configure class queue command
148077 + * returns error, or returns -ENOMEM if allocating CQ memory fails.
148078 + */
148079 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
148080 + struct qm_ceetm_channel *channel,
148081 + unsigned int idx,
148082 + struct qm_ceetm_ccg *ccg);
148083 +
148084 +/**
148085 + * qman_ceetm_cq_claim_A - Claims a class queue group A.
148086 + * @cq: the returned class queue object, if successful.
148087 + * @channel: the class queue channel.
148088 + * @idx: is from 8 to 15 if only group A exits, otherwise, it is from 8 to 11.
148089 + * @ccg: represents the class congestion group that this class queue should be
148090 + * subscribed to, or NULL if no congestion group membership is desired.
148091 + *
148092 + * Return zero for success, or -EINVAL if @idx is out the range or if
148093 + * this class queue has been claimed or configure class queue command returns
148094 + * error, or returns -ENOMEM if allocating CQ memory fails.
148095 + */
148096 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
148097 + struct qm_ceetm_channel *channel,
148098 + unsigned int idx,
148099 + struct qm_ceetm_ccg *ccg);
148100 +
148101 +/**
148102 + * qman_ceetm_cq_claim_B - Claims a class queue group B.
148103 + * @cq: the returned class queue object, if successful.
148104 + * @channel: the class queue channel.
148105 + * @idx: is from 0 to 3 (CQ12 to CQ15).
148106 + * @ccg: represents the class congestion group that this class queue should be
148107 + * subscribed to, or NULL if no congestion group membership is desired.
148108 + *
148109 + * Return zero for success, or -EINVAL if @idx is out the range or if
148110 + * this class queue has been claimed or configure class queue command returns
148111 + * error, or returns -ENOMEM if allocating CQ memory fails.
148112 + */
148113 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
148114 + struct qm_ceetm_channel *channel,
148115 + unsigned int idx,
148116 + struct qm_ceetm_ccg *ccg);
148117 +
148118 +/**
148119 + * qman_ceetm_cq_release - Releases a previously claimed class queue.
148120 + * @cq: The class queue to be released.
148121 + *
148122 + * Return zero for success, or -EBUSY if the dependent objects (eg. logical
148123 + * FQIDs) have not been released.
148124 + */
148125 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq);
148126 +
148127 +/**
148128 + * qman_ceetm_set_queue_weight
148129 + * qman_ceetm_get_queue_weight - Configure/query the weight of a grouped class
148130 + * queue.
148131 + * @cq: the given class queue.
148132 + * @weight_code: the desired weight code to set for the given class queue for
148133 + * "set" function or the queired weight code for "get" function.
148134 + *
148135 + * Grouped class queues have a default weight code of zero, which corresponds to
148136 + * a scheduler weighting of 1. This function can be used to modify a grouped
148137 + * class queue to another weight, (Use the helpers qman_ceetm_wbfs2ratio()
148138 + * and qman_ceetm_ratio2wbfs() to convert between these 'weight_code' values
148139 + * and the corresponding sharing weight.)
148140 + *
148141 + * Returns zero for success, or -EIO if the configure weight command returns
148142 + * error for "set" function, or -EINVAL if the query command returns
148143 + * error for "get" function.
148144 + * See section "CEETM Weighted Scheduling among Grouped Classes" in Reference
148145 + * Manual for weight and weight code.
148146 + */
148147 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
148148 + struct qm_ceetm_weight_code *weight_code);
148149 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
148150 + struct qm_ceetm_weight_code *weight_code);
148151 +
148152 +/**
148153 + * qman_ceetm_set_queue_weight_in_ratio
148154 + * qman_ceetm_get_queue_weight_in_ratio - Configure/query the weight of a
148155 + * grouped class queue.
148156 + * @cq: the given class queue.
148157 + * @ratio: the weight in ratio. It should be the real ratio number multiplied
148158 + * by 100 to get rid of fraction.
148159 + *
148160 + * Returns zero for success, or -EIO if the configure weight command returns
148161 + * error for "set" function, or -EINVAL if the query command returns
148162 + * error for "get" function.
148163 + */
148164 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio);
148165 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio);
148166 +
148167 +/* Weights are encoded using a pseudo-exponential scheme. The weight codes 0,
148168 + * 32, 64, [...] correspond to weights of 1, 2, 4, [...]. The weights
148169 + * corresponding to intermediate weight codes are calculated using linear
148170 + * interpolation on the inverted values. Or put another way, the inverse weights
148171 + * for each 32nd weight code are 1, 1/2, 1/4, [...], and so the intervals
148172 + * between these are divided linearly into 32 intermediate values, the inverses
148173 + * of which form the remaining weight codes.
148174 + *
148175 + * The Weighted Bandwidth Fair Scheduling (WBFS) algorithm provides a form of
148176 + * scheduling within a group of class queues (group A or B). Weights are used to
148177 + * normalise the class queues to an underlying BFS algorithm where all class
148178 + * queues are assumed to require "equal bandwidth". So the weights referred to
148179 + * by the weight codes act as divisors on the size of frames being enqueued. Ie.
148180 + * one class queue in a group is assigned a weight of 2 whilst the other class
148181 + * queues in the group keep the default weight of 1, then the WBFS scheduler
148182 + * will effectively treat all frames enqueued on the weight-2 class queue as
148183 + * having half the number of bytes they really have. Ie. if all other things are
148184 + * equal, that class queue would get twice as much bytes-per-second bandwidth as
148185 + * the others. So weights should be chosen to provide bandwidth ratios between
148186 + * members of the same class queue group. These weights have no bearing on
148187 + * behaviour outside that group's WBFS mechanism though.
148188 + */
148189 +
148190 +/**
148191 + * qman_ceetm_wbfs2ratio - Given a weight code ('wbfs'), an accurate fractional
148192 + * representation of the corresponding weight is given (in order to not lose
148193 + * any precision).
148194 + * @weight_code: The given weight code in WBFS.
148195 + * @numerator: the numerator part of the weight computed by the weight code.
148196 + * @denominator: the denominator part of the weight computed by the weight code
148197 + *
148198 + * Returns zero for success or -EINVAL if the given weight code is illegal.
148199 + */
148200 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
148201 + u32 *numerator,
148202 + u32 *denominator);
148203 +/**
148204 + * qman_ceetm_ratio2wbfs - Given a weight, find the nearest possible weight code
148205 + * If the user needs to know how close this is, convert the resulting weight
148206 + * code back to a weight and compare.
148207 + * @numerator: numerator part of the given weight.
148208 + * @denominator: denominator part of the given weight.
148209 + * @weight_code: the weight code computed from the given weight.
148210 + *
148211 + * Returns zero for success, or -ERANGE if "numerator/denominator" is outside
148212 + * the range of weights.
148213 + */
148214 +int qman_ceetm_ratio2wbfs(u32 numerator,
148215 + u32 denominator,
148216 + struct qm_ceetm_weight_code *weight_code,
148217 + int rounding);
148218 +
148219 +#define QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER 0x1
148220 +/**
148221 + * qman_ceetm_cq_get_dequeue_statistics - Get the statistics provided by CEETM
148222 + * CQ counters.
148223 + * @cq: the given CQ object.
148224 + * @flags: indicates whether the statistics counter will be cleared after query.
148225 + * @frame_count: The number of the frames that have been counted since the
148226 + * counter was cleared last time.
148227 + * @byte_count: the number of bytes in all frames that have been counted.
148228 + *
148229 + * Return zero for success or -EINVAL if query statistics command returns error.
148230 + *
148231 + */
148232 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
148233 + u64 *frame_count, u64 *byte_count);
148234 +
148235 +/**
148236 + * qman_ceetm_drain_cq - drain the CQ till it is empty.
148237 + * @cq: the give CQ object.
148238 + * Return 0 for success or -EINVAL for unsuccessful command to empty CQ.
148239 + */
148240 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq);
148241 +
148242 + /* ---------------------- */
148243 + /* CEETM :: logical FQIDs */
148244 + /* ---------------------- */
148245 +/**
148246 + * qman_ceetm_lfq_claim - Claims an unused logical FQID, associates it with
148247 + * the given class queue.
148248 + * @lfq: the returned lfq object, if successful.
148249 + * @cq: the class queue which needs to claim a LFQID.
148250 + *
148251 + * Return zero for success, or -ENODEV if no LFQID is available or -ENOMEM if
148252 + * allocating memory for lfq fails, or -EINVAL if configuring LFQMT fails.
148253 + */
148254 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
148255 + struct qm_ceetm_cq *cq);
148256 +
148257 +/**
148258 + * qman_ceetm_lfq_release - Releases a previously claimed logical FQID.
148259 + * @lfq: the lfq to be released.
148260 + *
148261 + * Return zero for success.
148262 + */
148263 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq);
148264 +
148265 +/**
148266 + * qman_ceetm_lfq_set_context
148267 + * qman_ceetm_lfq_get_context - Set/get the context_a/context_b pair to the
148268 + * "dequeue context table" associated with the logical FQID.
148269 + * @lfq: the given logical FQ object.
148270 + * @context_a: contextA of the dequeue context.
148271 + * @context_b: contextB of the dequeue context.
148272 + *
148273 + * Returns zero for success, or -EINVAL if there is error to set/get the
148274 + * context pair.
148275 + */
148276 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq,
148277 + u64 context_a,
148278 + u32 context_b);
148279 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq,
148280 + u64 *context_a,
148281 + u32 *context_b);
148282 +
148283 +/**
148284 + * qman_ceetm_create_fq - Initialise a FQ object for the LFQ.
148285 + * @lfq: the given logic fq.
148286 + * @fq: the fq object created for the given logic fq.
148287 + *
148288 + * The FQ object can be used in qman_enqueue() and qman_enqueue_orp() APIs to
148289 + * target a logical FQID (and the class queue it is associated with).
148290 + * Note that this FQ object can only be used for enqueues, and
148291 + * in the case of qman_enqueue_orp() it can not be used as the 'orp' parameter,
148292 + * only as 'fq'. This FQ object can not (and shouldn't) be destroyed, it is only
148293 + * valid as long as the underlying 'lfq' remains claimed. It is the user's
148294 + * responsibility to ensure that the underlying 'lfq' is not released until any
148295 + * enqueues to this FQ object have completed. The only field the user needs to
148296 + * fill in is fq->cb.ern, as that enqueue rejection handler is the callback that
148297 + * could conceivably be called on this FQ object. This API can be called
148298 + * multiple times to create multiple FQ objects referring to the same logical
148299 + * FQID, and any enqueue rejections will respect the callback of the object that
148300 + * issued the enqueue (and will identify the object via the parameter passed to
148301 + * the callback too). There is no 'flags' parameter to this API as there is for
148302 + * qman_create_fq() - the created FQ object behaves as though qman_create_fq()
148303 + * had been called with the single flag QMAN_FQ_FLAG_NO_MODIFY.
148304 + *
148305 + * Returns 0 for success.
148306 + */
148307 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq);
148308 +
148309 + /* -------------------------------- */
148310 + /* CEETM :: class congestion groups */
148311 + /* -------------------------------- */
148312 +
148313 +/**
148314 + * qman_ceetm_ccg_claim - Claims an unused CCG.
148315 + * @ccg: the returned CCG object, if successful.
148316 + * @channel: the given class queue channel
148317 + * @cscn: the callback function of this CCG.
148318 + * @cb_ctx: the corresponding context to be used used if state change
148319 + * notifications are later enabled for this CCG.
148320 + *
148321 + * The congestion group is local to the given class queue channel, so only
148322 + * class queues within the channel can be associated with that congestion group.
148323 + * The association of class queues to congestion groups occurs when the class
148324 + * queues are claimed, see qman_ceetm_cq_claim() and related functions.
148325 + * Congestion groups are in a "zero" state when initially claimed, and they are
148326 + * returned to that state when released.
148327 + *
148328 + * Return zero for success, or -EINVAL if no CCG in the channel is available.
148329 + */
148330 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
148331 + struct qm_ceetm_channel *channel,
148332 + unsigned int idx,
148333 + void (*cscn)(struct qm_ceetm_ccg *,
148334 + void *cb_ctx,
148335 + int congested),
148336 + void *cb_ctx);
148337 +
148338 +/**
148339 + * qman_ceetm_ccg_release - Releases a previously claimed CCG.
148340 + * @ccg: the given ccg.
148341 + *
148342 + * Returns zero for success, or -EBUSY if the given ccg's dependent objects
148343 + * (class queues that are associated with the CCG) have not been released.
148344 + */
148345 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg);
148346 +
148347 +/* This struct is used to specify attributes for a CCG. The 'we_mask' field
148348 + * controls which CCG attributes are to be updated, and the remainder specify
148349 + * the values for those attributes. A CCG counts either frames or the bytes
148350 + * within those frames, but not both ('mode'). A CCG can optionally cause
148351 + * enqueues to be rejected, due to tail-drop or WRED, or both (they are
148352 + * independent options, 'td_en' and 'wr_en_g,wr_en_y,wr_en_r'). Tail-drop can be
148353 + * level-triggered due to a single threshold ('td_thres') or edge-triggered due
148354 + * to a "congestion state", but not both ('td_mode'). Congestion state has
148355 + * distinct entry and exit thresholds ('cs_thres_in' and 'cs_thres_out'), and
148356 + * notifications can be sent to software the CCG goes in to and out of this
148357 + * congested state ('cscn_en'). */
148358 +struct qm_ceetm_ccg_params {
148359 + /* Boolean fields together in a single bitfield struct */
148360 + struct {
148361 + /* Whether to count bytes or frames. 1==frames */
148362 + u8 mode:1;
148363 + /* En/disable tail-drop. 1==enable */
148364 + u8 td_en:1;
148365 + /* Tail-drop on congestion-state or threshold. 1=threshold */
148366 + u8 td_mode:1;
148367 + /* Generate congestion state change notifications. 1==enable */
148368 + u8 cscn_en:1;
148369 + /* Enable WRED rejections (per colour). 1==enable */
148370 + u8 wr_en_g:1;
148371 + u8 wr_en_y:1;
148372 + u8 wr_en_r:1;
148373 + } __packed;
148374 + /* Tail-drop threshold. See qm_cgr_thres_[gs]et64(). */
148375 + struct qm_cgr_cs_thres td_thres;
148376 + /* Congestion state thresholds, for entry and exit. */
148377 + struct qm_cgr_cs_thres cs_thres_in;
148378 + struct qm_cgr_cs_thres cs_thres_out;
148379 + /* Overhead accounting length. Per-packet "tax", from -128 to +127 */
148380 + signed char oal;
148381 + /* Congestion state change notification for DCP portal, virtual CCGID*/
148382 + /* WRED parameters. */
148383 + struct qm_cgr_wr_parm wr_parm_g;
148384 + struct qm_cgr_wr_parm wr_parm_y;
148385 + struct qm_cgr_wr_parm wr_parm_r;
148386 +};
148387 +/* Bits used in 'we_mask' to qman_ceetm_ccg_set(), controls which attributes of
148388 + * the CCGR are to be updated. */
148389 +#define QM_CCGR_WE_MODE 0x0001 /* mode (bytes/frames) */
148390 +#define QM_CCGR_WE_CS_THRES_IN 0x0002 /* congestion state entry threshold */
148391 +#define QM_CCGR_WE_TD_EN 0x0004 /* congestion state tail-drop enable */
148392 +#define QM_CCGR_WE_CSCN_TUPD 0x0008 /* CSCN target update */
148393 +#define QM_CCGR_WE_CSCN_EN 0x0010 /* congestion notification enable */
148394 +#define QM_CCGR_WE_WR_EN_R 0x0020 /* WRED enable - red */
148395 +#define QM_CCGR_WE_WR_EN_Y 0x0040 /* WRED enable - yellow */
148396 +#define QM_CCGR_WE_WR_EN_G 0x0080 /* WRED enable - green */
148397 +#define QM_CCGR_WE_WR_PARM_R 0x0100 /* WRED parameters - red */
148398 +#define QM_CCGR_WE_WR_PARM_Y 0x0200 /* WRED parameters - yellow */
148399 +#define QM_CCGR_WE_WR_PARM_G 0x0400 /* WRED parameters - green */
148400 +#define QM_CCGR_WE_OAL 0x0800 /* overhead accounting length */
148401 +#define QM_CCGR_WE_CS_THRES_OUT 0x1000 /* congestion state exit threshold */
148402 +#define QM_CCGR_WE_TD_THRES 0x2000 /* tail-drop threshold */
148403 +#define QM_CCGR_WE_TD_MODE 0x4000 /* tail-drop mode (state/threshold) */
148404 +#define QM_CCGR_WE_CDV 0x8000 /* cdv */
148405 +
148406 +/**
148407 + * qman_ceetm_ccg_set
148408 + * qman_ceetm_ccg_get - Configure/query a subset of CCG attributes.
148409 + * @ccg: the given CCG object.
148410 + * @we_mask: the write enable mask.
148411 + * @params: the parameters setting for this ccg
148412 + *
148413 + * Return 0 for success, or -EIO if configure ccg command returns error for
148414 + * "set" function, or -EINVAL if query ccg command returns error for "get"
148415 + * function.
148416 + */
148417 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg,
148418 + u16 we_mask,
148419 + const struct qm_ceetm_ccg_params *params);
148420 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
148421 + struct qm_ceetm_ccg_params *params);
148422 +
148423 +/** qman_ceetm_cscn_swp_set - Add or remove a software portal from the target
148424 + * mask.
148425 + * qman_ceetm_cscn_swp_get - Query whether a given software portal index is
148426 + * in the cscn target mask.
148427 + * @ccg: the give CCG object.
148428 + * @swp_idx: the index of the software portal.
148429 + * @cscn_enabled: 1: Set the swp to be cscn target. 0: remove the swp from
148430 + * the target mask.
148431 + * @we_mask: the write enable mask.
148432 + * @params: the parameters setting for this ccg
148433 + *
148434 + * Return 0 for success, or -EINVAL if command in set/get function fails.
148435 + */
148436 +int qman_ceetm_cscn_swp_set(struct qm_ceetm_ccg *ccg,
148437 + u16 swp_idx,
148438 + unsigned int cscn_enabled,
148439 + u16 we_mask,
148440 + const struct qm_ceetm_ccg_params *params);
148441 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
148442 + u16 swp_idx,
148443 + unsigned int *cscn_enabled);
148444 +
148445 +/** qman_ceetm_cscn_dcp_set - Add or remove a direct connect portal from the\
148446 + * target mask.
148447 + * qman_ceetm_cscn_dcp_get - Query whether a given direct connect portal index
148448 + * is in the cscn target mask.
148449 + * @ccg: the give CCG object.
148450 + * @dcp_idx: the index of the direct connect portal.
148451 + * @vcgid: congestion state change notification for dcp portal, virtual CGID.
148452 + * @cscn_enabled: 1: Set the dcp to be cscn target. 0: remove the dcp from
148453 + * the target mask.
148454 + * @we_mask: the write enable mask.
148455 + * @params: the parameters setting for this ccg
148456 + *
148457 + * Return 0 for success, or -EINVAL if command in set/get function fails.
148458 + */
148459 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
148460 + u16 dcp_idx,
148461 + u8 vcgid,
148462 + unsigned int cscn_enabled,
148463 + u16 we_mask,
148464 + const struct qm_ceetm_ccg_params *params);
148465 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
148466 + u16 dcp_idx,
148467 + u8 *vcgid,
148468 + unsigned int *cscn_enabled);
148469 +
148470 +/**
148471 + * qman_ceetm_ccg_get_reject_statistics - Get the statistics provided by
148472 + * CEETM CCG counters.
148473 + * @ccg: the given CCG object.
148474 + * @flags: indicates whether the statistics counter will be cleared after query.
148475 + * @frame_count: The number of the frames that have been counted since the
148476 + * counter was cleared last time.
148477 + * @byte_count: the number of bytes in all frames that have been counted.
148478 + *
148479 + * Return zero for success or -EINVAL if query statistics command returns error.
148480 + *
148481 + */
148482 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
148483 + u64 *frame_count, u64 *byte_count);
148484 +
148485 +/**
148486 + * qman_ceetm_query_lfqmt - Query the logical frame queue mapping table
148487 + * @lfqid: Logical Frame Queue ID
148488 + * @lfqmt_query: Results of the query command
148489 + *
148490 + * Returns zero for success or -EIO if the query command returns error.
148491 + *
148492 + */
148493 +int qman_ceetm_query_lfqmt(int lfqid,
148494 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query);
148495 +
148496 +/**
148497 + * qman_ceetm_query_write_statistics - Query (and optionally write) statistics
148498 + * @cid: Target ID (CQID or CCGRID)
148499 + * @dcp_idx: CEETM portal ID
148500 + * @command_type: One of the following:
148501 + * 0 = Query dequeue statistics. CID carries the CQID to be queried.
148502 + * 1 = Query and clear dequeue statistics. CID carries the CQID to be queried
148503 + * 2 = Write dequeue statistics. CID carries the CQID to be written.
148504 + * 3 = Query reject statistics. CID carries the CCGRID to be queried.
148505 + * 4 = Query and clear reject statistics. CID carries the CCGRID to be queried
148506 + * 5 = Write reject statistics. CID carries the CCGRID to be written
148507 + * @frame_count: Frame count value to be written if this is a write command
148508 + * @byte_count: Bytes count value to be written if this is a write command
148509 + *
148510 + * Returns zero for success or -EIO if the query command returns error.
148511 + */
148512 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
148513 + u16 command_type, u64 frame_count,
148514 + u64 byte_count);
148515 +
148516 +/**
148517 + * qman_set_wpm - Set waterfall power management
148518 + *
148519 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
148520 + *
148521 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
148522 + * accessible.
148523 + */
148524 +int qman_set_wpm(int wpm_enable);
148525 +
148526 +/**
148527 + * qman_get_wpm - Query the waterfall power management setting
148528 + *
148529 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
148530 + *
148531 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
148532 + * accessible.
148533 + */
148534 +int qman_get_wpm(int *wpm_enable);
148535 +
148536 +/* The below qman_p_***() variants might be called in a migration situation
148537 + * (e.g. cpu hotplug). They are used to continue accessing the portal that
148538 + * execution was affine to prior to migration.
148539 + * @qman_portal specifies which portal the APIs will use.
148540 +*/
148541 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal
148542 + *p);
148543 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits);
148544 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits);
148545 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit);
148546 +u32 qman_p_poll_slow(struct qman_portal *p);
148547 +void qman_p_poll(struct qman_portal *p);
148548 +void qman_p_stop_dequeues(struct qman_portal *p);
148549 +void qman_p_start_dequeues(struct qman_portal *p);
148550 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools);
148551 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools);
148552 +u32 qman_p_static_dequeue_get(struct qman_portal *p);
148553 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
148554 + int park_request);
148555 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
148556 + u32 flags __maybe_unused, u32 vdqcr);
148557 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
148558 + const struct qm_fd *fd, u32 flags);
148559 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
148560 + const struct qm_fd *fd, u32 flags,
148561 + struct qman_fq *orp, u16 orp_seqnum);
148562 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
148563 + const struct qm_fd *fd, u32 flags,
148564 + qman_cb_precommit cb, void *cb_arg);
148565 +#ifdef __cplusplus
148566 +}
148567 +#endif
148568 +
148569 +#endif /* FSL_QMAN_H */
148570 --- /dev/null
148571 +++ b/include/linux/fsl_usdpaa.h
148572 @@ -0,0 +1,372 @@
148573 +/* Copyright 2011-2012 Freescale Semiconductor, Inc.
148574 + *
148575 + * This file is licensed under the terms of the GNU General Public License
148576 + * version 2. This program is licensed "as is" without any warranty of any
148577 + * kind, whether express or implied.
148578 + */
148579 +
148580 +#ifndef FSL_USDPAA_H
148581 +#define FSL_USDPAA_H
148582 +
148583 +#ifdef __cplusplus
148584 +extern "C" {
148585 +#endif
148586 +
148587 +#include <linux/uaccess.h>
148588 +#include <linux/ioctl.h>
148589 +#include <linux/fsl_qman.h> /* For "enum qm_channel" */
148590 +#include <linux/compat.h>
148591 +
148592 +#ifdef CONFIG_FSL_USDPAA
148593 +
148594 +/******************************/
148595 +/* Allocation of resource IDs */
148596 +/******************************/
148597 +
148598 +/* This enum is used to distinguish between the type of underlying object being
148599 + * manipulated. */
148600 +enum usdpaa_id_type {
148601 + usdpaa_id_fqid,
148602 + usdpaa_id_bpid,
148603 + usdpaa_id_qpool,
148604 + usdpaa_id_cgrid,
148605 + usdpaa_id_ceetm0_lfqid,
148606 + usdpaa_id_ceetm0_channelid,
148607 + usdpaa_id_ceetm1_lfqid,
148608 + usdpaa_id_ceetm1_channelid,
148609 + usdpaa_id_max /* <-- not a valid type, represents the number of types */
148610 +};
148611 +#define USDPAA_IOCTL_MAGIC 'u'
148612 +struct usdpaa_ioctl_id_alloc {
148613 + uint32_t base; /* Return value, the start of the allocated range */
148614 + enum usdpaa_id_type id_type; /* what kind of resource(s) to allocate */
148615 + uint32_t num; /* how many IDs to allocate (and return value) */
148616 + uint32_t align; /* must be a power of 2, 0 is treated like 1 */
148617 + int partial; /* whether to allow less than 'num' */
148618 +};
148619 +struct usdpaa_ioctl_id_release {
148620 + /* Input; */
148621 + enum usdpaa_id_type id_type;
148622 + uint32_t base;
148623 + uint32_t num;
148624 +};
148625 +struct usdpaa_ioctl_id_reserve {
148626 + enum usdpaa_id_type id_type;
148627 + uint32_t base;
148628 + uint32_t num;
148629 +};
148630 +
148631 +
148632 +/* ioctl() commands */
148633 +#define USDPAA_IOCTL_ID_ALLOC \
148634 + _IOWR(USDPAA_IOCTL_MAGIC, 0x01, struct usdpaa_ioctl_id_alloc)
148635 +#define USDPAA_IOCTL_ID_RELEASE \
148636 + _IOW(USDPAA_IOCTL_MAGIC, 0x02, struct usdpaa_ioctl_id_release)
148637 +#define USDPAA_IOCTL_ID_RESERVE \
148638 + _IOW(USDPAA_IOCTL_MAGIC, 0x0A, struct usdpaa_ioctl_id_reserve)
148639 +
148640 +/**********************/
148641 +/* Mapping DMA memory */
148642 +/**********************/
148643 +
148644 +/* Maximum length for a map name, including NULL-terminator */
148645 +#define USDPAA_DMA_NAME_MAX 16
148646 +/* Flags for requesting DMA maps. Maps are private+unnamed or sharable+named.
148647 + * For a sharable and named map, specify _SHARED (whether creating one or
148648 + * binding to an existing one). If _SHARED is specified and _CREATE is not, then
148649 + * the mapping must already exist. If _SHARED and _CREATE are specified and the
148650 + * mapping doesn't already exist, it will be created. If _SHARED and _CREATE are
148651 + * specified and the mapping already exists, the mapping will fail unless _LAZY
148652 + * is specified. When mapping to a pre-existing sharable map, the length must be
148653 + * an exact match. Lengths must be a power-of-4 multiple of page size.
148654 + *
148655 + * Note that this does not actually map the memory to user-space, that is done
148656 + * by a subsequent mmap() using the page offset returned from this ioctl(). The
148657 + * ioctl() is what gives the process permission to do this, and a page-offset
148658 + * with which to do so.
148659 + */
148660 +#define USDPAA_DMA_FLAG_SHARE 0x01
148661 +#define USDPAA_DMA_FLAG_CREATE 0x02
148662 +#define USDPAA_DMA_FLAG_LAZY 0x04
148663 +#define USDPAA_DMA_FLAG_RDONLY 0x08
148664 +struct usdpaa_ioctl_dma_map {
148665 + /* Output parameters - virtual and physical addresses */
148666 + void *ptr;
148667 + uint64_t phys_addr;
148668 + /* Input parameter, the length of the region to be created (or if
148669 + * mapping an existing region, this must match it). Must be a power-of-4
148670 + * multiple of page size. */
148671 + uint64_t len;
148672 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
148673 + uint32_t flags;
148674 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
148675 + * of the existing mapping to use). */
148676 + char name[USDPAA_DMA_NAME_MAX];
148677 + /* If this ioctl() creates the mapping, this is an input parameter
148678 + * stating whether the region supports locking. If mapping an existing
148679 + * region, this is a return value indicating the same thing. */
148680 + int has_locking;
148681 + /* In the case of a successful map with _CREATE and _LAZY, this return
148682 + * value indicates whether we created the mapped region or whether it
148683 + * already existed. */
148684 + int did_create;
148685 +};
148686 +
148687 +#ifdef CONFIG_COMPAT
148688 +struct usdpaa_ioctl_dma_map_compat {
148689 + /* Output parameters - virtual and physical addresses */
148690 + compat_uptr_t ptr;
148691 + uint64_t phys_addr;
148692 + /* Input parameter, the length of the region to be created (or if
148693 + * mapping an existing region, this must match it). Must be a power-of-4
148694 + * multiple of page size. */
148695 + uint64_t len;
148696 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
148697 + uint32_t flags;
148698 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
148699 + * of the existing mapping to use). */
148700 + char name[USDPAA_DMA_NAME_MAX];
148701 + /* If this ioctl() creates the mapping, this is an input parameter
148702 + * stating whether the region supports locking. If mapping an existing
148703 + * region, this is a return value indicating the same thing. */
148704 + int has_locking;
148705 + /* In the case of a successful map with _CREATE and _LAZY, this return
148706 + * value indicates whether we created the mapped region or whether it
148707 + * already existed. */
148708 + int did_create;
148709 +};
148710 +
148711 +#define USDPAA_IOCTL_DMA_MAP_COMPAT \
148712 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map_compat)
148713 +#endif
148714 +
148715 +
148716 +#define USDPAA_IOCTL_DMA_MAP \
148717 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map)
148718 +/* munmap() does not remove the DMA map, just the user-space mapping to it.
148719 + * This ioctl will do both (though you can munmap() before calling the ioctl
148720 + * too). */
148721 +#define USDPAA_IOCTL_DMA_UNMAP \
148722 + _IOW(USDPAA_IOCTL_MAGIC, 0x04, unsigned char)
148723 +/* We implement a cross-process locking scheme per DMA map. Call this ioctl()
148724 + * with a mmap()'d address, and the process will (interruptible) sleep if the
148725 + * lock is already held by another process. Process destruction will
148726 + * automatically clean up any held locks. */
148727 +#define USDPAA_IOCTL_DMA_LOCK \
148728 + _IOW(USDPAA_IOCTL_MAGIC, 0x05, unsigned char)
148729 +#define USDPAA_IOCTL_DMA_UNLOCK \
148730 + _IOW(USDPAA_IOCTL_MAGIC, 0x06, unsigned char)
148731 +
148732 +/***************************************/
148733 +/* Mapping and using QMan/BMan portals */
148734 +/***************************************/
148735 +enum usdpaa_portal_type {
148736 + usdpaa_portal_qman,
148737 + usdpaa_portal_bman,
148738 +};
148739 +
148740 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
148741 +
148742 +struct usdpaa_ioctl_portal_map {
148743 + /* Input parameter, is a qman or bman portal required. */
148744 +
148745 + enum usdpaa_portal_type type;
148746 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148747 + for don't care. The portal index will be populated by the
148748 + driver when the ioctl() successfully completes */
148749 + uint32_t index;
148750 +
148751 + /* Return value if the map succeeds, this gives the mapped
148752 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
148753 + struct usdpaa_portal_map {
148754 + void *cinh;
148755 + void *cena;
148756 + } addr;
148757 + /* Qman-specific return values */
148758 + uint16_t channel;
148759 + uint32_t pools;
148760 +};
148761 +
148762 +#ifdef CONFIG_COMPAT
148763 +struct compat_usdpaa_ioctl_portal_map {
148764 + /* Input parameter, is a qman or bman portal required. */
148765 + enum usdpaa_portal_type type;
148766 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148767 + for don't care. The portal index will be populated by the
148768 + driver when the ioctl() successfully completes */
148769 + uint32_t index;
148770 + /* Return value if the map succeeds, this gives the mapped
148771 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
148772 + struct usdpaa_portal_map_compat {
148773 + compat_uptr_t cinh;
148774 + compat_uptr_t cena;
148775 + } addr;
148776 + /* Qman-specific return values */
148777 + uint16_t channel;
148778 + uint32_t pools;
148779 +};
148780 +#define USDPAA_IOCTL_PORTAL_MAP_COMPAT \
148781 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct compat_usdpaa_ioctl_portal_map)
148782 +#define USDPAA_IOCTL_PORTAL_UNMAP_COMPAT \
148783 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map_compat)
148784 +#endif
148785 +
148786 +#define USDPAA_IOCTL_PORTAL_MAP \
148787 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct usdpaa_ioctl_portal_map)
148788 +#define USDPAA_IOCTL_PORTAL_UNMAP \
148789 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map)
148790 +
148791 +struct usdpaa_ioctl_irq_map {
148792 + enum usdpaa_portal_type type; /* Type of portal to map */
148793 + int fd; /* File descriptor that contains the portal */
148794 + void *portal_cinh; /* Cache inhibited area to identify the portal */
148795 +};
148796 +
148797 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP \
148798 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct usdpaa_ioctl_irq_map)
148799 +
148800 +#ifdef CONFIG_COMPAT
148801 +
148802 +struct compat_ioctl_irq_map {
148803 + enum usdpaa_portal_type type; /* Type of portal to map */
148804 + compat_int_t fd; /* File descriptor that contains the portal */
148805 + compat_uptr_t portal_cinh; /* Used identify the portal */};
148806 +
148807 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT \
148808 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct compat_ioctl_irq_map)
148809 +#endif
148810 +
148811 +/* ioctl to query the amount of DMA memory used in the system */
148812 +struct usdpaa_ioctl_dma_used {
148813 + uint64_t free_bytes;
148814 + uint64_t total_bytes;
148815 +};
148816 +#define USDPAA_IOCTL_DMA_USED \
148817 + _IOR(USDPAA_IOCTL_MAGIC, 0x0B, struct usdpaa_ioctl_dma_used)
148818 +
148819 +/* ioctl to allocate a raw portal */
148820 +struct usdpaa_ioctl_raw_portal {
148821 + /* inputs */
148822 + enum usdpaa_portal_type type; /* Type of portal to allocate */
148823 +
148824 + /* set to non zero to turn on stashing */
148825 + uint8_t enable_stash;
148826 + /* Stashing attributes for the portal */
148827 + uint32_t cpu;
148828 + uint32_t cache;
148829 + uint32_t window;
148830 +
148831 + /* Specifies the stash request queue this portal should use */
148832 + uint8_t sdest;
148833 +
148834 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148835 + * for don't care. The portal index will be populated by the
148836 + * driver when the ioctl() successfully completes */
148837 + uint32_t index;
148838 +
148839 + /* outputs */
148840 + uint64_t cinh;
148841 + uint64_t cena;
148842 +};
148843 +
148844 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL \
148845 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct usdpaa_ioctl_raw_portal)
148846 +
148847 +#define USDPAA_IOCTL_FREE_RAW_PORTAL \
148848 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct usdpaa_ioctl_raw_portal)
148849 +
148850 +#ifdef CONFIG_COMPAT
148851 +
148852 +struct compat_ioctl_raw_portal {
148853 + /* inputs */
148854 + enum usdpaa_portal_type type; /* Type of portal to allocate */
148855 +
148856 + /* set to non zero to turn on stashing */
148857 + uint8_t enable_stash;
148858 + /* Stashing attributes for the portal */
148859 + uint32_t cpu;
148860 + uint32_t cache;
148861 + uint32_t window;
148862 + /* Specifies the stash request queue this portal should use */
148863 + uint8_t sdest;
148864 +
148865 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148866 + * for don't care. The portal index will be populated by the
148867 + * driver when the ioctl() successfully completes */
148868 + uint32_t index;
148869 +
148870 + /* outputs */
148871 + uint64_t cinh;
148872 + uint64_t cena;
148873 +};
148874 +
148875 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT \
148876 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct compat_ioctl_raw_portal)
148877 +
148878 +#define USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT \
148879 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct compat_ioctl_raw_portal)
148880 +
148881 +#endif
148882 +
148883 +#ifdef __KERNEL__
148884 +
148885 +/* Early-boot hook */
148886 +int __init fsl_usdpaa_init_early(void);
148887 +
148888 +/* Fault-handling in arch/powerpc/mm/mem.c gives USDPAA an opportunity to detect
148889 + * faults within its ranges via this hook. */
148890 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size);
148891 +
148892 +#endif /* __KERNEL__ */
148893 +
148894 +#endif /* CONFIG_FSL_USDPAA */
148895 +
148896 +#ifdef __KERNEL__
148897 +/* This interface is needed in a few places and though it's not specific to
148898 + * USDPAA as such, creating a new header for it doesn't make any sense. The
148899 + * qbman kernel driver implements this interface and uses it as the backend for
148900 + * both the FQID and BPID allocators. The fsl_usdpaa driver also uses this
148901 + * interface for tracking per-process allocations handed out to user-space. */
148902 +struct dpa_alloc {
148903 + struct list_head free;
148904 + spinlock_t lock;
148905 + struct list_head used;
148906 +};
148907 +#define DECLARE_DPA_ALLOC(name) \
148908 + struct dpa_alloc name = { \
148909 + .free = { \
148910 + .prev = &name.free, \
148911 + .next = &name.free \
148912 + }, \
148913 + .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
148914 + .used = { \
148915 + .prev = &name.used, \
148916 + .next = &name.used \
148917 + } \
148918 + }
148919 +static inline void dpa_alloc_init(struct dpa_alloc *alloc)
148920 +{
148921 + INIT_LIST_HEAD(&alloc->free);
148922 + INIT_LIST_HEAD(&alloc->used);
148923 + spin_lock_init(&alloc->lock);
148924 +}
148925 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
148926 + int partial);
148927 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count);
148928 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 fqid, u32 count);
148929 +
148930 +/* Like 'new' but specifies the desired range, returns -ENOMEM if the entire
148931 + * desired range is not available, or 0 for success. */
148932 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base_id, u32 count);
148933 +/* Pops and returns contiguous ranges from the allocator. Returns -ENOMEM when
148934 + * 'alloc' is empty. */
148935 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count);
148936 +/* Returns 1 if the specified id is alloced, 0 otherwise */
148937 +int dpa_alloc_check(struct dpa_alloc *list, u32 id);
148938 +#endif /* __KERNEL__ */
148939 +
148940 +#ifdef __cplusplus
148941 +}
148942 +#endif
148943 +
148944 +#endif /* FSL_USDPAA_H */
148945 --- /dev/null
148946 +++ b/include/uapi/linux/fmd/Kbuild
148947 @@ -0,0 +1,5 @@
148948 +header-y += integrations/
148949 +header-y += Peripherals/
148950 +
148951 +header-y += ioctls.h
148952 +header-y += net_ioctls.h
148953 --- /dev/null
148954 +++ b/include/uapi/linux/fmd/Peripherals/Kbuild
148955 @@ -0,0 +1,4 @@
148956 +header-y += fm_ioctls.h
148957 +header-y += fm_port_ioctls.h
148958 +header-y += fm_pcd_ioctls.h
148959 +header-y += fm_test_ioctls.h
148960 --- /dev/null
148961 +++ b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h
148962 @@ -0,0 +1,628 @@
148963 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
148964 + * All rights reserved.
148965 + *
148966 + * Redistribution and use in source and binary forms, with or without
148967 + * modification, are permitted provided that the following conditions are met:
148968 + * * Redistributions of source code must retain the above copyright
148969 + * notice, this list of conditions and the following disclaimer.
148970 + * * Redistributions in binary form must reproduce the above copyright
148971 + * notice, this list of conditions and the following disclaimer in the
148972 + * documentation and/or other materials provided with the distribution.
148973 + * * Neither the name of Freescale Semiconductor nor the
148974 + * names of its contributors may be used to endorse or promote products
148975 + * derived from this software without specific prior written permission.
148976 + *
148977 + *
148978 + * ALTERNATIVELY, this software may be distributed under the terms of the
148979 + * GNU General Public License ("GPL") as published by the Free Software
148980 + * Foundation, either version 2 of that License or (at your option) any
148981 + * later version.
148982 + *
148983 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
148984 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
148985 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
148986 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
148987 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
148988 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
148989 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
148990 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
148991 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
148992 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
148993 + */
148994 +
148995 +/**************************************************************************//**
148996 + @File fm_ioctls.h
148997 +
148998 + @Description FM Char device ioctls
148999 +*//***************************************************************************/
149000 +#ifndef __FM_IOCTLS_H
149001 +#define __FM_IOCTLS_H
149002 +
149003 +
149004 +/**************************************************************************//**
149005 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
149006 +
149007 + @Description FM Linux ioctls definitions and enums
149008 +
149009 + @{
149010 +*//***************************************************************************/
149011 +
149012 +/**************************************************************************//**
149013 + @Collection FM IOCTL device ('/dev') definitions
149014 +*//***************************************************************************/
149015 +#define DEV_FM_NAME "fm" /**< Name of the FM chardev */
149016 +
149017 +#define DEV_FM_MINOR_BASE 0
149018 +#define DEV_FM_PCD_MINOR_BASE (DEV_FM_MINOR_BASE + 1) /*/dev/fmx-pcd */
149019 +#define DEV_FM_OH_PORTS_MINOR_BASE (DEV_FM_PCD_MINOR_BASE + 1) /*/dev/fmx-port-ohy */
149020 +#define DEV_FM_RX_PORTS_MINOR_BASE (DEV_FM_OH_PORTS_MINOR_BASE + FM_MAX_NUM_OF_OH_PORTS) /*/dev/fmx-port-rxy */
149021 +#define DEV_FM_TX_PORTS_MINOR_BASE (DEV_FM_RX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_RX_PORTS) /*/dev/fmx-port-txy */
149022 +#define DEV_FM_MAX_MINORS (DEV_FM_TX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_TX_PORTS)
149023 +
149024 +#define FM_IOC_NUM(n) (n)
149025 +#define FM_PCD_IOC_NUM(n) (n+20)
149026 +#define FM_PORT_IOC_NUM(n) (n+70)
149027 +/* @} */
149028 +
149029 +#define IOC_FM_MAX_NUM_OF_PORTS 64
149030 +
149031 +
149032 +/**************************************************************************//**
149033 + @Description Enum for defining port types
149034 + (must match enum e_FmPortType defined in fm_ext.h)
149035 +*//***************************************************************************/
149036 +typedef enum ioc_fm_port_type {
149037 + e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
149038 + e_IOC_FM_PORT_TYPE_RX, /**< 1G Rx port */
149039 + e_IOC_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
149040 + e_IOC_FM_PORT_TYPE_TX, /**< 1G Tx port */
149041 + e_IOC_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
149042 + e_IOC_FM_PORT_TYPE_DUMMY
149043 +} ioc_fm_port_type;
149044 +
149045 +
149046 +/**************************************************************************//**
149047 + @Group lnx_ioctl_FM_lib_grp FM library
149048 +
149049 + @Description FM API functions, definitions and enums
149050 + The FM module is the main driver module and is a mandatory module
149051 + for FM driver users. Before any further module initialization,
149052 + this module must be initialized.
149053 + The FM is a "single-tone" module. It is responsible of the common
149054 + HW modules: FPM, DMA, common QMI, common BMI initializations and
149055 + run-time control routines. This module must be initialized always
149056 + when working with any of the FM modules.
149057 + NOTE - We assumes that the FML will be initialize only by core No. 0!
149058 +
149059 + @{
149060 +*//***************************************************************************/
149061 +
149062 +/**************************************************************************//**
149063 + @Description FM Exceptions
149064 +*//***************************************************************************/
149065 +typedef enum ioc_fm_exceptions {
149066 + e_IOC_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */
149067 + e_IOC_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
149068 + e_IOC_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
149069 + e_IOC_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
149070 + e_IOC_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
149071 + e_IOC_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
149072 + e_IOC_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
149073 + e_IOC_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
149074 + e_IOC_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
149075 + e_IOC_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
149076 + e_IOC_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
149077 + e_IOC_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
149078 + e_IOC_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
149079 + e_IOC_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
149080 + e_IOC_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
149081 + e_IOC_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
149082 + e_IOC_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
149083 +} ioc_fm_exceptions;
149084 +
149085 +/**************************************************************************//**
149086 + @Group lnx_ioctl_FM_runtime_control_grp FM Runtime Control Unit
149087 +
149088 + @Description FM Runtime control unit API functions, definitions and enums.
149089 + The FM driver provides a set of control routines for each module.
149090 + These routines may only be called after the module was fully
149091 + initialized (both configuration and initialization routines were
149092 + called). They are typically used to get information from hardware
149093 + (status, counters/statistics, revision etc.), to modify a current
149094 + state or to force/enable a required action. Run-time control may
149095 + be called whenever necessary and as many times as needed.
149096 + @{
149097 +*//***************************************************************************/
149098 +
149099 +/**************************************************************************//**
149100 + @Collection General FM defines.
149101 + *//***************************************************************************/
149102 +#define IOC_FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
149103 + FM_MAX_NUM_OF_1G_RX_PORTS + \
149104 + FM_MAX_NUM_OF_10G_RX_PORTS + \
149105 + FM_MAX_NUM_OF_1G_TX_PORTS + \
149106 + FM_MAX_NUM_OF_10G_TX_PORTS)
149107 +/* @} */
149108 +
149109 +/**************************************************************************//**
149110 + @Description Structure for Port bandwidth requirement. Port is identified
149111 + by type and relative id.
149112 + (must be identical to t_FmPortBandwidth defined in fm_ext.h)
149113 +*//***************************************************************************/
149114 +typedef struct ioc_fm_port_bandwidth_t {
149115 + ioc_fm_port_type type; /**< FM port type */
149116 + uint8_t relative_port_id; /**< Type relative port id */
149117 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
149118 +} ioc_fm_port_bandwidth_t;
149119 +
149120 +/**************************************************************************//**
149121 + @Description A Structure containing an array of Port bandwidth requirements.
149122 + The user should state the ports requiring bandwidth in terms of
149123 + percentage - i.e. all port's bandwidths in the array must add
149124 + up to 100.
149125 + (must be identical to t_FmPortsBandwidthParams defined in fm_ext.h)
149126 +*//***************************************************************************/
149127 +typedef struct ioc_fm_port_bandwidth_params {
149128 + uint8_t num_of_ports;
149129 + /**< num of ports listed in the array below */
149130 + ioc_fm_port_bandwidth_t ports_bandwidths[IOC_FM_MAX_NUM_OF_VALID_PORTS];
149131 + /**< for each port, it's bandwidth (all port's
149132 + bandwidths must add up to 100.*/
149133 +} ioc_fm_port_bandwidth_params;
149134 +
149135 +/**************************************************************************//**
149136 + @Description enum for defining FM counters
149137 +*//***************************************************************************/
149138 +typedef enum ioc_fm_counters {
149139 + e_IOC_FM_COUNTERS_ENQ_TOTAL_FRAME, /**< QMI total enqueued frames counter */
149140 + e_IOC_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
149141 + e_IOC_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
149142 + e_IOC_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
149143 + e_IOC_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
149144 + e_IOC_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
149145 + e_IOC_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
149146 + e_IOC_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
149147 + e_IOC_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
149148 + e_IOC_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
149149 +} ioc_fm_counters;
149150 +
149151 +typedef struct ioc_fm_obj_t {
149152 + void *obj;
149153 +} ioc_fm_obj_t;
149154 +
149155 +/**************************************************************************//**
149156 + @Description A structure for returning revision information
149157 + (must match struct t_FmRevisionInfo declared in fm_ext.h)
149158 +*//***************************************************************************/
149159 +typedef struct ioc_fm_revision_info_t {
149160 + uint8_t major; /**< Major revision */
149161 + uint8_t minor; /**< Minor revision */
149162 +} ioc_fm_revision_info_t;
149163 +
149164 +/**************************************************************************//**
149165 + @Description A structure for FM counters
149166 +*//***************************************************************************/
149167 +typedef struct ioc_fm_counters_params_t {
149168 + ioc_fm_counters cnt; /**< The requested counter */
149169 + uint32_t val; /**< The requested value to get/set from/into the counter */
149170 +} ioc_fm_counters_params_t;
149171 +
149172 +typedef union ioc_fm_api_version_t {
149173 + struct {
149174 + uint8_t major;
149175 + uint8_t minor;
149176 + uint8_t respin;
149177 + uint8_t reserved;
149178 + } version;
149179 + uint32_t ver;
149180 +} ioc_fm_api_version_t;
149181 +
149182 +#if (DPAA_VERSION >= 11)
149183 +/**************************************************************************//**
149184 + @Description A structure of information about each of the external
149185 + buffer pools used by a port or storage-profile.
149186 + (must be identical to t_FmExtPoolParams defined in fm_ext.h)
149187 +*//***************************************************************************/
149188 +typedef struct ioc_fm_ext_pool_params {
149189 + uint8_t id; /**< External buffer pool id */
149190 + uint16_t size; /**< External buffer pool buffer size */
149191 +} ioc_fm_ext_pool_params;
149192 +
149193 +/**************************************************************************//**
149194 + @Description A structure for informing the driver about the external
149195 + buffer pools allocated in the BM and used by a port or a
149196 + storage-profile.
149197 + (must be identical to t_FmExtPools defined in fm_ext.h)
149198 +*//***************************************************************************/
149199 +typedef struct ioc_fm_ext_pools {
149200 + uint8_t num_of_pools_used; /**< Number of pools use by this port */
149201 + ioc_fm_ext_pool_params ext_buf_pool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
149202 + /**< Parameters for each port */
149203 +} ioc_fm_ext_pools;
149204 +
149205 +typedef struct ioc_fm_vsp_params_t {
149206 + void *p_fm; /**< A handle to the FM object this VSP related to */
149207 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
149208 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
149209 + parameter associated with Rx / OP port */
149210 + uint16_t liodn_offset; /**< VSP's LIODN offset */
149211 + struct {
149212 + ioc_fm_port_type port_type; /**< Port type */
149213 + uint8_t port_id; /**< Port Id - relative to type */
149214 + } port_params;
149215 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
149216 + defined in relevant FM object */
149217 + void *id; /**< return value */
149218 +} ioc_fm_vsp_params_t;
149219 +#endif /* (DPAA_VERSION >= 11) */
149220 +
149221 +/**************************************************************************//**
149222 + @Description A structure for defining BM pool depletion criteria
149223 +*//***************************************************************************/
149224 +typedef struct ioc_fm_buf_pool_depletion_t {
149225 + bool pools_grp_mode_enable; /**< select mode in which pause frames will be sent after
149226 + a number of pools (all together!) are depleted */
149227 + uint8_t num_of_pools; /**< the number of depleted pools that will invoke
149228 + pause frames transmission. */
149229 + bool pools_to_consider[BM_MAX_NUM_OF_POOLS];
149230 + /**< For each pool, TRUE if it should be considered for
149231 + depletion (Note - this pool must be used by this port!). */
149232 + bool single_pool_mode_enable; /**< select mode in which pause frames will be sent after
149233 + a single-pool is depleted; */
149234 + bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS];
149235 + /**< For each pool, TRUE if it should be considered for
149236 + depletion (Note - this pool must be used by this port!) */
149237 +#if (DPAA_VERSION >= 11)
149238 + bool pfc_priorities_en[FM_MAX_NUM_OF_PFC_PRIORITIES];
149239 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame
149240 + which is transmitted */
149241 +#endif /* (DPAA_VERSION >= 11) */
149242 +} ioc_fm_buf_pool_depletion_t;
149243 +
149244 +#if (DPAA_VERSION >= 11)
149245 +typedef struct ioc_fm_buf_pool_depletion_params_t {
149246 + void *p_fm_vsp;
149247 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
149248 +} ioc_fm_buf_pool_depletion_params_t;
149249 +#endif /* (DPAA_VERSION >= 11) */
149250 +
149251 +typedef struct ioc_fm_buffer_prefix_content_t {
149252 + uint16_t priv_data_size; /**< Number of bytes to be left at the beginning
149253 + of the external buffer; Note that the private-area will
149254 + start from the base of the buffer address. */
149255 + bool pass_prs_result; /**< TRUE to pass the parse result to/from the FM;
149256 + User may use FM_PORT_GetBufferPrsResult() in order to
149257 + get the parser-result from a buffer. */
149258 + bool pass_time_stamp; /**< TRUE to pass the timeStamp to/from the FM
149259 + User may use FM_PORT_GetBufferTimeStamp() in order to
149260 + get the parser-result from a buffer. */
149261 + bool pass_hash_result; /**< TRUE to pass the KG hash result to/from the FM
149262 + User may use FM_PORT_GetBufferHashResult() in order to
149263 + get the parser-result from a buffer. */
149264 + bool pass_all_other_pcd_info; /**< Add all other Internal-Context information:
149265 + AD, hash-result, key, etc. */
149266 + uint16_t data_align; /**< 0 to use driver's default alignment [64],
149267 + other value for selecting a data alignment (must be a power of 2);
149268 + if write optimization is used, must be >= 16. */
149269 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
149270 + Note that this field impacts the size of the buffer-prefix
149271 + (i.e. it pushes the data offset);
149272 + This field is irrelevant if DPAA_VERSION==10 */
149273 +} ioc_fm_buffer_prefix_content_t;
149274 +
149275 +typedef struct ioc_fm_buffer_prefix_content_params_t {
149276 + void *p_fm_vsp;
149277 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
149278 +} ioc_fm_buffer_prefix_content_params_t;
149279 +
149280 +#if (DPAA_VERSION >= 11)
149281 +typedef struct ioc_fm_vsp_config_no_sg_params_t {
149282 + void *p_fm_vsp;
149283 + bool no_sg;
149284 +} ioc_fm_vsp_config_no_sg_params_t;
149285 +
149286 +typedef struct ioc_fm_vsp_prs_result_params_t {
149287 + void *p_fm_vsp;
149288 + void *p_data;
149289 +} ioc_fm_vsp_prs_result_params_t;
149290 +#endif
149291 +
149292 +typedef struct fm_ctrl_mon_t {
149293 + uint8_t percent_cnt[2];
149294 +} fm_ctrl_mon_t;
149295 +
149296 +typedef struct ioc_fm_ctrl_mon_counters_params_t {
149297 + uint8_t fm_ctrl_index;
149298 + fm_ctrl_mon_t *p_mon;
149299 +} ioc_fm_ctrl_mon_counters_params_t;
149300 +
149301 +/**************************************************************************//**
149302 + @Function FM_IOC_SET_PORTS_BANDWIDTH
149303 +
149304 + @Description Sets relative weights between ports when accessing common resources.
149305 +
149306 + @Param[in] ioc_fm_port_bandwidth_params Port bandwidth percentages,
149307 + their sum must equal 100.
149308 +
149309 + @Return E_OK on success; Error code otherwise.
149310 +
149311 + @Cautions Allowed only following FM_Init().
149312 +*//***************************************************************************/
149313 +#define FM_IOC_SET_PORTS_BANDWIDTH _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(2), ioc_fm_port_bandwidth_params)
149314 +
149315 +/**************************************************************************//**
149316 + @Function FM_IOC_GET_REVISION
149317 +
149318 + @Description Returns the FM revision
149319 +
149320 + @Param[out] ioc_fm_revision_info_t A structure of revision information parameters.
149321 +
149322 + @Return None.
149323 +
149324 + @Cautions Allowed only following FM_Init().
149325 +*//***************************************************************************/
149326 +#define FM_IOC_GET_REVISION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(3), ioc_fm_revision_info_t)
149327 +
149328 +/**************************************************************************//**
149329 + @Function FM_IOC_GET_COUNTER
149330 +
149331 + @Description Reads one of the FM counters.
149332 +
149333 + @Param[in,out] ioc_fm_counters_params_t The requested counter parameters.
149334 +
149335 + @Return Counter's current value.
149336 +
149337 + @Cautions Allowed only following FM_Init().
149338 + Note that it is user's responsibilty to call this routine only
149339 + for enabled counters, and there will be no indication if a
149340 + disabled counter is accessed.
149341 +*//***************************************************************************/
149342 +#define FM_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(4), ioc_fm_counters_params_t)
149343 +
149344 +/**************************************************************************//**
149345 + @Function FM_IOC_SET_COUNTER
149346 +
149347 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
149348 +
149349 + @Param[in] ioc_fm_counters_params_t The requested counter parameters.
149350 +
149351 + @Return E_OK on success; Error code otherwise.
149352 +
149353 + @Cautions Allowed only following FM_Init().
149354 +*//***************************************************************************/
149355 +#define FM_IOC_SET_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(5), ioc_fm_counters_params_t)
149356 +
149357 +/**************************************************************************//**
149358 + @Function FM_IOC_FORCE_INTR
149359 +
149360 + @Description Causes an interrupt event on the requested source.
149361 +
149362 + @Param[in] ioc_fm_exceptions An exception to be forced.
149363 +
149364 + @Return E_OK on success; Error code if the exception is not enabled,
149365 + or is not able to create interrupt.
149366 +
149367 + @Cautions Allowed only following FM_Init().
149368 +*//***************************************************************************/
149369 +#define FM_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(6), ioc_fm_exceptions)
149370 +
149371 +/**************************************************************************//**
149372 + @Function FM_IOC_GET_API_VERSION
149373 +
149374 + @Description Reads the FMD IOCTL API version.
149375 +
149376 + @Param[in,out] ioc_fm_api_version_t The requested counter parameters.
149377 +
149378 + @Return Version's value.
149379 +*//***************************************************************************/
149380 +#define FM_IOC_GET_API_VERSION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(7), ioc_fm_api_version_t)
149381 +
149382 +#if (DPAA_VERSION >= 11)
149383 +/**************************************************************************//**
149384 + @Function FM_VSP_Config
149385 +
149386 + @Description Creates descriptor for the FM VSP module.
149387 +
149388 + The routine returns a handle (descriptor) to the FM VSP object.
149389 + This descriptor must be passed as first parameter to all other
149390 + FM VSP function calls.
149391 +
149392 + No actual initialization or configuration of FM hardware is
149393 + done by this routine.
149394 +
149395 +@Param[in] p_FmVspParams Pointer to data structure of parameters
149396 +
149397 + @Retval Handle to FM VSP object, or NULL for Failure.
149398 +*//***************************************************************************/
149399 +#if defined(CONFIG_COMPAT)
149400 +#define FM_IOC_VSP_CONFIG_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_compat_fm_vsp_params_t)
149401 +#endif
149402 +#define FM_IOC_VSP_CONFIG _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_fm_vsp_params_t)
149403 +
149404 +/**************************************************************************//**
149405 + @Function FM_VSP_Init
149406 +
149407 + @Description Initializes the FM VSP module
149408 +
149409 + @Param[in] h_FmVsp - FM VSP module descriptor
149410 +
149411 + @Return E_OK on success; Error code otherwise.
149412 +*//***************************************************************************/
149413 +#if defined(CONFIG_COMPAT)
149414 +#define FM_IOC_VSP_INIT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_compat_fm_obj_t)
149415 +#endif
149416 +#define FM_IOC_VSP_INIT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_fm_obj_t)
149417 +
149418 +/**************************************************************************//**
149419 + @Function FM_VSP_Free
149420 +
149421 + @Description Frees all resources that were assigned to FM VSP module.
149422 +
149423 + Calling this routine invalidates the descriptor.
149424 +
149425 + @Param[in] h_FmVsp - FM VSP module descriptor
149426 +
149427 + @Return E_OK on success; Error code otherwise.
149428 +*//***************************************************************************/
149429 +#if defined(CONFIG_COMPAT)
149430 +#define FM_IOC_VSP_FREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_compat_fm_obj_t)
149431 +#endif
149432 +#define FM_IOC_VSP_FREE _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_fm_obj_t)
149433 +
149434 +/**************************************************************************//**
149435 + @Function FM_VSP_ConfigPoolDepletion
149436 +
149437 + @Description Calling this routine enables pause frame generation depending on the
149438 + depletion status of BM pools. It also defines the conditions to activate
149439 + this functionality. By default, this functionality is disabled.
149440 +
149441 + @Param[in] ioc_fm_buf_pool_depletion_params_t A structure holding the required parameters.
149442 +
149443 + @Return E_OK on success; Error code otherwise.
149444 +
149445 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149446 +*//***************************************************************************/
149447 +#if defined(CONFIG_COMPAT)
149448 +#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)
149449 +#endif
149450 +#define FM_IOC_VSP_CONFIG_POOL_DEPLETION _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_fm_buf_pool_depletion_params_t)
149451 +
149452 +/**************************************************************************//**
149453 + @Function FM_VSP_ConfigBufferPrefixContent
149454 +
149455 + @Description Defines the structure, size and content of the application buffer.
149456 +
149457 + The prefix will
149458 + In VSPs defined for Tx ports, if 'passPrsResult', the application
149459 + should set a value to their offsets in the prefix of
149460 + the FM will save the first 'privDataSize', than,
149461 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
149462 + and timeStamp, and the packet itself (in this order), to the
149463 + application buffer, and to offset.
149464 +
149465 + Calling this routine changes the buffer margins definitions
149466 + in the internal driver data base from its default
149467 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
149468 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
149469 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
149470 +
149471 + @Param[in] ioc_fm_buffer_prefix_content_params_t A structure holding the required parameters.
149472 +
149473 + @Return E_OK on success; Error code otherwise.
149474 +
149475 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149476 +*//***************************************************************************/
149477 +#if defined(CONFIG_COMPAT)
149478 +#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)
149479 +#endif
149480 +#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_fm_buffer_prefix_content_params_t)
149481 +
149482 +/**************************************************************************//**
149483 + @Function FM_VSP_ConfigNoScatherGather
149484 +
149485 + @Description Calling this routine changes the possibility to receive S/G frame
149486 + in the internal driver data base
149487 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
149488 +
149489 + @Param[in] ioc_fm_vsp_config_no_sg_params_t A structure holding the required parameters.
149490 +
149491 + @Return E_OK on success; Error code otherwise.
149492 +
149493 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149494 +*//***************************************************************************/
149495 +#if defined(CONFIG_COMPAT)
149496 +#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)
149497 +#endif
149498 +#define FM_IOC_VSP_CONFIG_NO_SG _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_fm_vsp_config_no_sg_params_t)
149499 +
149500 +/**************************************************************************//**
149501 + @Function FM_VSP_GetBufferPrsResult
149502 +
149503 + @Description Returns the pointer to the parse result in the data buffer.
149504 + In Rx ports this is relevant after reception, if parse
149505 + result is configured to be part of the data passed to the
149506 + application. For non Rx ports it may be used to get the pointer
149507 + of the area in the buffer where parse result should be
149508 + initialized - if so configured.
149509 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
149510 + configuration.
149511 +
149512 + @Param[in] ioc_fm_vsp_prs_result_params_t A structure holding the required parameters.
149513 +
149514 + @Return Parse result pointer on success, NULL if parse result was not
149515 + configured for this port.
149516 +
149517 + @Cautions Allowed only following FM_VSP_Init().
149518 +*//***************************************************************************/
149519 +#if defined(CONFIG_COMPAT)
149520 +#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)
149521 +#endif
149522 +#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_fm_vsp_prs_result_params_t)
149523 +#endif /* (DPAA_VERSION >= 11) */
149524 +
149525 +/**************************************************************************//**
149526 + @Function FM_CtrlMonStart
149527 +
149528 + @Description Start monitoring utilization of all available FM controllers.
149529 +
149530 + In order to obtain FM controllers utilization the following sequence
149531 + should be used:
149532 + -# FM_CtrlMonStart()
149533 + -# FM_CtrlMonStop()
149534 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149535 +
149536 + @Return E_OK on success; Error code otherwise.
149537 +
149538 + @Cautions Allowed only following FM_Init().
149539 +*//***************************************************************************/
149540 +#define FM_IOC_CTRL_MON_START _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(15))
149541 +
149542 +
149543 +/**************************************************************************//**
149544 + @Function FM_CtrlMonStop
149545 +
149546 + @Description Stop monitoring utilization of all available FM controllers.
149547 +
149548 + In order to obtain FM controllers utilization the following sequence
149549 + should be used:
149550 + -# FM_CtrlMonStart()
149551 + -# FM_CtrlMonStop()
149552 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149553 +
149554 + @Return E_OK on success; Error code otherwise.
149555 +
149556 + @Cautions Allowed only following FM_Init().
149557 +*//***************************************************************************/
149558 +#define FM_IOC_CTRL_MON_STOP _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(16))
149559 +
149560 +/**************************************************************************//**
149561 + @Function FM_CtrlMonGetCounters
149562 +
149563 + @Description Obtain FM controller utilization parameters.
149564 +
149565 + In order to obtain FM controllers utilization the following sequence
149566 + should be used:
149567 + -# FM_CtrlMonStart()
149568 + -# FM_CtrlMonStop()
149569 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149570 +
149571 + @Param[in] ioc_fm_ctrl_mon_counters_params_t A structure holding the required parameters.
149572 +
149573 + @Return E_OK on success; Error code otherwise.
149574 +
149575 + @Cautions Allowed only following FM_Init().
149576 +*//***************************************************************************/
149577 +#if defined(CONFIG_COMPAT)
149578 +#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)
149579 +#endif
149580 +#define FM_IOC_CTRL_MON_GET_COUNTERS _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_fm_ctrl_mon_counters_params_t)
149581 +
149582 +/** @} */ /* end of lnx_ioctl_FM_runtime_control_grp group */
149583 +/** @} */ /* end of lnx_ioctl_FM_lib_grp group */
149584 +/** @} */ /* end of lnx_ioctl_FM_grp */
149585 +
149586 +#define FMD_API_VERSION_MAJOR 21
149587 +#define FMD_API_VERSION_MINOR 1
149588 +#define FMD_API_VERSION_RESPIN 0
149589 +
149590 +#endif /* __FM_IOCTLS_H */
149591 --- /dev/null
149592 +++ b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
149593 @@ -0,0 +1,3084 @@
149594 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
149595 + * All rights reserved.
149596 + *
149597 + * Redistribution and use in source and binary forms, with or without
149598 + * modification, are permitted provided that the following conditions are met:
149599 + * * Redistributions of source code must retain the above copyright
149600 + * notice, this list of conditions and the following disclaimer.
149601 + * * Redistributions in binary form must reproduce the above copyright
149602 + * notice, this list of conditions and the following disclaimer in the
149603 + * documentation and/or other materials provided with the distribution.
149604 + * * Neither the name of Freescale Semiconductor nor the
149605 + * names of its contributors may be used to endorse or promote products
149606 + * derived from this software without specific prior written permission.
149607 + *
149608 + *
149609 + * ALTERNATIVELY, this software may be distributed under the terms of the
149610 + * GNU General Public License ("GPL") as published by the Free Software
149611 + * Foundation, either version 2 of that License or (at your option) any
149612 + * later version.
149613 + *
149614 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
149615 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
149616 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
149617 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
149618 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
149619 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
149620 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
149621 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
149622 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
149623 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
149624 + */
149625 +
149626 +
149627 +/******************************************************************************
149628 + @File fm_pcd_ioctls.h
149629 +
149630 + @Description FM PCD ...
149631 +*//***************************************************************************/
149632 +#ifndef __FM_PCD_IOCTLS_H
149633 +#define __FM_PCD_IOCTLS_H
149634 +
149635 +#include "net_ioctls.h"
149636 +#include "fm_ioctls.h"
149637 +
149638 +
149639 +/**************************************************************************//**
149640 +
149641 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
149642 +
149643 + @Description Frame Manager Linux ioctls definitions and enums
149644 +
149645 + @{
149646 +*//***************************************************************************/
149647 +
149648 +/**************************************************************************//**
149649 + @Group lnx_ioctl_FM_PCD_grp FM PCD
149650 +
149651 + @Description Frame Manager PCD API functions, definitions and enums
149652 +
149653 + The FM PCD module is responsible for the initialization of all
149654 + global classifying FM modules. This includes the parser general and
149655 + common registers, the key generator global and common registers,
149656 + and the policer global and common registers.
149657 + In addition, the FM PCD SW module will initialize all required
149658 + key generator schemes, coarse classification flows, and policer
149659 + profiles. When an FM module is configured to work with one of these
149660 + entities, it will register to it using the FM PORT API. The PCD
149661 + module will manage the PCD resources - i.e. resource management of
149662 + KeyGen schemes, etc.
149663 +
149664 + @{
149665 +*//***************************************************************************/
149666 +
149667 +/**************************************************************************//**
149668 + @Collection General PCD defines
149669 +*//***************************************************************************/
149670 +#define IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
149671 +
149672 +#define IOC_FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
149673 +#define IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
149674 + /**< Number of distinction units is limited by
149675 + register size (32 bits) minus reserved bits
149676 + for private headers. */
149677 +#define IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
149678 + in a distinction unit */
149679 +#define IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KeyGen registers */
149680 +#define IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
149681 + For HW implementation reasons, in most
149682 + cases less than this will be allowed; The
149683 + driver will return an initialization error
149684 + if resource is unavailable. */
149685 +#define IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
149686 +#define IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
149687 +
149688 +#define IOC_FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
149689 +#define IOC_FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
149690 +
149691 +#define IOC_FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
149692 + insert manipulation */
149693 +
149694 +#if DPAA_VERSION >= 11
149695 +#define IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
149696 +#endif /* DPAA_VERSION >= 11 */
149697 +/* @} */
149698 +
149699 +#ifdef FM_CAPWAP_SUPPORT
149700 +#error "FM_CAPWAP_SUPPORT not implemented!"
149701 +#endif
149702 +
149703 +
149704 +/**************************************************************************//**
149705 + @Group lnx_ioctl_FM_PCD_init_grp FM PCD Initialization Unit
149706 +
149707 + @Description Frame Manager PCD Initialization Unit API
149708 +
149709 + @{
149710 +*//***************************************************************************/
149711 +
149712 +/**************************************************************************//**
149713 + @Description PCD counters
149714 + (must match enum e_FmPcdCounters defined in fm_pcd_ext.h)
149715 +*//***************************************************************************/
149716 +typedef enum ioc_fm_pcd_counters {
149717 + e_IOC_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
149718 + e_IOC_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
149719 + e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
149720 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
149721 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
149722 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
149723 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
149724 + e_IOC_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
149725 + e_IOC_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
149726 + e_IOC_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
149727 + e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
149728 + e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
149729 + e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
149730 + e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
149731 + 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. */
149732 + 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. */
149733 + 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. */
149734 + 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. */
149735 + e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
149736 + 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. */
149737 + 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). */
149738 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
149739 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
149740 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
149741 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
149742 + e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
149743 +} ioc_fm_pcd_counters;
149744 +
149745 +/**************************************************************************//**
149746 + @Description PCD interrupts
149747 + (must match enum e_FmPcdExceptions defined in fm_pcd_ext.h)
149748 +*//***************************************************************************/
149749 +typedef enum ioc_fm_pcd_exceptions {
149750 + e_IOC_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
149751 + e_IOC_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
149752 + e_IOC_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
149753 + e_IOC_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
149754 + e_IOC_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
149755 + e_IOC_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
149756 + e_IOC_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
149757 + e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
149758 +} ioc_fm_pcd_exceptions;
149759 +
149760 +/** @} */ /* end of lnx_ioctl_FM_PCD_init_grp group */
149761 +
149762 +
149763 +/**************************************************************************//**
149764 + @Group lnx_ioctl_FM_PCD_Runtime_grp FM PCD Runtime Unit
149765 +
149766 + @Description Frame Manager PCD Runtime Unit
149767 +
149768 + The runtime control allows creation of PCD infrastructure modules
149769 + such as Network Environment Characteristics, Classification Plan
149770 + Groups and Coarse Classification Trees.
149771 + It also allows on-the-fly initialization, modification and removal
149772 + of PCD modules such as KeyGen schemes, coarse classification nodes
149773 + and Policer profiles.
149774 +
149775 + In order to explain the programming model of the PCD driver interface
149776 + a few terms should be explained, and will be used below.
149777 + - Distinction Header - One of the 16 protocols supported by the FM parser,
149778 + or one of the SHIM headers (1 or 2). May be a header with a special
149779 + option (see below).
149780 + - Interchangeable Headers Group - This is a group of Headers recognized
149781 + by either one of them. For example, if in a specific context the user
149782 + chooses to treat IPv4 and IPV6 in the same way, they may create an
149783 + interchangeable Headers Unit consisting of these 2 headers.
149784 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
149785 + Group.
149786 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
149787 + IPv6, includes multicast, broadcast and other protocol specific options.
149788 + In terms of hardware it relates to the options available in the classification
149789 + plan.
149790 + - Network Environment Characteristics - a set of Distinction Units that define
149791 + the total recognizable header selection for a certain environment. This is
149792 + NOT the list of all headers that will ever appear in a flow, but rather
149793 + everything that needs distinction in a flow, where distinction is made by KeyGen
149794 + schemes and coarse classification action descriptors.
149795 +
149796 + The PCD runtime modules initialization is done in stages. The first stage after
149797 + initializing the PCD module itself is to establish a Network Flows Environment
149798 + Definition. The application may choose to establish one or more such environments.
149799 + Later, when needed, the application will have to state, for some of its modules,
149800 + to which single environment it belongs.
149801 +
149802 + @{
149803 +*//***************************************************************************/
149804 +
149805 +
149806 +/**************************************************************************//**
149807 + @Description structure for FM counters
149808 +*//***************************************************************************/
149809 +typedef struct ioc_fm_pcd_counters_params_t {
149810 + ioc_fm_pcd_counters cnt; /**< The requested counter */
149811 + uint32_t val; /**< The requested value to get/set from/into the counter */
149812 +} ioc_fm_pcd_counters_params_t;
149813 +
149814 +/**************************************************************************//**
149815 + @Description structure for FM exception definitios
149816 +*//***************************************************************************/
149817 +typedef struct ioc_fm_pcd_exception_params_t {
149818 + ioc_fm_pcd_exceptions exception; /**< The requested exception */
149819 + bool enable; /**< TRUE to enable interrupt, FALSE to mask it. */
149820 +} ioc_fm_pcd_exception_params_t;
149821 +
149822 +/**************************************************************************//**
149823 + @Description A structure for SW parser labels
149824 + (must be identical to struct t_FmPcdPrsLabelParams defined in fm_pcd_ext.h)
149825 + *//***************************************************************************/
149826 +typedef struct ioc_fm_pcd_prs_label_params_t {
149827 + uint32_t instruction_offset; /**< SW parser label instruction offset (2 bytes
149828 + resolution), relative to Parser RAM. */
149829 + ioc_net_header_type hdr; /**< The existence of this header will invoke
149830 + the SW parser code. */
149831 + uint8_t index_per_hdr; /**< Normally 0, if more than one SW parser
149832 + attachments for the same header, use this
149833 + index to distinguish between them. */
149834 +} ioc_fm_pcd_prs_label_params_t;
149835 +
149836 +/**************************************************************************//**
149837 + @Description A structure for SW parser
149838 + (Must match struct t_FmPcdPrsSwParams defined in fm_pcd_ext.h)
149839 + *//***************************************************************************/
149840 +typedef struct ioc_fm_pcd_prs_sw_params_t {
149841 + bool override; /**< FALSE to invoke a check that nothing else
149842 + was loaded to this address, including
149843 + internal patches.
149844 + TRUE to override any existing code.*/
149845 + uint32_t size; /**< SW parser code size */
149846 + uint16_t base; /**< SW parser base (in instruction counts!
149847 + must be larger than 0x20)*/
149848 + uint8_t *p_code; /**< SW parser code */
149849 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
149850 + /**< SW parser data (parameters) */
149851 + uint8_t num_of_labels; /**< Number of labels for SW parser. */
149852 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
149853 + /**< SW parser labels table,
149854 + containing num_of_labels entries */
149855 +} ioc_fm_pcd_prs_sw_params_t;
149856 +
149857 +/**************************************************************************//**
149858 + @Description A structure to set the a KeyGen default value
149859 + *//***************************************************************************/
149860 +typedef struct ioc_fm_pcd_kg_dflt_value_params_t {
149861 + uint8_t valueId; /**< 0,1 - one of 2 global default values */
149862 + uint32_t value; /**< The requested default value */
149863 +} ioc_fm_pcd_kg_dflt_value_params_t;
149864 +
149865 +
149866 +/**************************************************************************//**
149867 + @Function FM_PCD_Enable
149868 +
149869 + @Description This routine should be called after PCD is initialized for enabling all
149870 + PCD engines according to their existing configuration.
149871 +
149872 + @Return 0 on success; Error code otherwise.
149873 +
149874 + @Cautions Allowed only when PCD is disabled.
149875 +*//***************************************************************************/
149876 +#define FM_PCD_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(1))
149877 +
149878 +/**************************************************************************//**
149879 + @Function FM_PCD_Disable
149880 +
149881 + @Description This routine may be called when PCD is enabled in order to
149882 + disable all PCD engines. It may be called
149883 + only when none of the ports in the system are using the PCD.
149884 +
149885 + @Return 0 on success; Error code otherwise.
149886 +
149887 + @Cautions Allowed only when PCD is enabled.
149888 +*//***************************************************************************/
149889 +#define FM_PCD_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(2))
149890 +
149891 + /**************************************************************************//**
149892 + @Function FM_PCD_PrsLoadSw
149893 +
149894 + @Description This routine may be called only when all ports in the
149895 + system are actively using the classification plan scheme.
149896 + In such cases it is recommended in order to save resources.
149897 + The driver automatically saves 8 classification plans for
149898 + ports that do NOT use the classification plan mechanism, to
149899 + avoid this (in order to save those entries) this routine may
149900 + be called.
149901 +
149902 + @Param[in] ioc_fm_pcd_prs_sw_params_t A pointer to the image of the software parser code.
149903 +
149904 + @Return 0 on success; Error code otherwise.
149905 +
149906 + @Cautions Allowed only when PCD is disabled.
149907 +*//***************************************************************************/
149908 +#if defined(CONFIG_COMPAT)
149909 +#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)
149910 +#endif
149911 +#define FM_PCD_IOC_PRS_LOAD_SW _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_fm_pcd_prs_sw_params_t)
149912 +
149913 +/**************************************************************************//**
149914 + @Function FM_PCD_KgSetDfltValue
149915 +
149916 + @Description Calling this routine sets a global default value to be used
149917 + by the KeyGen when parser does not recognize a required
149918 + field/header.
149919 + By default default values are 0.
149920 +
149921 + @Param[in] ioc_fm_pcd_kg_dflt_value_params_t A pointer to a structure with the relevant parameters
149922 +
149923 + @Return 0 on success; Error code otherwise.
149924 +
149925 + @Cautions Allowed only when PCD is disabled.
149926 +*//***************************************************************************/
149927 +#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)
149928 +
149929 +/**************************************************************************//**
149930 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
149931 +
149932 + @Description Calling this routine allows the keygen to access data past
149933 + the parser finishing point.
149934 +
149935 + @Param[in] uint8_t payload-offset; the number of bytes beyond the parser location.
149936 +
149937 + @Return 0 on success; Error code otherwise.
149938 +
149939 + @Cautions Allowed only when PCD is disabled.
149940 +*//***************************************************************************/
149941 +#define FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(7), uint8_t)
149942 +
149943 +/**************************************************************************//**
149944 + @Function FM_PCD_SetException
149945 +
149946 + @Description Calling this routine enables/disables PCD interrupts.
149947 +
149948 + @Param[in] ioc_fm_pcd_exception_params_t Arguments struct with exception to be enabled/disabled.
149949 +
149950 + @Return 0 on success; Error code otherwise.
149951 +*//***************************************************************************/
149952 +#define FM_PCD_IOC_SET_EXCEPTION _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(8), ioc_fm_pcd_exception_params_t)
149953 +
149954 +/**************************************************************************//**
149955 + @Function FM_PCD_GetCounter
149956 +
149957 + @Description Reads one of the FM PCD counters.
149958 +
149959 + @Param[in,out] ioc_fm_pcd_counters_params_t The requested counter parameters.
149960 +
149961 + @Return 0 on success; Error code otherwise.
149962 +
149963 + @Cautions Note that it is user's responsibilty to call this routine only
149964 + for enabled counters, and there will be no indication if a
149965 + disabled counter is accessed.
149966 +*//***************************************************************************/
149967 +#define FM_PCD_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(9), ioc_fm_pcd_counters_params_t)
149968 +
149969 +/**************************************************************************//**
149970 +
149971 + @Function FM_PCD_KgSchemeGetCounter
149972 +
149973 + @Description Reads scheme packet counter.
149974 +
149975 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
149976 +
149977 + @Return Counter's current value.
149978 +
149979 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
149980 +*//***************************************************************************/
149981 +#if defined(CONFIG_COMPAT)
149982 +#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)
149983 +#endif
149984 +#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)
149985 +
149986 +#if 0
149987 +TODO: unused IOCTL
149988 +/**************************************************************************//**
149989 + @Function FM_PCD_ModifyCounter
149990 +
149991 + @Description Writes a value to an enabled counter. Use "0" to reset the counter.
149992 +
149993 + @Param[in] ioc_fm_pcd_counters_params_t - The requested counter parameters.
149994 +
149995 + @Return 0 on success; Error code otherwise.
149996 +*//***************************************************************************/
149997 +#define FM_PCD_IOC_MODIFY_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(10), ioc_fm_pcd_counters_params_t)
149998 +#define FM_PCD_IOC_SET_COUNTER FM_PCD_IOC_MODIFY_COUNTER
149999 +#endif
150000 +
150001 +/**************************************************************************//**
150002 + @Function FM_PCD_ForceIntr
150003 +
150004 + @Description Causes an interrupt event on the requested source.
150005 +
150006 + @Param[in] ioc_fm_pcd_exceptions - An exception to be forced.
150007 +
150008 + @Return 0 on success; error code if the exception is not enabled,
150009 + or is not able to create interrupt.
150010 +*//***************************************************************************/
150011 +#define FM_PCD_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(11), ioc_fm_pcd_exceptions)
150012 +
150013 +/**************************************************************************//**
150014 + @Collection Definitions of coarse classification parameters as required by KeyGen
150015 + (when coarse classification is the next engine after this scheme).
150016 +*//***************************************************************************/
150017 +#define IOC_FM_PCD_MAX_NUM_OF_CC_TREES 8
150018 +#define IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS 16
150019 +#define IOC_FM_PCD_MAX_NUM_OF_CC_UNITS 4
150020 +#define IOC_FM_PCD_MAX_NUM_OF_KEYS 256
150021 +#define IOC_FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
150022 +#define IOC_FM_PCD_MAX_SIZE_OF_KEY 56
150023 +#define IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
150024 +#define IOC_FM_PCD_LAST_KEY_INDEX 0xffff
150025 +#define IOC_FM_PCD_MANIP_DSCP_VALUES 64
150026 +/* @} */
150027 +
150028 +/**************************************************************************//**
150029 + @Collection A set of definitions to allow protocol
150030 + special option description.
150031 +*//***************************************************************************/
150032 +typedef uint32_t ioc_protocol_opt_t; /**< A general type to define a protocol option. */
150033 +
150034 +typedef ioc_protocol_opt_t ioc_eth_protocol_opt_t; /**< Ethernet protocol options. */
150035 +#define IOC_ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
150036 +#define IOC_ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
150037 +
150038 +typedef ioc_protocol_opt_t ioc_vlan_protocol_opt_t; /**< Vlan protocol options. */
150039 +#define IOC_VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
150040 +
150041 +typedef ioc_protocol_opt_t ioc_mpls_protocol_opt_t; /**< MPLS protocol options. */
150042 +#define IOC_MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
150043 +
150044 +typedef ioc_protocol_opt_t ioc_ipv4_protocol_opt_t; /**< IPv4 protocol options. */
150045 +#define IOC_IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
150046 +#define IOC_IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
150047 +#define IOC_IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
150048 +#define IOC_IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
150049 +
150050 +#define IOC_IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
150051 + IPV4 Reassembly manipulation requires network
150052 + environment with IPV4 header and IPV4_FRAG_1 option */
150053 +
150054 +typedef ioc_protocol_opt_t ioc_ipv6_protocol_opt_t; /**< IPv6 protocol options. */
150055 +#define IOC_IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
150056 +#define IOC_IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
150057 +#define IOC_IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
150058 +
150059 +#define IOC_IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
150060 + IPV6 Reassembly manipulation requires network
150061 + environment with IPV6 header and IPV6_FRAG_1 option */
150062 +#if (DPAA_VERSION >= 11)
150063 +typedef ioc_protocol_opt_t ioc_capwap_protocol_opt_t; /**< CAPWAP protocol options. */
150064 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
150065 + CAPWAP Reassembly manipulation requires network
150066 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
150067 + in case where fragment found, the fragment-extension offset
150068 + may be found at 'shim2' (in parser-result). */
150069 +#endif /* (DPAA_VERSION >= 11) */
150070 +
150071 +/* @} */
150072 +
150073 +#define IOC_FM_PCD_MANIP_MAX_HDR_SIZE 256
150074 +#define IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
150075 +/**************************************************************************//**
150076 + @Collection A set of definitions to support Header Manipulation selection.
150077 +*//***************************************************************************/
150078 +typedef uint32_t ioc_hdr_manip_flags_t; /**< A general type to define a HMan update command flags. */
150079 +
150080 +typedef ioc_hdr_manip_flags_t ioc_ipv4_hdr_manip_update_flags_t; /**< IPv4 protocol HMan update command flags. */
150081 +
150082 +#define IOC_HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
150083 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150084 +#define IOC_HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
150085 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150086 +#define IOC_HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
150087 +#define IOC_HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
150088 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150089 +#define IOC_HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
150090 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150091 +
150092 +typedef ioc_hdr_manip_flags_t ioc_ipv6_hdr_manip_update_flags_t; /**< IPv6 protocol HMan update command flags. */
150093 +
150094 +#define IOC_HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
150095 + ('traffic_class' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150096 +#define IOC_HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
150097 +#define IOC_HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
150098 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150099 +#define IOC_HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
150100 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150101 +
150102 +typedef ioc_hdr_manip_flags_t ioc_tcp_udp_hdr_manip_update_flags_t;/**< TCP/UDP protocol HMan update command flags. */
150103 +
150104 +#define IOC_HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
150105 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
150106 +#define IOC_HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
150107 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
150108 +#define IOC_HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
150109 +
150110 +/* @} */
150111 +
150112 +/**************************************************************************//**
150113 + @Description A type used for returning the order of the key extraction.
150114 + each value in this array represents the index of the extraction
150115 + command as defined by the user in the initialization extraction array.
150116 + The valid size of this array is the user define number of extractions
150117 + required (also marked by the second '0' in this array).
150118 +*//***************************************************************************/
150119 +typedef uint8_t ioc_fm_pcd_kg_key_order_t [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
150120 +
150121 +/**************************************************************************//**
150122 + @Description All PCD engines
150123 + (must match enum e_FmPcdEngine defined in fm_pcd_ext.h)
150124 +*//***************************************************************************/
150125 +typedef enum ioc_fm_pcd_engine {
150126 + e_IOC_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
150127 + e_IOC_FM_PCD_DONE, /**< No PCD Engine indicated */
150128 + e_IOC_FM_PCD_KG, /**< KeyGen */
150129 + e_IOC_FM_PCD_CC, /**< Coarse Classifier */
150130 + e_IOC_FM_PCD_PLCR, /**< Policer */
150131 + e_IOC_FM_PCD_PRS, /**< Parser */
150132 +#if DPAA_VERSION >= 11
150133 + e_IOC_FM_PCD_FR, /**< Frame Replicator */
150134 +#endif /* DPAA_VERSION >= 11 */
150135 + e_IOC_FM_PCD_HASH /**< Hash Table */
150136 +} ioc_fm_pcd_engine;
150137 +
150138 +/**************************************************************************//**
150139 + @Description An enum for selecting extraction by header types
150140 + (Must match enum e_FmPcdExtractByHdrType defined in fm_pcd_ext.h)
150141 +*//***************************************************************************/
150142 +typedef enum ioc_fm_pcd_extract_by_hdr_type {
150143 + e_IOC_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
150144 + e_IOC_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
150145 + e_IOC_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
150146 +} ioc_fm_pcd_extract_by_hdr_type;
150147 +
150148 +/**************************************************************************//**
150149 + @Description An enum for selecting extraction source (when it is not the header)
150150 + (Must match enum e_FmPcdExtractFrom defined in fm_pcd_ext.h)
150151 +*//***************************************************************************/
150152 +typedef enum ioc_fm_pcd_extract_from {
150153 + e_IOC_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
150154 + e_IOC_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
150155 + e_IOC_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */
150156 + e_IOC_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
150157 + e_IOC_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
150158 + e_IOC_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */
150159 + e_IOC_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
150160 + e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
150161 +} ioc_fm_pcd_extract_from;
150162 +
150163 +/**************************************************************************//**
150164 + @Description An enum for selecting extraction type
150165 +*//***************************************************************************/
150166 +typedef enum ioc_fm_pcd_extract_type {
150167 + e_IOC_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
150168 + e_IOC_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
150169 + e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
150170 +} ioc_fm_pcd_extract_type;
150171 +
150172 +/**************************************************************************//**
150173 + @Description An enum for selecting a default
150174 +*//***************************************************************************/
150175 +typedef enum ioc_fm_pcd_kg_extract_dflt_select {
150176 + e_IOC_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
150177 + e_IOC_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
150178 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
150179 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
150180 + e_IOC_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
150181 +} ioc_fm_pcd_kg_extract_dflt_select;
150182 +
150183 +/**************************************************************************//**
150184 + @Description Enumeration type defining all default groups - each group shares
150185 + a default value, one of four user-initialized values.
150186 +*//***************************************************************************/
150187 +typedef enum ioc_fm_pcd_kg_known_fields_dflt_types {
150188 + e_IOC_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
150189 + e_IOC_FM_PCD_KG_TCI, /**< TCI field */
150190 + e_IOC_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
150191 + e_IOC_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
150192 + e_IOC_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
150193 + e_IOC_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
150194 + e_IOC_FM_PCD_KG_IP_ADDR, /**< IP addr */
150195 + e_IOC_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
150196 + e_IOC_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
150197 + e_IOC_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
150198 + e_IOC_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
150199 + e_IOC_FM_PCD_KG_L4_PORT, /**< L4 Port */
150200 + e_IOC_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
150201 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
150202 + any data extraction that is not the full
150203 + field described above */
150204 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
150205 + any data extraction without validation */
150206 + e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
150207 + extraction from parser result or
150208 + direct use of default value */
150209 +} ioc_fm_pcd_kg_known_fields_dflt_types;
150210 +
150211 +/**************************************************************************//**
150212 + @Description Enumeration type for defining header index for scenarios with
150213 + multiple (tunneled) headers
150214 +*//***************************************************************************/
150215 +typedef enum ioc_fm_pcd_hdr_index {
150216 + e_IOC_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
150217 + to specify regular IP (not tunneled). */
150218 + e_IOC_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
150219 + e_IOC_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
150220 + e_IOC_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
150221 + e_IOC_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
150222 +} ioc_fm_pcd_hdr_index;
150223 +
150224 +/**************************************************************************//**
150225 + @Description Enumeration type for selecting the policer profile functional type
150226 +*//***************************************************************************/
150227 +typedef enum ioc_fm_pcd_profile_type_selection {
150228 + e_IOC_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
150229 + e_IOC_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
150230 +} ioc_fm_pcd_profile_type_selection;
150231 +
150232 +/**************************************************************************//**
150233 + @Description Enumeration type for selecting the policer profile algorithm
150234 +*//***************************************************************************/
150235 +typedef enum ioc_fm_pcd_plcr_algorithm_selection {
150236 + e_IOC_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
150237 + e_IOC_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
150238 + e_IOC_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
150239 +} ioc_fm_pcd_plcr_algorithm_selection;
150240 +
150241 +/**************************************************************************//**
150242 + @Description Enumeration type for selecting a policer profile color mode
150243 +*//***************************************************************************/
150244 +typedef enum ioc_fm_pcd_plcr_color_mode {
150245 + e_IOC_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
150246 + e_IOC_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
150247 +} ioc_fm_pcd_plcr_color_mode;
150248 +
150249 +/**************************************************************************//**
150250 + @Description Enumeration type for selecting a policer profile color
150251 +*//***************************************************************************/
150252 +typedef enum ioc_fm_pcd_plcr_color {
150253 + e_IOC_FM_PCD_PLCR_GREEN, /**< Green */
150254 + e_IOC_FM_PCD_PLCR_YELLOW, /**< Yellow */
150255 + e_IOC_FM_PCD_PLCR_RED, /**< Red */
150256 + e_IOC_FM_PCD_PLCR_OVERRIDE /**< Color override */
150257 +} ioc_fm_pcd_plcr_color;
150258 +
150259 +/**************************************************************************//**
150260 + @Description Enumeration type for selecting the policer profile packet frame length selector
150261 +*//***************************************************************************/
150262 +typedef enum ioc_fm_pcd_plcr_frame_length_select {
150263 + e_IOC_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
150264 + e_IOC_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
150265 + e_IOC_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
150266 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
150267 +} ioc_fm_pcd_plcr_frame_length_select;
150268 +
150269 +/**************************************************************************//**
150270 + @Description Enumeration type for selecting roll-back frame
150271 +*//***************************************************************************/
150272 +typedef enum ioc_fm_pcd_plcr_roll_back_frame_select {
150273 + e_IOC_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */
150274 + e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */
150275 +} ioc_fm_pcd_plcr_roll_back_frame_select;
150276 +
150277 +/**************************************************************************//**
150278 + @Description Enumeration type for selecting the policer profile packet or byte mode
150279 +*//***************************************************************************/
150280 +typedef enum ioc_fm_pcd_plcr_rate_mode {
150281 + e_IOC_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
150282 + e_IOC_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
150283 +} ioc_fm_pcd_plcr_rate_mode;
150284 +
150285 +/**************************************************************************//**
150286 + @Description Enumeration type for defining action of frame
150287 +*//***************************************************************************/
150288 +typedef enum ioc_fm_pcd_done_action {
150289 + e_IOC_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
150290 + e_IOC_FM_PCD_DROP_FRAME /**< Drop frame */
150291 +} ioc_fm_pcd_done_action;
150292 +
150293 +/**************************************************************************//**
150294 + @Description Enumeration type for selecting the policer counter
150295 +*//***************************************************************************/
150296 +typedef enum ioc_fm_pcd_plcr_profile_counters {
150297 + e_IOC_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
150298 + e_IOC_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
150299 + e_IOC_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
150300 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
150301 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
150302 +} ioc_fm_pcd_plcr_profile_counters;
150303 +
150304 +/**************************************************************************//**
150305 + @Description Enumeration type for selecting the PCD action after extraction
150306 +*//***************************************************************************/
150307 +typedef enum ioc_fm_pcd_action {
150308 + e_IOC_FM_PCD_ACTION_NONE, /**< NONE */
150309 + e_IOC_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/
150310 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/
150311 +} ioc_fm_pcd_action;
150312 +
150313 +/**************************************************************************//**
150314 + @Description Enumeration type for selecting type of insert manipulation
150315 +*//***************************************************************************/
150316 +typedef enum ioc_fm_pcd_manip_hdr_insrt_type {
150317 + e_IOC_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
150318 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
150319 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
150320 + e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
150321 +#endif /* FM_CAPWAP_SUPPORT */
150322 +} ioc_fm_pcd_manip_hdr_insrt_type;
150323 +
150324 +/**************************************************************************//**
150325 + @Description Enumeration type for selecting type of remove manipulation
150326 +*//***************************************************************************/
150327 +typedef enum ioc_fm_pcd_manip_hdr_rmv_type {
150328 + e_IOC_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
150329 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
150330 +} ioc_fm_pcd_manip_hdr_rmv_type;
150331 +
150332 +/**************************************************************************//**
150333 + @Description An enum for selecting specific L2 fields removal
150334 +*//***************************************************************************/
150335 +typedef enum ioc_fm_pcd_manip_hdr_rmv_specific_l2 {
150336 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
150337 + e_IOC_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
150338 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
150339 + the header which follows the MPLS header */
150340 + e_IOC_FM_PCD_MANIP_HDR_RMV_MPLS /**< Remove MPLS header (Unlimited MPLS labels) */
150341 +} ioc_fm_pcd_manip_hdr_rmv_specific_l2;
150342 +
150343 +/**************************************************************************//**
150344 + @Description Enumeration type for selecting specific fields updates
150345 +*//***************************************************************************/
150346 +typedef enum ioc_fm_pcd_manip_hdr_field_update_type {
150347 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
150348 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
150349 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
150350 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
150351 +} ioc_fm_pcd_manip_hdr_field_update_type;
150352 +
150353 +/**************************************************************************//**
150354 + @Description Enumeration type for selecting VLAN updates
150355 +*//***************************************************************************/
150356 +typedef enum ioc_fm_pcd_manip_hdr_field_update_vlan {
150357 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
150358 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
150359 +} ioc_fm_pcd_manip_hdr_field_update_vlan;
150360 +
150361 +/**************************************************************************//**
150362 + @Description Enumeration type for selecting specific L2 fields removal
150363 +*//***************************************************************************/
150364 +typedef enum ioc_fm_pcd_manip_hdr_insrt_specific_l2 {
150365 + e_IOC_FM_PCD_MANIP_HDR_INSRT_MPLS /**< Insert MPLS header (Unlimited MPLS labels) */
150366 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2;
150367 +
150368 +#if (DPAA_VERSION >= 11)
150369 +/**************************************************************************//**
150370 + @Description Enumeration type for selecting QoS mapping mode
150371 +
150372 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
150373 + User should instruct the port to read the parser-result
150374 +*//***************************************************************************/
150375 +typedef enum ioc_fm_pcd_manip_hdr_qos_mapping_mode {
150376 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
150377 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the parser-result. */
150378 +} ioc_fm_pcd_manip_hdr_qos_mapping_mode;
150379 +
150380 +/**************************************************************************//**
150381 + @Description Enumeration type for selecting QoS source
150382 +
150383 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
150384 + User should left room for the parser-result on input/output buffer
150385 + and instruct the port to read/write the parser-result to the buffer (RPD should be set)
150386 +*//***************************************************************************/
150387 +typedef enum ioc_fm_pcd_manip_hdr_qos_src {
150388 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
150389 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the parser-result. */
150390 +} ioc_fm_pcd_manip_hdr_qos_src;
150391 +#endif /* (DPAA_VERSION >= 11) */
150392 +
150393 +/**************************************************************************//**
150394 + @Description Enumeration type for selecting type of header insertion
150395 +*//***************************************************************************/
150396 +typedef enum ioc_fm_pcd_manip_hdr_insrt_by_hdr_type {
150397 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
150398 +#if (DPAA_VERSION >= 11)
150399 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
150400 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
150401 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
150402 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
150403 +#endif /* (DPAA_VERSION >= 11) */
150404 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_type;
150405 +
150406 +/**************************************************************************//**
150407 + @Description Enumeration type for selecting specific custom command
150408 +*//***************************************************************************/
150409 +typedef enum ioc_fm_pcd_manip_hdr_custom_type {
150410 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
150411 +} ioc_fm_pcd_manip_hdr_custom_type;
150412 +
150413 +/**************************************************************************//**
150414 + @Description Enumeration type for selecting specific custom command
150415 +*//***************************************************************************/
150416 +typedef enum ioc_fm_pcd_manip_hdr_custom_ip_replace {
150417 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
150418 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
150419 +} ioc_fm_pcd_manip_hdr_custom_ip_replace;
150420 +
150421 +/**************************************************************************//**
150422 + @Description Enumeration type for selecting type of header removal
150423 +*//***************************************************************************/
150424 +typedef enum ioc_fm_pcd_manip_hdr_rmv_by_hdr_type {
150425 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
150426 +#if (DPAA_VERSION >= 11)
150427 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
150428 +#endif /* (DPAA_VERSION >= 11) */
150429 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
150430 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
150431 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
150432 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_type;
150433 +
150434 +/**************************************************************************//**
150435 + @Description Enumeration type for selecting type of timeout mode
150436 +*//***************************************************************************/
150437 +typedef enum ioc_fm_pcd_manip_reassem_time_out_mode {
150438 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
150439 + from the first fragment to the last */
150440 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
150441 +} ioc_fm_pcd_manip_reassem_time_out_mode;
150442 +
150443 +/**************************************************************************//**
150444 + @Description Enumeration type for selecting type of WaysNumber mode
150445 +*//***************************************************************************/
150446 +typedef enum ioc_fm_pcd_manip_reassem_ways_number {
150447 + e_IOC_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
150448 + e_IOC_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
150449 + e_IOC_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
150450 + e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
150451 + e_IOC_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
150452 + e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
150453 + e_IOC_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
150454 + e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
150455 +} ioc_fm_pcd_manip_reassem_ways_number;
150456 +
150457 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
150458 +/**************************************************************************//**
150459 + @Description Enumeration type for selecting type of statistics mode
150460 +*//***************************************************************************/
150461 +typedef enum ioc_fm_pcd_stats {
150462 + e_IOC_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
150463 +} ioc_fm_pcd_stats;
150464 +#endif
150465 +
150466 +/**************************************************************************//**
150467 + @Description Enumeration type for selecting manipulation type
150468 +*//***************************************************************************/
150469 +typedef enum ioc_fm_pcd_manip_type {
150470 + e_IOC_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
150471 + e_IOC_FM_PCD_MANIP_REASSEM, /**< Reassembly */
150472 + e_IOC_FM_PCD_MANIP_FRAG, /**< Fragmentation */
150473 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
150474 +} ioc_fm_pcd_manip_type;
150475 +
150476 +/**************************************************************************//**
150477 + @Description Enumeration type for selecting type of statistics mode
150478 +*//***************************************************************************/
150479 +typedef enum ioc_fm_pcd_cc_stats_mode {
150480 + e_IOC_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
150481 + e_IOC_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
150482 + e_IOC_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
150483 +#if (DPAA_VERSION >= 11)
150484 + e_IOC_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics */
150485 +#endif /* (DPAA_VERSION >= 11) */
150486 +} ioc_fm_pcd_cc_stats_mode;
150487 +
150488 +/**************************************************************************//**
150489 + @Description Enumeration type for determining the action in case an IP packet
150490 + is larger than MTU but its DF (Don't Fragment) bit is set.
150491 +*//***************************************************************************/
150492 +typedef enum ioc_fm_pcd_manip_dont_frag_action {
150493 + e_IOC_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
150494 + e_IOC_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_IOC_FM_PCD_MANIP_DISCARD_PACKET,
150495 + /**< Obsolete, cannot enqueue to error queue;
150496 + In practice, selects to discard packets;
150497 + Will be removed in the future */
150498 + e_IOC_FM_PCD_MANIP_FRAGMENT_PACKECT, /**< Fragment packet and continue normal processing */
150499 + e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
150500 +} ioc_fm_pcd_manip_dont_frag_action;
150501 +
150502 +/**************************************************************************//**
150503 + @Description Enumeration type for selecting type of special offload manipulation
150504 +*//***************************************************************************/
150505 +typedef enum ioc_fm_pcd_manip_special_offload_type {
150506 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
150507 +#if (DPAA_VERSION >= 11)
150508 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
150509 +#endif /* (DPAA_VERSION >= 11) */
150510 +} ioc_fm_pcd_manip_special_offload_type;
150511 +
150512 +/**************************************************************************//**
150513 + @Description A union of protocol dependent special options
150514 + (Must match union u_FmPcdHdrProtocolOpt defined in fm_pcd_ext.h)
150515 +*//***************************************************************************/
150516 +typedef union ioc_fm_pcd_hdr_protocol_opt_u {
150517 + ioc_eth_protocol_opt_t eth_opt; /**< Ethernet options */
150518 + ioc_vlan_protocol_opt_t vlan_opt; /**< Vlan options */
150519 + ioc_mpls_protocol_opt_t mpls_opt; /**< MPLS options */
150520 + ioc_ipv4_protocol_opt_t ipv4_opt; /**< IPv4 options */
150521 + ioc_ipv6_protocol_opt_t ipv6_opt; /**< IPv6 options */
150522 +#if (DPAA_VERSION >= 11)
150523 + ioc_capwap_protocol_opt_t capwap_opt; /**< CAPWAP options */
150524 +#endif /* (DPAA_VERSION >= 11) */
150525 +} ioc_fm_pcd_hdr_protocol_opt_u;
150526 +
150527 +/**************************************************************************//**
150528 + @Description A union holding all known protocol fields
150529 +*//***************************************************************************/
150530 +typedef union ioc_fm_pcd_fields_u {
150531 + ioc_header_field_eth_t eth; /**< Ethernet */
150532 + ioc_header_field_vlan_t vlan; /**< VLAN */
150533 + ioc_header_field_llc_snap_t llc_snap; /**< LLC SNAP */
150534 + ioc_header_field_pppoe_t pppoe; /**< PPPoE */
150535 + ioc_header_field_mpls_t mpls; /**< MPLS */
150536 + ioc_header_field_ip_t ip; /**< IP */
150537 + ioc_header_field_ipv4_t ipv4; /**< IPv4 */
150538 + ioc_header_field_ipv6_t ipv6; /**< IPv6 */
150539 + ioc_header_field_udp_t udp; /**< UDP */
150540 + ioc_header_field_udp_lite_t udp_lite; /**< UDP_Lite */
150541 + ioc_header_field_tcp_t tcp; /**< TCP */
150542 + ioc_header_field_sctp_t sctp; /**< SCTP */
150543 + ioc_header_field_dccp_t dccp; /**< DCCP */
150544 + ioc_header_field_gre_t gre; /**< GRE */
150545 + ioc_header_field_minencap_t minencap; /**< Minimal Encapsulation */
150546 + ioc_header_field_ipsec_ah_t ipsec_ah; /**< IPSec AH */
150547 + ioc_header_field_ipsec_esp_t ipsec_esp; /**< IPSec ESP */
150548 + ioc_header_field_udp_encap_esp_t udp_encap_esp; /**< UDP Encapsulation ESP */
150549 +} ioc_fm_pcd_fields_u;
150550 +
150551 +/**************************************************************************//**
150552 + @Description Parameters for defining header extraction for key generation
150553 +*//***************************************************************************/
150554 +typedef struct ioc_fm_pcd_from_hdr_t {
150555 + uint8_t size; /**< Size in byte */
150556 + uint8_t offset; /**< Byte offset */
150557 +} ioc_fm_pcd_from_hdr_t;
150558 +
150559 +/**************************************************************************//**
150560 + @Description Parameters for defining field extraction for key generation
150561 +*//***************************************************************************/
150562 +typedef struct ioc_fm_pcd_from_field_t {
150563 + ioc_fm_pcd_fields_u field; /**< Field selection */
150564 + uint8_t size; /**< Size in byte */
150565 + uint8_t offset; /**< Byte offset */
150566 +} ioc_fm_pcd_from_field_t;
150567 +
150568 +/**************************************************************************//**
150569 + @Description Parameters for defining a single network environment unit
150570 + A distinction unit should be defined if it will later be used
150571 + by one or more PCD engines to distinguish between flows.
150572 + (Must match struct t_FmPcdDistinctionUnit defined in fm_pcd_ext.h)
150573 +*//***************************************************************************/
150574 +typedef struct ioc_fm_pcd_distinction_unit_t {
150575 + struct {
150576 + ioc_net_header_type hdr; /**< One of the headers supported by the FM */
150577 + ioc_fm_pcd_hdr_protocol_opt_u opt; /**< Select only one option! */
150578 + } hdrs[IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
150579 +} ioc_fm_pcd_distinction_unit_t;
150580 +
150581 +/**************************************************************************//**
150582 + @Description Parameters for defining all different distinction units supported
150583 + by a specific PCD Network Environment Characteristics module.
150584 +
150585 + Each unit represent a protocol or a group of protocols that may
150586 + be used later by the different PCD engines to distinguish between flows.
150587 + (Must match struct t_FmPcdNetEnvParams defined in fm_pcd_ext.h)
150588 +*//***************************************************************************/
150589 +typedef struct ioc_fm_pcd_net_env_params_t {
150590 + uint8_t num_of_distinction_units;/**< Number of different units to be identified */
150591 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
150592 + /**< An array of num_of_distinction_units of the
150593 + different units to be identified */
150594 + void *id; /**< Output parameter; Returns the net-env Id to be used */
150595 +} ioc_fm_pcd_net_env_params_t;
150596 +
150597 +/**************************************************************************//**
150598 + @Description Parameters for defining a single extraction action when
150599 + creating a key
150600 +*//***************************************************************************/
150601 +typedef struct ioc_fm_pcd_extract_entry_t {
150602 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
150603 + union {
150604 + struct {
150605 + ioc_net_header_type hdr; /**< Header selection */
150606 + bool ignore_protocol_validation;
150607 + /**< Ignore protocol validation */
150608 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
150609 + IP. Otherwise should be cleared.*/
150610 + ioc_fm_pcd_extract_by_hdr_type type; /**< Header extraction type select */
150611 + union {
150612 + ioc_fm_pcd_from_hdr_t from_hdr; /**< Extract bytes from header parameters */
150613 + ioc_fm_pcd_from_field_t from_field; /**< Extract bytes from field parameters */
150614 + ioc_fm_pcd_fields_u full_field; /**< Extract full field parameters */
150615 + } extract_by_hdr_type;
150616 + } extract_by_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
150617 + struct {
150618 + ioc_fm_pcd_extract_from src; /**< Non-header extraction source */
150619 + ioc_fm_pcd_action action; /**< Relevant for CC Only */
150620 + uint16_t ic_indx_mask; /**< Relevant only for CC when
150621 + action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP;
150622 + Note that the number of bits that are set within
150623 + this mask must be log2 of the CC-node 'num_of_keys'.
150624 + Note that the mask cannot be set on the lower bits. */
150625 + uint8_t offset; /**< Byte offset */
150626 + uint8_t size; /**< Size in bytes */
150627 + } extract_non_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
150628 + } extract_params;
150629 +} ioc_fm_pcd_extract_entry_t;
150630 +
150631 +/**************************************************************************//**
150632 + @Description A structure for defining masks for each extracted
150633 + field in the key.
150634 +*//***************************************************************************/
150635 +typedef struct ioc_fm_pcd_kg_extract_mask_t {
150636 + uint8_t extract_array_index; /**< Index in the extraction array, as initialized by user */
150637 + uint8_t offset; /**< Byte offset */
150638 + uint8_t mask; /**< A byte mask (selected bits will be ignored) */
150639 +} ioc_fm_pcd_kg_extract_mask_t;
150640 +
150641 +/**************************************************************************//**
150642 + @Description A structure for defining default selection per groups
150643 + of fields
150644 +*//***************************************************************************/
150645 +typedef struct ioc_fm_pcd_kg_extract_dflt_t {
150646 + ioc_fm_pcd_kg_known_fields_dflt_types type; /**< Default type select*/
150647 + ioc_fm_pcd_kg_extract_dflt_select dflt_select; /**< Default register select */
150648 +} ioc_fm_pcd_kg_extract_dflt_t;
150649 +
150650 +
150651 +/**************************************************************************//**
150652 + @Description A structure for defining all parameters needed for
150653 + generation a key and using a hash function
150654 +*//***************************************************************************/
150655 +typedef struct ioc_fm_pcd_kg_key_extract_and_hash_params_t {
150656 + uint32_t private_dflt0; /**< Scheme default register 0 */
150657 + uint32_t private_dflt1; /**< Scheme default register 1 */
150658 + uint8_t num_of_used_extracts; /**< defines the valid size of the following array */
150659 + ioc_fm_pcd_extract_entry_t extract_array [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
150660 + /**< An array of extraction definitions. */
150661 + uint8_t num_of_used_dflts; /**< defines the valid size of the following array */
150662 + ioc_fm_pcd_kg_extract_dflt_t dflts[IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
150663 + /**< For each extraction used in this scheme, specify the required
150664 + default register to be used when header is not found.
150665 + types not specified in this array will get undefined value. */
150666 + uint8_t num_of_used_masks; /**< Defines the valid size of the following array */
150667 + ioc_fm_pcd_kg_extract_mask_t masks[IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
150668 + uint8_t hash_shift; /**< Hash result right shift.
150669 + Selects the 24 bits out of the 64 hash result.
150670 + 0 means using the 24 LSB's, otherwise use the
150671 + 24 LSB's after shifting right.*/
150672 + uint32_t hash_distribution_num_of_fqids; /**< must be > 1 and a power of 2. Represents the range
150673 + of queues for the key and hash functionality */
150674 + uint8_t hash_distribution_fqids_shift; /**< selects the FQID bits that will be effected by the hash */
150675 + bool symmetric_hash; /**< TRUE to generate the same hash for frames with swapped source and
150676 + destination fields on all layers; If TRUE, driver will check that for
150677 + all layers, if SRC extraction is selected, DST extraction must also be
150678 + selected, and vice versa. */
150679 +} ioc_fm_pcd_kg_key_extract_and_hash_params_t;
150680 +
150681 +/**************************************************************************//**
150682 + @Description A structure of parameters for defining a single
150683 + Qid mask (extracted OR).
150684 +*//***************************************************************************/
150685 +typedef struct ioc_fm_pcd_kg_extracted_or_params_t {
150686 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
150687 + union {
150688 + struct { /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
150689 + ioc_net_header_type hdr;
150690 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
150691 + IP. Otherwise should be cleared.*/
150692 + bool ignore_protocol_validation;
150693 +
150694 + } extract_by_hdr;
150695 + ioc_fm_pcd_extract_from src; /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
150696 + } extract_params;
150697 + uint8_t extraction_offset; /**< Offset for extraction */
150698 + ioc_fm_pcd_kg_extract_dflt_select dflt_value; /**< Select register from which extraction is taken if
150699 + field not found */
150700 + uint8_t mask; /**< Mask LSB byte of extraction (specified bits are ignored) */
150701 + uint8_t bit_offset_in_fqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
150702 + the extracted byte; Assume byte is placed as the 8 MSB's in
150703 + a 32 bit word where the lower bits
150704 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
150705 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
150706 + extracted byte will effect the 8 LSB's of the FQID,
150707 + if bitOffsetInFqid=31 than the byte's MSB will effect
150708 + the FQID's LSB; 0 means - no effect on FQID;
150709 + Note that one, and only one of
150710 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
150711 + extracted byte must effect either FQID or Policer profile).*/
150712 + uint8_t bit_offset_in_plcr_profile;
150713 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
150714 + effect using the extracted byte; Assume byte is placed
150715 + as the 8 MSB's in a 16 bit word where the lower bits
150716 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
150717 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
150718 + than the extracted byte will effect the whole policer profile id,
150719 + if bitOffsetInFqid=15 than the byte's MSB will effect
150720 + the Policer Profile id's LSB;
150721 + 0 means - no effect on policer profile; Note that one, and only one of
150722 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
150723 + extracted byte must effect either FQID or Policer profile).*/
150724 +} ioc_fm_pcd_kg_extracted_or_params_t;
150725 +
150726 +/**************************************************************************//**
150727 + @Description A structure for configuring scheme counter
150728 +*//***************************************************************************/
150729 +typedef struct ioc_fm_pcd_kg_scheme_counter_t {
150730 + bool update; /**< FALSE to keep the current counter state
150731 + and continue from that point, TRUE to update/reset
150732 + the counter when the scheme is written. */
150733 + uint32_t value; /**< If update=TRUE, this value will be written into the
150734 + counter; clear this field to reset the counter. */
150735 +} ioc_fm_pcd_kg_scheme_counter_t;
150736 +
150737 +
150738 +/**************************************************************************//**
150739 + @Description A structure for retrieving FMKG_SE_SPC
150740 +*//***************************************************************************/
150741 +typedef struct ioc_fm_pcd_kg_scheme_spc_t {
150742 + uint32_t val; /**< return value */
150743 + void *id; /**< scheme handle */
150744 +} ioc_fm_pcd_kg_scheme_spc_t;
150745 +
150746 +/**************************************************************************//**
150747 + @Description A structure for defining policer profile parameters as required by keygen
150748 + (when policer is the next engine after this scheme).
150749 + (Must match struct t_FmPcdKgPlcrProfile defined in fm_pcd_ext.h)
150750 +*//***************************************************************************/
150751 +typedef struct ioc_fm_pcd_kg_plcr_profile_t {
150752 + bool shared_profile; /**< TRUE if this profile is shared between ports
150753 + (i.e. managed by master partition) May not be TRUE
150754 + if profile is after Coarse Classification*/
150755 + bool direct; /**< If TRUE, direct_relative_profile_id only selects the profile
150756 + id, if FALSE fqid_offset_relative_profile_id_base is used
150757 + together with fqid_offset_shift and num_of_profiles
150758 + parameters, to define a range of profiles from
150759 + which the KeyGen result will determine the
150760 + destination policer profile. */
150761 + union {
150762 + uint16_t direct_relative_profile_id; /**< Used if 'direct' is TRUE, to select policer profile.
150763 + This parameter should indicate the policer profile offset within the port's
150764 + policer profiles or SHARED window. */
150765 + struct {
150766 + uint8_t fqid_offset_shift; /**< Shift of KG results without the qid base */
150767 + uint8_t fqid_offset_relative_profile_id_base;
150768 + /**< OR of KG results without the qid base
150769 + This parameter should indicate the policer profile
150770 + offset within the port's policer profiles window
150771 + or SHARED window depends on shared_profile */
150772 + uint8_t num_of_profiles; /**< Range of profiles starting at base */
150773 + } indirect_profile; /**< Indirect profile parameters */
150774 + } profile_select; /**< Direct/indirect profile selection and parameters */
150775 +} ioc_fm_pcd_kg_plcr_profile_t;
150776 +
150777 +#if DPAA_VERSION >= 11
150778 +/**************************************************************************//**
150779 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
150780 +*//***************************************************************************/
150781 +typedef struct ioc_fm_pcd_kg_storage_profile_t {
150782 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
150783 + profile id;
150784 + If FALSE, fqidOffsetRelativeProfileIdBase is used
150785 + together with fqidOffsetShift and numOfProfiles
150786 + parameters to define a range of profiles from which
150787 + the KeyGen result will determine the destination
150788 + storage profile. */
150789 + union {
150790 + uint16_t direct_relative_profileId; /**< Used when 'direct' is TRUE, to select a storage profile;
150791 + should indicate the storage profile offset within the
150792 + port's storage profiles window. */
150793 + struct {
150794 + uint8_t fqid_offset_shift; /**< Shift of KeyGen results without the FQID base */
150795 + uint8_t fqid_offset_relative_profile_id_base;
150796 + /**< OR of KeyGen results without the FQID base;
150797 + should indicate the policer profile offset within the
150798 + port's storage profiles window. */
150799 + uint8_t num_of_profiles; /**< Range of profiles starting at base. */
150800 + } indirect_profile; /**< Indirect profile parameters. */
150801 + } profile_select; /**< Direct/indirect profile selection and parameters. */
150802 +} ioc_fm_pcd_kg_storage_profile_t;
150803 +#endif /* DPAA_VERSION >= 11 */
150804 +
150805 +/**************************************************************************//**
150806 + @Description Parameters for defining CC as the next engine after KeyGen
150807 + (Must match struct t_FmPcdKgCc defined in fm_pcd_ext.h)
150808 +*//***************************************************************************/
150809 +typedef struct ioc_fm_pcd_kg_cc_t {
150810 + void *tree_id; /**< CC Tree id */
150811 + uint8_t grp_id; /**< CC group id within the CC tree */
150812 + bool plcr_next; /**< TRUE if after CC, in case of data frame,
150813 + policing is required. */
150814 + bool bypass_plcr_profile_generation;
150815 + /**< TRUE to bypass KeyGen policer profile generation;
150816 + selected profile is the one set at port initialization. */
150817 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Valid only if plcr_next = TRUE and
150818 + bypass_plcr_profile_generation = FALSE */
150819 +} ioc_fm_pcd_kg_cc_t;
150820 +
150821 +/**************************************************************************//**
150822 + @Description Parameters for defining initializing a KeyGen scheme
150823 + (Must match struct t_FmPcdKgSchemeParams defined in fm_pcd_ext.h)
150824 +*//***************************************************************************/
150825 +typedef struct ioc_fm_pcd_kg_scheme_params_t {
150826 + bool modify; /**< TRUE to change an existing scheme */
150827 + union {
150828 + uint8_t relative_scheme_id;
150829 + /**< if modify=FALSE: partition-relative scheme id */
150830 + void *scheme_id; /**< if modify=TRUE: the id of an existing scheme */
150831 + } scm_id;
150832 + bool always_direct; /**< This scheme is reached only directly, i.e. no need
150833 + for match vector; KeyGen will ignore it when matching */
150834 + struct { /**< HL relevant only if always_direct=FALSE */
150835 + void *net_env_id; /**< The id of the Network Environment as returned
150836 + by FM_PCD_NetEnvCharacteristicsSet() */
150837 + uint8_t num_of_distinction_units;
150838 + /**< Number of NetEnv units listed in unit_ids array */
150839 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
150840 + /**< Indexes as passed to SetNetEnvCharacteristics (?) array */
150841 + } net_env_params;
150842 + bool use_hash; /**< use the KG Hash functionality */
150843 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
150844 + /**< used only if useHash = TRUE */
150845 + bool bypass_fqid_generation;
150846 + /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
150847 + In such a case FQID after KG will be the default FQID
150848 + defined for the relevant port, or the FQID defined by CC
150849 + in cases where CC was the previous engine. */
150850 + uint32_t base_fqid; /**< Base FQID; Relevant only if bypass_fqid_generation = FALSE;
150851 + If hash is used and an even distribution is expected
150852 + according to hash_distribution_num_of_fqids, base_fqid must be aligned to
150853 + hash_distribution_num_of_fqids. */
150854 + uint8_t num_of_used_extracted_ors;
150855 + /**< Number of FQID masks listed in extracted_ors array*/
150856 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
150857 + /**< IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS
150858 + registers are shared between qid_masks
150859 + functionality and some of the extraction
150860 + actions; Normally only some will be used
150861 + for qid_mask. Driver will return error if
150862 + resource is full at initialization time. */
150863 +#if DPAA_VERSION >= 11
150864 + bool override_storage_profile;
150865 + /**< TRUE if KeyGen override previously decided storage profile */
150866 + ioc_fm_pcd_kg_storage_profile_t storage_profile;/**< Used when override_storage_profile=TRUE */
150867 +#endif /* DPAA_VERSION >= 11 */
150868 + ioc_fm_pcd_engine next_engine; /**< may be BMI, PLCR or CC */
150869 + union { /**< depends on nextEngine */
150870 + ioc_fm_pcd_done_action done_action; /**< Used when next engine is BMI (done) */
150871 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Used when next engine is PLCR */
150872 + ioc_fm_pcd_kg_cc_t cc; /**< Used when next engine is CC */
150873 + } kg_next_engine_params;
150874 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter; /**< A structure of parameters for updating
150875 + the scheme counter */
150876 + void *id; /**< Returns the scheme Id to be used */
150877 +} ioc_fm_pcd_kg_scheme_params_t;
150878 +
150879 +/**************************************************************************//**
150880 + @Collection
150881 +*//***************************************************************************/
150882 +#if DPAA_VERSION >= 11
150883 +#define IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
150884 +#define IOC_FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
150885 +#endif /* DPAA_VERSION >= 11 */
150886 +#define IOC_FM_PCD_CC_STATS_FLR_COUNT_SIZE 4 /* Size in bytes of a frame length range counter */
150887 +/* @} */
150888 +
150889 +/**************************************************************************//**
150890 + @Description Parameters for defining CC as the next engine after a CC node.
150891 + (Must match struct t_FmPcdCcNextCcParams defined in fm_pcd_ext.h)
150892 +*//***************************************************************************/
150893 +typedef struct ioc_fm_pcd_cc_next_cc_params_t {
150894 + void *cc_node_id; /**< Id of the next CC node */
150895 +} ioc_fm_pcd_cc_next_cc_params_t;
150896 +
150897 +#if DPAA_VERSION >= 11
150898 +/**************************************************************************//**
150899 + @Description A structure for defining Frame Replicator as the next engine after a CC node.
150900 + (Must match struct t_FmPcdCcNextFrParams defined in fm_pcd_ext.h)
150901 +*//***************************************************************************/
150902 +typedef struct ioc_fm_pcd_cc_next_fr_params_t {
150903 + void* frm_replic_id; /**< The id of the next frame replicator group */
150904 +} ioc_fm_pcd_cc_next_fr_params_t;
150905 +#endif /* DPAA_VERSION >= 11 */
150906 +
150907 +/**************************************************************************//**
150908 + @Description A structure for defining PLCR params when PLCR is the
150909 + next engine after a CC node
150910 + (Must match struct t_FmPcdCcNextPlcrParams defined in fm_pcd_ext.h)
150911 +*//***************************************************************************/
150912 +typedef struct ioc_fm_pcd_cc_next_plcr_params_t {
150913 + bool override_params; /**< TRUE if CC override previously decided parameters*/
150914 + bool shared_profile; /**< Relevant only if overrideParams=TRUE:
150915 + TRUE if this profile is shared between ports */
150916 + uint16_t new_relative_profile_id; /**< Relevant only if overrideParams=TRUE:
150917 + (otherwise profile id is taken from keygen);
150918 + This parameter should indicate the policer
150919 + profile offset within the port's
150920 + policer profiles or from SHARED window.*/
150921 + uint32_t new_fqid; /**< Relevant only if overrideParams=TRUE:
150922 + FQID for enquing the frame;
150923 + In earlier chips if policer next engine is KEYGEN,
150924 + this parameter can be 0, because the KEYGEN always decides
150925 + the enqueue FQID.*/
150926 +#if DPAA_VERSION >= 11
150927 + uint8_t new_relative_storage_profile_id;
150928 + /**< Indicates the relative storage profile offset within
150929 + the port's storage profiles window;
150930 + Relevant only if the port was configured with VSP. */
150931 +#endif /* DPAA_VERSION >= 11 */
150932 +} ioc_fm_pcd_cc_next_plcr_params_t;
150933 +
150934 +/**************************************************************************//**
150935 + @Description A structure for defining enqueue params when BMI is the
150936 + next engine after a CC node
150937 + (Must match struct t_FmPcdCcNextEnqueueParams defined in fm_pcd_ext.h)
150938 +*//***************************************************************************/
150939 +typedef struct ioc_fm_pcd_cc_next_enqueue_params_t {
150940 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
150941 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
150942 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME */
150943 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
150944 + (otherwise FQID is taken from KeyGen),
150945 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME*/
150946 +#if DPAA_VERSION >= 11
150947 + uint8_t new_relative_storage_profile_id;
150948 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
150949 + storage profile offset within the port's storage profiles
150950 + window; Relevant only if the port was configured with VSP. */
150951 +#endif /* DPAA_VERSION >= 11 */
150952 +
150953 +} ioc_fm_pcd_cc_next_enqueue_params_t;
150954 +
150955 +/**************************************************************************//**
150956 + @Description A structure for defining KG params when KG is the next engine after a CC node
150957 + (Must match struct t_FmPcdCcNextKgParams defined in fm_pcd_ext.h)
150958 +*//***************************************************************************/
150959 +typedef struct ioc_fm_pcd_cc_next_kg_params_t {
150960 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
150961 + Note - this parameters are irrelevant for earlier chips */
150962 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
150963 + (otherwise FQID is taken from KeyGen),
150964 + Note - this parameters are irrelevant for earlier chips */
150965 +#if DPAA_VERSION >= 11
150966 + uint8_t new_relative_storage_profile_id;
150967 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
150968 + storage profile offset within the port's storage profiles
150969 + window; Relevant only if the port was configured with VSP. */
150970 +#endif /* DPAA_VERSION >= 11 */
150971 + void *p_direct_scheme; /**< Direct scheme id to go to. */
150972 +} ioc_fm_pcd_cc_next_kg_params_t;
150973 +
150974 +/**************************************************************************//**
150975 + @Description Parameters for defining the next engine after a CC node.
150976 + (Must match struct t_FmPcdCcNextEngineParams defined in fm_pcd_ext.h)
150977 +*//***************************************************************************/
150978 +typedef struct ioc_fm_pcd_cc_next_engine_params_t {
150979 + ioc_fm_pcd_engine next_engine; /**< User has to initialize parameters
150980 + according to nextEngine definition */
150981 + union {
150982 + ioc_fm_pcd_cc_next_cc_params_t cc_params; /**< Parameters in case next engine is CC */
150983 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< Parameters in case next engine is PLCR */
150984 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< Parameters in case next engine is BMI */
150985 + ioc_fm_pcd_cc_next_kg_params_t kg_params; /**< Parameters in case next engine is KG */
150986 +#if DPAA_VERSION >= 11
150987 + ioc_fm_pcd_cc_next_fr_params_t fr_params; /**< Parameters in case next engine is FR */
150988 +#endif /* DPAA_VERSION >= 11 */
150989 + } params; /**< Union used for all the next-engine parameters options */
150990 + void *manip_id; /**< Handle to Manipulation object.
150991 + Relevant if next engine is of type result
150992 + (e_IOC_FM_PCD_PLCR, e_IOC_FM_PCD_KG, e_IOC_FM_PCD_DONE) */
150993 + bool statistics_en; /**< If TRUE, statistics counters are incremented
150994 + for each frame passing through this
150995 + Coarse Classification entry. */
150996 +} ioc_fm_pcd_cc_next_engine_params_t;
150997 +
150998 +/**************************************************************************//**
150999 + @Description Parameters for defining a single CC key
151000 +*//***************************************************************************/
151001 +typedef struct ioc_fm_pcd_cc_key_params_t {
151002 + uint8_t *p_key; /**< pointer to the key of the size defined in key_size */
151003 + uint8_t *p_mask; /**< pointer to the Mask per key of the size defined
151004 + in keySize. p_key and p_mask (if defined) has to be
151005 + of the same size defined in the key_size */
151006 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151007 + /**< parameters for the next for the defined Key in p_key */
151008 +
151009 +} ioc_fm_pcd_cc_key_params_t;
151010 +
151011 +/**************************************************************************//**
151012 + @Description Parameters for defining CC keys parameters
151013 + The driver supports two methods for CC node allocation: dynamic and static.
151014 + Static mode was created in order to prevent runtime alloc/free
151015 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
151016 + the driver automatically allocates the memory according to
151017 + 'max_num_of_keys' parameter. The driver calculates the maximal memory
151018 + size that may be used for this CC-Node taking into consideration
151019 + 'mask_support' and 'statistics_mode' parameters.
151020 + When 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
151021 + parameters of this node, 'max_num_of_keys' must be equal to 'num_of_keys'.
151022 + In dynamic mode, 'max_num_of_keys' must be zero. At initialization,
151023 + all required structures are allocated according to 'num_of_keys'
151024 + parameter. During runtime modification, these structures are
151025 + re-allocated according to the updated number of keys.
151026 +
151027 + Please note that 'action' and 'ic_indx_mask' mentioned in the
151028 + specific parameter explanations are passed in the extraction
151029 + parameters of the node (fields of extractccparams.extractnonhdr).
151030 +*//***************************************************************************/
151031 +typedef struct ioc_keys_params_t {
151032 + uint16_t max_num_of_keys;/**< Maximum number of keys that will (ever) be used in this CC-Node;
151033 + A value of zero may be used for dynamic memory allocation. */
151034 + bool mask_support; /**< This parameter is relevant only if a node is initialized with
151035 + action = e_IOC_FM_PCD_ACTION_EXACT_MATCH and max_num_of_keys > 0;
151036 + Should be TRUE to reserve table memory for key masks, even if
151037 + initial keys do not contain masks, or if the node was initialized
151038 + as 'empty' (without keys); this will allow user to add keys with
151039 + masks at runtime. */
151040 + ioc_fm_pcd_cc_stats_mode statistics_mode;/**< Determines the supported statistics mode for all node's keys.
151041 + To enable statistics gathering, statistics should be enabled per
151042 + every key, using 'statistics_en' in next engine parameters structure
151043 + of that key;
151044 + If 'max_num_of_keys' is set, all required structures will be
151045 + preallocated for all keys. */
151046 +#if (DPAA_VERSION >= 11)
151047 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
151048 + /**< Relevant only for 'RMON' statistics mode
151049 + (this feature is supported only on B4860 device);
151050 + Holds a list of programmable thresholds. For each received frame,
151051 + its length in bytes is examined against these range thresholds and
151052 + the appropriate counter is incremented by 1. For example, to belong
151053 + to range i, the following should hold:
151054 + range i-1 threshold < frame length <= range i threshold
151055 + Each range threshold must be larger then its preceding range
151056 + threshold. Last range threshold must be 0xFFFF. */
151057 +#endif /* (DPAA_VERSION >= 11) */
151058 + uint16_t num_of_keys; /**< Number of initial keys;
151059 + Note that in case of 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP,
151060 + this field should be power-of-2 of the number of bits that are
151061 + set in 'ic_indx_mask'. */
151062 + uint8_t key_size; /**< Size of key - for extraction of type FULL_FIELD, 'key_size' has
151063 + to be the standard size of the selected key; For other extraction
151064 + types, 'key_size' has to be as size of extraction; When 'action' =
151065 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
151066 + ioc_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS];
151067 + /**< An array with 'num_of_keys' entries, each entry specifies the
151068 + corresponding key parameters;
151069 + When 'action' = e_IOC_FM_PCD_ACTION_EXACT_MATCH, this value must not
151070 + exceed 255 (IOC_FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
151071 + for the 'miss' entry. */
151072 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
151073 + /**< Parameters for defining the next engine when a key is not matched;
151074 + Not relevant if action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP. */
151075 +} ioc_keys_params_t;
151076 +
151077 +/**************************************************************************//**
151078 + @Description Parameters for defining a CC node
151079 +*//***************************************************************************/
151080 +typedef struct ioc_fm_pcd_cc_node_params_t {
151081 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< Extraction parameters */
151082 + ioc_keys_params_t keys_params; /**< Keys definition matching the selected extraction */
151083 + void *id; /**< Output parameter; returns the CC node Id to be used */
151084 +} ioc_fm_pcd_cc_node_params_t;
151085 +
151086 +/**************************************************************************//**
151087 + @Description Parameters for defining a hash table
151088 + (Must match struct t_FmPcdHashTableParams defined in fm_pcd_ext.h)
151089 +*//***************************************************************************/
151090 +typedef struct ioc_fm_pcd_hash_table_params_t {
151091 + uint16_t max_num_of_keys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
151092 + ioc_fm_pcd_cc_stats_mode statistics_mode; /**< If not e_IOC_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
151093 + requested statistics mode will be allocated according to max_num_of_keys. */
151094 + uint8_t kg_hash_shift; /**< KG-Hash-shift as it was configured in the KG-scheme
151095 + that leads to this hash-table. */
151096 + uint16_t hash_res_mask; /**< Mask that will be used on the hash-result;
151097 + The number-of-sets for this hash will be calculated
151098 + as (2^(number of bits set in 'hash_res_mask'));
151099 + The 4 lower bits must be cleared. */
151100 + uint8_t hash_shift; /**< Byte offset from the beginning of the KeyGen hash result to the
151101 + 2-bytes to be used as hash index. */
151102 + uint8_t match_key_size; /**< Size of the exact match keys held by the hash buckets */
151103 +
151104 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
151105 + /**< Parameters for defining the next engine when a key is not matched */
151106 + void *id;
151107 +} ioc_fm_pcd_hash_table_params_t;
151108 +
151109 +/**************************************************************************//**
151110 + @Description A structure with the arguments for the FM_PCD_HashTableAddKey ioctl() call
151111 +*//***************************************************************************/
151112 +typedef struct ioc_fm_pcd_hash_table_add_key_params_t {
151113 + void *p_hash_tbl;
151114 + uint8_t key_size;
151115 + ioc_fm_pcd_cc_key_params_t key_params;
151116 +} ioc_fm_pcd_hash_table_add_key_params_t;
151117 +
151118 +/**************************************************************************//**
151119 + @Description Parameters for defining a CC tree group.
151120 +
151121 + This structure defines a CC group in terms of NetEnv units
151122 + and the action to be taken in each case. The unit_ids list must
151123 + be given in order from low to high indices.
151124 +
151125 + ioc_fm_pcd_cc_next_engine_params_t is a list of 2^num_of_distinction_units
151126 + structures where each defines the next action to be taken for
151127 + each units combination. for example:
151128 + num_of_distinction_units = 2
151129 + unit_ids = {1,3}
151130 + next_engine_per_entries_in_grp[0] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151131 + unit 1 - not found; unit 3 - not found;
151132 + next_engine_per_entries_in_grp[1] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151133 + unit 1 - not found; unit 3 - found;
151134 + next_engine_per_entries_in_grp[2] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151135 + unit 1 - found; unit 3 - not found;
151136 + next_engine_per_entries_in_grp[3] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151137 + unit 1 - found; unit 3 - found;
151138 +*//***************************************************************************/
151139 +typedef struct ioc_fm_pcd_cc_grp_params_t {
151140 + uint8_t num_of_distinction_units; /**< Up to 4 */
151141 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
151142 + /**< Indexes of the units as defined in
151143 + FM_PCD_NetEnvCharacteristicsSet() */
151144 + ioc_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
151145 + /**< Maximum entries per group is 16 */
151146 +} ioc_fm_pcd_cc_grp_params_t;
151147 +
151148 +/**************************************************************************//**
151149 + @Description Parameters for defining the CC tree groups
151150 + (Must match struct t_FmPcdCcTreeParams defined in fm_pcd_ext.h)
151151 +*//***************************************************************************/
151152 +typedef struct ioc_fm_pcd_cc_tree_params_t {
151153 + void *net_env_id; /**< Id of the Network Environment as returned
151154 + by FM_PCD_NetEnvCharacteristicsSet() */
151155 + uint8_t num_of_groups; /**< Number of CC groups within the CC tree */
151156 + ioc_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
151157 + /**< Parameters for each group. */
151158 + void *id; /**< Output parameter; Returns the tree Id to be used */
151159 +} ioc_fm_pcd_cc_tree_params_t;
151160 +
151161 +/**************************************************************************//**
151162 + @Description Parameters for defining policer byte rate
151163 +*//***************************************************************************/
151164 +typedef struct ioc_fm_pcd_plcr_byte_rate_mode_param_t {
151165 + ioc_fm_pcd_plcr_frame_length_select frame_length_selection; /**< Frame length selection */
151166 + ioc_fm_pcd_plcr_roll_back_frame_select roll_back_frame_selection; /**< relevant option only e_IOC_FM_PCD_PLCR_L2_FRM_LEN,
151167 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN */
151168 +} ioc_fm_pcd_plcr_byte_rate_mode_param_t;
151169 +
151170 +/**************************************************************************//**
151171 + @Description Parameters for defining the policer profile (based on
151172 + RFC-2698 or RFC-4115 attributes).
151173 +*//***************************************************************************/
151174 +typedef struct ioc_fm_pcd_plcr_non_passthrough_alg_param_t {
151175 + ioc_fm_pcd_plcr_rate_mode rate_mode; /**< Byte / Packet */
151176 + ioc_fm_pcd_plcr_byte_rate_mode_param_t byte_mode_param; /**< Valid for Byte NULL for Packet */
151177 + uint32_t committed_info_rate; /**< KBits/Sec or Packets/Sec */
151178 + uint32_t committed_burst_size; /**< KBits or Packets */
151179 + uint32_t peak_or_excess_info_rate; /**< KBits/Sec or Packets/Sec */
151180 + uint32_t peak_or_excess_burst_size; /**< KBits or Packets */
151181 +} ioc_fm_pcd_plcr_non_passthrough_alg_param_t;
151182 +
151183 +/**************************************************************************//**
151184 + @Description Parameters for defining the next engine after policer
151185 +*//***************************************************************************/
151186 +typedef union ioc_fm_pcd_plcr_next_engine_params_u {
151187 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
151188 + void *p_profile; /**< Policer profile handle - used when next engine
151189 + is PLCR, must be a SHARED profile */
151190 + void *p_direct_scheme; /**< Direct scheme select - when next engine is Keygen */
151191 +} ioc_fm_pcd_plcr_next_engine_params_u;
151192 +
151193 +typedef struct ioc_fm_pcd_port_params_t {
151194 + ioc_fm_port_type port_type; /**< Type of port for this profile */
151195 + uint8_t port_id; /**< FM-Port id of port for this profile */
151196 +} ioc_fm_pcd_port_params_t;
151197 +
151198 +/**************************************************************************//**
151199 + @Description Parameters for defining the policer profile entry
151200 + (Must match struct t_FmPcdPlcrProfileParams defined in fm_pcd_ext.h)
151201 +*//***************************************************************************/
151202 +typedef struct ioc_fm_pcd_plcr_profile_params_t {
151203 + bool modify; /**< TRUE to change an existing profile */
151204 + union {
151205 + struct {
151206 + ioc_fm_pcd_profile_type_selection profile_type; /**< Type of policer profile */
151207 + ioc_fm_pcd_port_params_t *p_fm_port; /**< Relevant for per-port profiles only */
151208 + uint16_t relative_profile_id; /**< Profile id - relative to shared group or to port */
151209 + } new_params; /**< Use it when modify = FALSE */
151210 + void *p_profile; /**< A handle to a profile - use it when modify=TRUE */
151211 + } profile_select;
151212 + ioc_fm_pcd_plcr_algorithm_selection alg_selection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
151213 + ioc_fm_pcd_plcr_color_mode color_mode; /**< COLOR_BLIND, COLOR_AWARE */
151214 +
151215 + union {
151216 + ioc_fm_pcd_plcr_color dflt_color; /**< For Color-Blind Pass-Through mode; the policer will re-color
151217 + any incoming packet with the default value. */
151218 + ioc_fm_pcd_plcr_color override; /**< For Color-Aware modes; the profile response to a
151219 + pre-color value of 2'b11. */
151220 + } color;
151221 +
151222 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param; /**< RFC2698 or RFC4115 parameters */
151223 +
151224 + ioc_fm_pcd_engine next_engine_on_green; /**< Next engine for green-colored frames */
151225 + ioc_fm_pcd_plcr_next_engine_params_u params_on_green; /**< Next engine parameters for green-colored frames */
151226 +
151227 + ioc_fm_pcd_engine next_engine_on_yellow; /**< Next engine for yellow-colored frames */
151228 + ioc_fm_pcd_plcr_next_engine_params_u params_on_yellow; /**< Next engine parameters for yellow-colored frames */
151229 +
151230 + ioc_fm_pcd_engine next_engine_on_red; /**< Next engine for red-colored frames */
151231 + ioc_fm_pcd_plcr_next_engine_params_u params_on_red; /**< Next engine parameters for red-colored frames */
151232 +
151233 + bool trap_profile_on_flow_A; /**< Obsolete - do not use */
151234 + bool trap_profile_on_flow_B; /**< Obsolete - do not use */
151235 + bool trap_profile_on_flow_C; /**< Obsolete - do not use */
151236 +
151237 + void *id; /**< output parameter; Returns the profile Id to be used */
151238 +} ioc_fm_pcd_plcr_profile_params_t;
151239 +
151240 +/**************************************************************************//**
151241 + @Description A structure for modifying CC tree next engine
151242 +*//***************************************************************************/
151243 +typedef struct ioc_fm_pcd_cc_tree_modify_next_engine_params_t {
151244 + void *id; /**< CC tree Id to be used */
151245 + uint8_t grp_indx; /**< A Group index in the tree */
151246 + uint8_t indx; /**< Entry index in the group defined by grp_index */
151247 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151248 + /**< Parameters for the next for the defined Key in the p_Key */
151249 +} ioc_fm_pcd_cc_tree_modify_next_engine_params_t;
151250 +
151251 +/**************************************************************************//**
151252 + @Description A structure for modifying CC node next engine
151253 +*//***************************************************************************/
151254 +typedef struct ioc_fm_pcd_cc_node_modify_next_engine_params_t {
151255 + void *id; /**< CC node Id to be used */
151256 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151257 + NOTE: This parameter is IGNORED for miss-key! */
151258 + uint8_t key_size; /**< Key size of added key */
151259 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151260 + /**< parameters for the next for the defined Key in the p_Key */
151261 +} ioc_fm_pcd_cc_node_modify_next_engine_params_t;
151262 +
151263 +/**************************************************************************//**
151264 + @Description A structure for remove CC node key
151265 +*//***************************************************************************/
151266 +typedef struct ioc_fm_pcd_cc_node_remove_key_params_t {
151267 + void *id; /**< CC node Id to be used */
151268 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151269 + NOTE: This parameter is IGNORED for miss-key! */
151270 +} ioc_fm_pcd_cc_node_remove_key_params_t;
151271 +
151272 +/**************************************************************************//**
151273 + @Description A structure for modifying CC node key and next engine
151274 +*//***************************************************************************/
151275 +typedef struct ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
151276 + void *id; /**< CC node Id to be used */
151277 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151278 + NOTE: This parameter is IGNORED for miss-key! */
151279 + uint8_t key_size; /**< Key size of added key */
151280 + ioc_fm_pcd_cc_key_params_t key_params; /**< it's array with numOfKeys entries each entry in
151281 + the array of the type ioc_fm_pcd_cc_key_params_t */
151282 +} ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
151283 +
151284 +/**************************************************************************//**
151285 + @Description A structure for modifying CC node key
151286 +*//***************************************************************************/
151287 +typedef struct ioc_fm_pcd_cc_node_modify_key_params_t {
151288 + void *id; /**< CC node Id to be used */
151289 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151290 + NOTE: This parameter is IGNORED for miss-key! */
151291 + uint8_t key_size; /**< Key size of added key */
151292 + uint8_t *p_key; /**< Pointer to the key of the size defined in key_size */
151293 + uint8_t *p_mask; /**< Pointer to the Mask per key of the size defined
151294 + in keySize. p_Key and p_Mask (if defined) have to be
151295 + of the same size as defined in the key_size */
151296 +} ioc_fm_pcd_cc_node_modify_key_params_t;
151297 +
151298 +/**************************************************************************//**
151299 + @Description A structure with the arguments for the FM_PCD_HashTableRemoveKey ioctl() call
151300 +*//***************************************************************************/
151301 +typedef struct ioc_fm_pcd_hash_table_remove_key_params_t {
151302 + void *p_hash_tbl; /**< The id of the hash table */
151303 + uint8_t key_size; /**< The size of the key to remove */
151304 + uint8_t *p_key; /**< Pointer to the key to remove */
151305 +} ioc_fm_pcd_hash_table_remove_key_params_t;
151306 +
151307 +/**************************************************************************//**
151308 + @Description Parameters for selecting a location for requested manipulation
151309 +*//***************************************************************************/
151310 +typedef struct ioc_fm_manip_hdr_info_t {
151311 + ioc_net_header_type hdr; /**< Header selection */
151312 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
151313 + bool by_field; /**< TRUE if the location of manipulation is according to some field in the specific header*/
151314 + ioc_fm_pcd_fields_u full_field; /**< Relevant only when by_field = TRUE: Extract field */
151315 +} ioc_fm_manip_hdr_info_t;
151316 +
151317 +/**************************************************************************//**
151318 + @Description Parameters for defining header removal by header type
151319 +*//***************************************************************************/
151320 +typedef struct ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t {
151321 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_type type; /**< Selection of header removal location */
151322 + union {
151323 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
151324 + struct {
151325 + bool include;/**< If FALSE, remove until the specified header (not including the header);
151326 + If TRUE, remove also the specified header. */
151327 + ioc_fm_manip_hdr_info_t hdr_info;
151328 + } from_start_by_hdr; /**< Relevant when type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
151329 +#endif /* FM_CAPWAP_SUPPORT */
151330 +#if (DPAA_VERSION >= 11)
151331 + ioc_fm_manip_hdr_info_t hdr_info; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
151332 +#endif /* (DPAA_VERSION >= 11) */
151333 + ioc_fm_pcd_manip_hdr_rmv_specific_l2 specific_l2;/**< Relevant when type = e_IOC_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
151334 + Defines which L2 headers to remove. */
151335 + } u;
151336 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t;
151337 +
151338 +/**************************************************************************//**
151339 + @Description Parameters for configuring IP fragmentation manipulation
151340 +*//***************************************************************************/
151341 +typedef struct ioc_fm_pcd_manip_frag_ip_params_t {
151342 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
151343 + IP fragmentation will be executed.*/
151344 +#if DPAA_VERSION == 10
151345 + uint8_t scratch_bpid; /**< Absolute buffer pool id according to BM configuration.*/
151346 +#endif /* DPAA_VERSION == 10 */
151347 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
151348 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
151349 + received frame's buffer. */
151350 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
151351 + This parameter is relevant when 'sg_bpid_en=TRUE';
151352 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
151353 + of this pool need to be allocated in the same memory area as the received buffers.
151354 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
151355 + mutual to all these sources. */
151356 + ioc_fm_pcd_manip_dont_frag_action dont_frag_action; /**< Dont Fragment Action - If an IP packet is larger
151357 + than MTU and its DF bit is set, then this field will
151358 + determine the action to be taken.*/
151359 +} ioc_fm_pcd_manip_frag_ip_params_t;
151360 +
151361 +/**************************************************************************//**
151362 + @Description Parameters for configuring IP reassembly manipulation.
151363 +
151364 + This is a common structure for both IPv4 and IPv6 reassembly
151365 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
151366 + set the 'hdr' field in ioc_fm_pcd_manip_reassem_params_t to IOC_HEADER_TYPE_IPv6.
151367 +*//***************************************************************************/
151368 +typedef struct ioc_fm_pcd_manip_reassem_ip_params_t {
151369 + uint8_t relative_scheme_id[2]; /**< Partition relative scheme id:
151370 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
151371 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
151372 + NOTE: The following comment is relevant only for FMAN v2 devices:
151373 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
151374 + the user schemes id to ensure that the reassembly's schemes will be first match.
151375 + The remaining schemes, if defined, should have higher relative scheme ID. */
151376 +#if DPAA_VERSION >= 11
151377 + uint32_t non_consistent_sp_fqid; /**< In case that other fragments of the frame corresponds to different storage
151378 + profile than the opening fragment (Non-Consistent-SP state)
151379 + then one of two possible scenarios occurs:
151380 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
151381 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
151382 +#else
151383 + uint8_t sg_bpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
151384 +#endif /* DPAA_VERSION >= 11 */
151385 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
151386 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
151387 + uint16_t min_frag_size[2]; /**< Minimum fragment size:
151388 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
151389 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry[2];
151390 + /**< Number of frames per hash entry needed for reassembly process:
151391 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH);
151392 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH). */
151393 + uint16_t max_num_frames_in_process;/**< Number of frames which can be processed by Reassembly in the same time;
151394 + Must be power of 2;
151395 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH,
151396 + maxNumFramesInProcess has to be in the range of 4 - 512;
151397 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH,
151398 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
151399 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
151400 + uint32_t fqid_for_time_out_frames;/**< FQID in which time out frames will enqueue during Time Out Process */
151401 + uint32_t timeout_threshold_for_reassm_process;
151402 + /**< Represents the time interval in microseconds which defines
151403 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
151404 +} ioc_fm_pcd_manip_reassem_ip_params_t;
151405 +
151406 +/**************************************************************************//**
151407 + @Description Parameters for defining IPSEC manipulation
151408 +*//***************************************************************************/
151409 +typedef struct ioc_fm_pcd_manip_special_offload_ipsec_params_t {
151410 + bool decryption; /**< TRUE if being used in decryption direction;
151411 + FALSE if being used in encryption direction. */
151412 + bool ecn_copy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
151413 + (direction depends on the 'decryption' field). */
151414 + bool dscp_copy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
151415 + (direction depends on the 'decryption' field). */
151416 + bool variable_ip_hdr_len; /**< TRUE for supporting variable IP header length in decryption. */
151417 + bool variable_ip_version; /**< TRUE for supporting both IP version on the same SA in encryption */
151418 + uint8_t outer_ip_hdr_len; /**< If 'variable_ip_version == TRUE' than this field must be set to non-zero value;
151419 + It is specifies the length of the outer IP header that was configured in the
151420 + corresponding SA. */
151421 + uint16_t arw_size; /**< if <> '0' then will perform ARW check for this SA;
151422 + The value must be a multiplication of 16 */
151423 + void *arw_addr; /**< if arwSize <> '0' then this field must be set to non-zero value;
151424 + MUST be allocated from FMAN's MURAM that the post-sec op-port belong
151425 + Must be 4B aligned. Required MURAM size is '(NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
151426 +} ioc_fm_pcd_manip_special_offload_ipsec_params_t;
151427 +
151428 +#if (DPAA_VERSION >= 11)
151429 +/**************************************************************************//**
151430 + @Description Parameters for configuring CAPWAP fragmentation manipulation
151431 +
151432 + Restrictions:
151433 + - Maximum number of fragments per frame is 16.
151434 + - Transmit confirmation is not supported.
151435 + - Fragmentation nodes must be set as the last PCD action (i.e. the
151436 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
151437 + - Only BMan buffers shall be used for frames to be fragmented.
151438 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
151439 + does not support VSP. Therefore, on the same port where we have IPF we
151440 + cannot support VSP.
151441 +*//***************************************************************************/
151442 +typedef struct ioc_fm_pcd_manip_frag_capwap_params_t {
151443 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
151444 + CAPWAP fragmentation will be executed.*/
151445 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
151446 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
151447 + received frame's buffer. */
151448 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
151449 + This parameters is relevant when 'sgBpidEn=TRUE';
151450 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
151451 + of this pool need to be allocated in the same memory area as the received buffers.
151452 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
151453 + mutual to all these sources. */
151454 + bool compress_mode_en; /**< CAPWAP Header Options Compress Enable mode;
151455 + When this mode is enabled then only the first fragment include the CAPWAP header options
151456 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
151457 + options field (CAPWAP header is updated accordingly).*/
151458 +} ioc_fm_pcd_manip_frag_capwap_params_t;
151459 +
151460 +/**************************************************************************//**
151461 + @Description Parameters for configuring CAPWAP reassembly manipulation.
151462 +
151463 + Restrictions:
151464 + - Application must define one scheme to catch the reassembled frames.
151465 + - Maximum number of fragments per frame is 16.
151466 +
151467 +*//***************************************************************************/
151468 +typedef struct ioc_fm_pcd_manip_reassem_capwap_params_t {
151469 + uint8_t relative_scheme_id; /**< Partition relative scheme id;
151470 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
151471 + Rest schemes, if defined, should have higher relative scheme ID. */
151472 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
151473 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
151474 + uint16_t max_reassembled_frame_length;/**< The maximum CAPWAP reassembled frame length in bytes;
151475 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
151476 + considered as a valid length;
151477 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
151478 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
151479 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry;
151480 + /**< Number of frames per hash entry needed for reassembly process */
151481 + uint16_t max_num_frames_in_process; /**< Number of frames which can be processed by reassembly in the same time;
151482 + Must be power of 2;
151483 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
151484 + maxNumFramesInProcess has to be in the range of 4 - 512;
151485 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
151486 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
151487 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
151488 + uint32_t fqid_for_time_out_frames; /**< FQID in which time out frames will enqueue during Time Out Process;
151489 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
151490 + uint32_t timeout_threshold_for_reassm_process;
151491 + /**< Represents the time interval in microseconds which defines
151492 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
151493 +} ioc_fm_pcd_manip_reassem_capwap_params_t;
151494 +
151495 +/**************************************************************************//**
151496 + @Description structure for defining CAPWAP manipulation
151497 +*//***************************************************************************/
151498 +typedef struct ioc_fm_pcd_manip_special_offload_capwap_params_t {
151499 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
151500 + ioc_fm_pcd_manip_hdr_qos_src qos_src; /**< TODO */
151501 +} ioc_fm_pcd_manip_special_offload_capwap_params_t;
151502 +
151503 +#endif /* (DPAA_VERSION >= 11) */
151504 +
151505 +/**************************************************************************//**
151506 + @Description Parameters for defining special offload manipulation
151507 +*//***************************************************************************/
151508 +typedef struct ioc_fm_pcd_manip_special_offload_params_t {
151509 + ioc_fm_pcd_manip_special_offload_type type; /**< Type of special offload manipulation */
151510 + union
151511 + {
151512 + ioc_fm_pcd_manip_special_offload_ipsec_params_t ipsec; /**< Parameters for IPSec; Relevant when
151513 + type = e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
151514 +
151515 +#if (DPAA_VERSION >= 11)
151516 + ioc_fm_pcd_manip_special_offload_capwap_params_t capwap; /**< Parameters for CAPWAP; Relevant when
151517 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
151518 +#endif /* (DPAA_VERSION >= 11) */
151519 + } u;
151520 +} ioc_fm_pcd_manip_special_offload_params_t;
151521 +
151522 +/**************************************************************************//**
151523 + @Description Parameters for defining generic removal manipulation
151524 +*//***************************************************************************/
151525 +typedef struct ioc_fm_pcd_manip_hdr_rmv_generic_params_t {
151526 + uint8_t offset; /**< Offset from beginning of header to the start
151527 + location of the removal */
151528 + uint8_t size; /**< Size of removed section */
151529 +} ioc_fm_pcd_manip_hdr_rmv_generic_params_t;
151530 +
151531 +/**************************************************************************//**
151532 + @Description Parameters for defining insertion manipulation
151533 +*//***************************************************************************/
151534 +typedef struct ioc_fm_pcd_manip_hdr_insrt_t {
151535 + uint8_t size; /**< size of inserted section */
151536 + uint8_t *p_data; /**< data to be inserted */
151537 +} ioc_fm_pcd_manip_hdr_insrt_t;
151538 +
151539 +/**************************************************************************//**
151540 + @Description Parameters for defining generic insertion manipulation
151541 +*//***************************************************************************/
151542 +typedef struct ioc_fm_pcd_manip_hdr_insrt_generic_params_t {
151543 + uint8_t offset; /**< Offset from beginning of header to the start
151544 + location of the insertion */
151545 + uint8_t size; /**< Size of inserted section */
151546 + bool replace; /**< TRUE to override (replace) existing data at
151547 + 'offset', FALSE to insert */
151548 + uint8_t *p_data; /**< Pointer to data to be inserted */
151549 +} ioc_fm_pcd_manip_hdr_insrt_generic_params_t;
151550 +
151551 +/**************************************************************************//**
151552 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
151553 +*//***************************************************************************/
151554 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t {
151555 + uint8_t dscp_to_vpri_table[IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
151556 + /**< A table of VPri values for each DSCP value;
151557 + The index is the D_SCP value (0-0x3F) and the
151558 + value is the corresponding VPRI (0-15). */
151559 + uint8_t vpri_def_val; /**< 0-7, Relevant only if if update_type =
151560 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
151561 + this field is the Q Tag default value if the
151562 + IP header is not found. */
151563 +} ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t;
151564 +
151565 +/**************************************************************************//**
151566 + @Description Parameters for defining header manipulation VLAN fields updates
151567 +*//***************************************************************************/
151568 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_t {
151569 + ioc_fm_pcd_manip_hdr_field_update_vlan update_type; /**< Selects VLAN update type */
151570 + union {
151571 + uint8_t vpri; /**< 0-7, Relevant only if If update_type =
151572 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
151573 + is the new VLAN pri. */
151574 + ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t dscp_to_vpri;
151575 + /**< Parameters structure, Relevant only if update_type =
151576 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
151577 + } u;
151578 +} ioc_fm_pcd_manip_hdr_field_update_vlan_t;
151579 +
151580 +/**************************************************************************//**
151581 + @Description Parameters for defining header manipulation IPV4 fields updates
151582 +*//***************************************************************************/
151583 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv4_t {
151584 + ioc_ipv4_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151585 + uint8_t tos; /**< 8 bit New TOS; Relevant if valid_updates contains
151586 + IOC_HDR_MANIP_IPV4_TOS */
151587 + uint16_t id; /**< 16 bit New IP ID; Relevant only if valid_updates
151588 + contains IOC_HDR_MANIP_IPV4_ID */
151589 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if valid_updates
151590 + contains IOC_HDR_MANIP_IPV4_SRC */
151591 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if valid_updates
151592 + contains IOC_HDR_MANIP_IPV4_DST */
151593 +} ioc_fm_pcd_manip_hdr_field_update_ipv4_t;
151594 +
151595 +/**************************************************************************//**
151596 + @Description Parameters for defining header manipulation IPV6 fields updates
151597 +*//***************************************************************************/
151598 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv6_t {
151599 + ioc_ipv6_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151600 + uint8_t traffic_class; /**< 8 bit New Traffic Class; Relevant if valid_updates contains
151601 + IOC_HDR_MANIP_IPV6_TC */
151602 + uint8_t src[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
151603 + /**< 16 byte new IP SRC; Relevant only if valid_updates
151604 + contains IOC_HDR_MANIP_IPV6_SRC */
151605 + uint8_t dst[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
151606 + /**< 16 byte new IP DST; Relevant only if valid_updates
151607 + contains IOC_HDR_MANIP_IPV6_DST */
151608 +} ioc_fm_pcd_manip_hdr_field_update_ipv6_t;
151609 +
151610 +/**************************************************************************//**
151611 + @Description Parameters for defining header manipulation TCP/UDP fields updates
151612 +*//***************************************************************************/
151613 +typedef struct ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t {
151614 + ioc_tcp_udp_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151615 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if valid_updates
151616 + contains IOC_HDR_MANIP_TCP_UDP_SRC */
151617 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if valid_updates
151618 + contains IOC_HDR_MANIP_TCP_UDP_DST */
151619 +} ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t;
151620 +
151621 +/**************************************************************************//**
151622 + @Description Parameters for defining header manipulation fields updates
151623 +*//***************************************************************************/
151624 +typedef struct ioc_fm_pcd_manip_hdr_field_update_params_t {
151625 + ioc_fm_pcd_manip_hdr_field_update_type type; /**< Type of header field update manipulation */
151626 + union {
151627 + ioc_fm_pcd_manip_hdr_field_update_vlan_t vlan; /**< Parameters for VLAN update. Relevant when
151628 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
151629 + ioc_fm_pcd_manip_hdr_field_update_ipv4_t ipv4; /**< Parameters for IPv4 update. Relevant when
151630 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
151631 + ioc_fm_pcd_manip_hdr_field_update_ipv6_t ipv6; /**< Parameters for IPv6 update. Relevant when
151632 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
151633 + ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t tcp_udp;/**< Parameters for TCP/UDP update. Relevant when
151634 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
151635 + } u;
151636 +} ioc_fm_pcd_manip_hdr_field_update_params_t;
151637 +
151638 +/**************************************************************************//**
151639 + @Description Parameters for defining custom header manipulation for IP replacement
151640 +*//***************************************************************************/
151641 +typedef struct ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t {
151642 + ioc_fm_pcd_manip_hdr_custom_ip_replace replace_type; /**< Selects replace update type */
151643 + bool dec_ttl_hl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
151644 + bool update_ipv4_id; /**< Relevant when replace_type =
151645 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
151646 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
151647 + update_ipv4_id = TRUE */
151648 + uint8_t hdr_size; /**< The size of the new IP header */
151649 + uint8_t hdr[IOC_FM_PCD_MANIP_MAX_HDR_SIZE];
151650 + /**< The new IP header */
151651 +} ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t;
151652 +
151653 +/**************************************************************************//**
151654 + @Description Parameters for defining custom header manipulation
151655 +*//***************************************************************************/
151656 +typedef struct ioc_fm_pcd_manip_hdr_custom_params_t {
151657 + ioc_fm_pcd_manip_hdr_custom_type type; /**< Type of header field update manipulation */
151658 + union {
151659 + ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t ip_hdr_replace;
151660 + /**< Parameters IP header replacement */
151661 + } u;
151662 +} ioc_fm_pcd_manip_hdr_custom_params_t;
151663 +
151664 +/**************************************************************************//**
151665 + @Description Parameters for defining specific L2 insertion manipulation
151666 +*//***************************************************************************/
151667 +typedef struct ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
151668 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2; /**< Selects which L2 headers to insert */
151669 + bool update; /**< TRUE to update MPLS header */
151670 + uint8_t size; /**< size of inserted section */
151671 + uint8_t *p_data; /**< data to be inserted */
151672 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
151673 +
151674 +#if (DPAA_VERSION >= 11)
151675 +/**************************************************************************//**
151676 + @Description Parameters for defining IP insertion manipulation
151677 +*//***************************************************************************/
151678 +typedef struct ioc_fm_pcd_manip_hdr_insrt_ip_params_t {
151679 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
151680 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
151681 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
151682 + the inserted header */
151683 + uint16_t id; /**< 16 bit New IP ID */
151684 + bool dont_frag_overwrite;
151685 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
151686 + * This byte is configured to be overwritten when RPD is set. */
151687 + uint8_t last_dst_offset;
151688 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
151689 + * in order to calculate UDP checksum pseudo header;
151690 + * Otherwise set it to '0'. */
151691 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
151692 +} ioc_fm_pcd_manip_hdr_insrt_ip_params_t;
151693 +#endif /* (DPAA_VERSION >= 11) */
151694 +
151695 +/**************************************************************************//**
151696 + @Description Parameters for defining header insertion manipulation by header type
151697 +*//***************************************************************************/
151698 +typedef struct ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
151699 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type; /**< Selects manipulation type */
151700 + union {
151701 + ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
151702 + /**< Used when type = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
151703 + Selects which L2 headers to remove */
151704 +#if (DPAA_VERSION >= 11)
151705 + ioc_fm_pcd_manip_hdr_insrt_ip_params_t ip_params; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
151706 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
151707 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
151708 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
151709 +#endif /* (DPAA_VERSION >= 11) */
151710 + } u;
151711 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
151712 +
151713 +/**************************************************************************//**
151714 + @Description Parameters for defining header insertion manipulation
151715 +*//***************************************************************************/
151716 +typedef struct ioc_fm_pcd_manip_hdr_insrt_params_t {
151717 + ioc_fm_pcd_manip_hdr_insrt_type type; /**< Type of insertion manipulation */
151718 + union {
151719 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr; /**< Parameters for defining header insertion manipulation by header type,
151720 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR */
151721 + ioc_fm_pcd_manip_hdr_insrt_generic_params_t generic;/**< Parameters for defining generic header insertion manipulation,
151722 + relevant if type = e_IOC_FM_PCD_MANIP_INSRT_GENERIC */
151723 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
151724 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
151725 + /**< Parameters for defining header insertion manipulation by template,
151726 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
151727 +#endif /* FM_CAPWAP_SUPPORT */
151728 + } u;
151729 +} ioc_fm_pcd_manip_hdr_insrt_params_t;
151730 +
151731 +/**************************************************************************//**
151732 + @Description Parameters for defining header removal manipulation
151733 +*//***************************************************************************/
151734 +typedef struct ioc_fm_pcd_manip_hdr_rmv_params_t {
151735 + ioc_fm_pcd_manip_hdr_rmv_type type; /**< Type of header removal manipulation */
151736 + union {
151737 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t by_hdr; /**< Parameters for defining header removal manipulation by header type,
151738 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR */
151739 + ioc_fm_pcd_manip_hdr_rmv_generic_params_t generic; /**< Parameters for defining generic header removal manipulation,
151740 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_GENERIC */
151741 + } u;
151742 +} ioc_fm_pcd_manip_hdr_rmv_params_t;
151743 +
151744 +/**************************************************************************//**
151745 + @Description Parameters for defining header manipulation node
151746 +*//***************************************************************************/
151747 +typedef struct ioc_fm_pcd_manip_hdr_params_t {
151748 + bool rmv; /**< TRUE, to define removal manipulation */
151749 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
151750 +
151751 + bool insrt; /**< TRUE, to define insertion manipulation */
151752 + ioc_fm_pcd_manip_hdr_insrt_params_t insrt_params; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
151753 +
151754 + bool field_update; /**< TRUE, to define field update manipulation */
151755 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
151756 +
151757 + bool custom; /**< TRUE, to define custom manipulation */
151758 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
151759 +
151760 + bool dont_parse_after_manip;/**< FALSE to activate the parser a second time after
151761 + completing the manipulation on the frame */
151762 +} ioc_fm_pcd_manip_hdr_params_t;
151763 +
151764 +
151765 +/**************************************************************************//**
151766 + @Description structure for defining fragmentation manipulation
151767 +*//***************************************************************************/
151768 +typedef struct ioc_fm_pcd_manip_frag_params_t {
151769 + ioc_net_header_type hdr; /**< Header selection */
151770 + union {
151771 +#if (DPAA_VERSION >= 11)
151772 + ioc_fm_pcd_manip_frag_capwap_params_t capwap_frag; /**< Parameters for defining CAPWAP fragmentation,
151773 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
151774 +#endif /* (DPAA_VERSION >= 11) */
151775 + ioc_fm_pcd_manip_frag_ip_params_t ip_frag; /**< Parameters for defining IP fragmentation,
151776 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
151777 + } u;
151778 +} ioc_fm_pcd_manip_frag_params_t;
151779 +
151780 +/**************************************************************************//**
151781 + @Description structure for defining reassemble manipulation
151782 +*//***************************************************************************/
151783 +typedef struct ioc_fm_pcd_manip_reassem_params_t {
151784 + ioc_net_header_type hdr; /**< Header selection */
151785 + union {
151786 +#if (DPAA_VERSION >= 11)
151787 + ioc_fm_pcd_manip_reassem_capwap_params_t capwap_reassem; /**< Parameters for defining CAPWAP reassembly,
151788 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
151789 +#endif /* (DPAA_VERSION >= 11) */
151790 + ioc_fm_pcd_manip_reassem_ip_params_t ip_reassem; /**< Parameters for defining IP reassembly,
151791 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
151792 + } u;
151793 +} ioc_fm_pcd_manip_reassem_params_t;
151794 +
151795 +/**************************************************************************//**
151796 + @Description Parameters for defining a manipulation node
151797 +*//***************************************************************************/
151798 +typedef struct ioc_fm_pcd_manip_params_t {
151799 + ioc_fm_pcd_manip_type type; /**< Selects type of manipulation node */
151800 + union {
151801 + ioc_fm_pcd_manip_hdr_params_t hdr; /**< Parameters for defining header manipulation node */
151802 + ioc_fm_pcd_manip_reassem_params_t reassem;/**< Parameters for defining reassembly manipulation node */
151803 + ioc_fm_pcd_manip_frag_params_t frag; /**< Parameters for defining fragmentation manipulation node */
151804 + ioc_fm_pcd_manip_special_offload_params_t special_offload;/**< Parameters for defining special offload manipulation node */
151805 + } u;
151806 + void *p_next_manip;/**< Handle to another (previously defined) manipulation node;
151807 + Allows concatenation of manipulation actions
151808 + This parameter is optional and may be NULL. */
151809 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
151810 + bool frag_or_reasm;/**< TRUE, if defined fragmentation/reassembly manipulation */
151811 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;/**< Parameters for fragmentation/reassembly manipulation,
151812 + relevant if frag_or_reasm = TRUE */
151813 +#endif /* FM_CAPWAP_SUPPORT */
151814 + void *id;
151815 +} ioc_fm_pcd_manip_params_t;
151816 +
151817 +/**************************************************************************//**
151818 + @Description Structure for retrieving IP reassembly statistics
151819 +*//***************************************************************************/
151820 +typedef struct ioc_fm_pcd_manip_reassem_ip_stats_t {
151821 + /* common counters for both IPv4 and IPv6 */
151822 + uint32_t timeout; /**< Counts the number of TimeOut occurrences */
151823 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
151824 + a Reassembly Frame Descriptor */
151825 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
151826 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
151827 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
151828 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
151829 +#if (DPAA_VERSION >= 11)
151830 + uint32_t non_consistent_sp; /**< Counts the number of Non Consistent Storage Profile events for
151831 + successfully reassembled frames */
151832 +#endif /* (DPAA_VERSION >= 11) */
151833 +struct {
151834 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
151835 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
151836 + have been processed for all frames */
151837 + uint32_t processed_fragments; /**< Counts the number of processed fragments
151838 + (valid and error fragments) for all frames */
151839 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
151840 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
151841 + uint32_t auto_learn_busy; /**< Counts the number of times a busy condition occurs when attempting
151842 + to access an IP-Reassembly Automatic Learning Hash set */
151843 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
151844 + exceeds 16 */
151845 + } specific_hdr_statistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
151846 +} ioc_fm_pcd_manip_reassem_ip_stats_t;
151847 +
151848 +/**************************************************************************//**
151849 + @Description Structure for retrieving IP fragmentation statistics
151850 +*//***************************************************************************/
151851 +typedef struct ioc_fm_pcd_manip_frag_ip_stats_t {
151852 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
151853 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
151854 + uint32_t generated_fragments; /**< Number of fragments that were generated */
151855 +} ioc_fm_pcd_manip_frag_ip_stats_t;
151856 +
151857 +#if (DPAA_VERSION >= 11)
151858 +/**************************************************************************//**
151859 + @Description Structure for retrieving CAPWAP reassembly statistics
151860 +*//***************************************************************************/
151861 +typedef struct ioc_fm_pcd_manip_reassem_capwap_stats_t {
151862 + uint32_t timeout; /**< Counts the number of timeout occurrences */
151863 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
151864 + a Reassembly Frame Descriptor */
151865 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
151866 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
151867 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
151868 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
151869 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
151870 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
151871 + have been processed for all frames */
151872 + uint32_t processed_fragments; /**< Counts the number of processed fragments
151873 + (valid and error fragments) for all frames */
151874 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
151875 + uint32_t autoLearn_busy; /**< Counts the number of times a busy condition occurs when attempting
151876 + to access an Reassembly Automatic Learning Hash set */
151877 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
151878 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
151879 + exceeds 16 */
151880 + uint32_t exceed_max_reassembly_frame_len;/**< ounts the number of times that a successful reassembled frame
151881 + length exceeds MaxReassembledFrameLength value */
151882 +} ioc_fm_pcd_manip_reassem_capwap_stats_t;
151883 +
151884 +/**************************************************************************//**
151885 + @Description Structure for retrieving CAPWAP fragmentation statistics
151886 +*//***************************************************************************/
151887 +typedef struct ioc_fm_pcd_manip_frag_capwap_stats_t {
151888 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
151889 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
151890 + uint32_t generated_fragments; /**< Number of fragments that were generated */
151891 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
151892 + uint8_t sg_allocation_failure; /**< Number of allocation failure of s/g buffers */
151893 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
151894 +} ioc_fm_pcd_manip_frag_capwap_stats_t;
151895 +#endif /* (DPAA_VERSION >= 11) */
151896 +
151897 +/**************************************************************************//**
151898 + @Description Structure for retrieving reassembly statistics
151899 +*//***************************************************************************/
151900 +typedef struct ioc_fm_pcd_manip_reassem_stats_t {
151901 + union {
151902 + ioc_fm_pcd_manip_reassem_ip_stats_t ip_reassem; /**< Structure for IP reassembly statistics */
151903 +#if (DPAA_VERSION >= 11)
151904 + ioc_fm_pcd_manip_reassem_capwap_stats_t capwap_reassem; /**< Structure for CAPWAP reassembly statistics */
151905 +#endif /* (DPAA_VERSION >= 11) */
151906 + } u;
151907 +} ioc_fm_pcd_manip_reassem_stats_t;
151908 +
151909 +/**************************************************************************//**
151910 + @Description structure for retrieving fragmentation statistics
151911 +*//***************************************************************************/
151912 +typedef struct ioc_fm_pcd_manip_frag_stats_t {
151913 + union {
151914 + ioc_fm_pcd_manip_frag_ip_stats_t ip_frag; /**< Structure for IP fragmentation statistics */
151915 +#if (DPAA_VERSION >= 11)
151916 + ioc_fm_pcd_manip_frag_capwap_stats_t capwap_frag; /**< Structure for CAPWAP fragmentation statistics */
151917 +#endif /* (DPAA_VERSION >= 11) */
151918 + } u;
151919 +} ioc_fm_pcd_manip_frag_stats_t;
151920 +
151921 +/**************************************************************************//**
151922 + @Description structure for defining manipulation statistics
151923 +*//***************************************************************************/
151924 +typedef struct ioc_fm_pcd_manip_stats_t {
151925 + union {
151926 + ioc_fm_pcd_manip_reassem_stats_t reassem; /**< Structure for reassembly statistics */
151927 + ioc_fm_pcd_manip_frag_stats_t frag; /**< Structure for fragmentation statistics */
151928 + } u;
151929 +} ioc_fm_pcd_manip_stats_t;
151930 +
151931 +/**************************************************************************//**
151932 + @Description Parameters for acquiring manipulation statistics
151933 +*//***************************************************************************/
151934 +typedef struct ioc_fm_pcd_manip_get_stats_t {
151935 + void *id;
151936 + ioc_fm_pcd_manip_stats_t stats;
151937 +} ioc_fm_pcd_manip_get_stats_t;
151938 +
151939 +#if DPAA_VERSION >= 11
151940 +/**************************************************************************//**
151941 + @Description Parameters for defining frame replicator group and its members
151942 +*//***************************************************************************/
151943 +typedef struct ioc_fm_pcd_frm_replic_group_params_t {
151944 + uint8_t max_num_of_entries; /**< Maximal number of members in the group - must be at least two */
151945 + uint8_t num_of_entries; /**< Number of members in the group - must be at least 1 */
151946 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
151947 + /**< Array of members' parameters */
151948 + void *id;
151949 +} ioc_fm_pcd_frm_replic_group_params_t;
151950 +
151951 +typedef struct ioc_fm_pcd_frm_replic_member_t {
151952 + void *h_replic_group;
151953 + uint16_t member_index;
151954 +} ioc_fm_pcd_frm_replic_member_t;
151955 +
151956 +typedef struct ioc_fm_pcd_frm_replic_member_params_t {
151957 + ioc_fm_pcd_frm_replic_member_t member;
151958 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params;
151959 +} ioc_fm_pcd_frm_replic_member_params_t;
151960 +#endif /* DPAA_VERSION >= 11 */
151961 +
151962 +
151963 +typedef struct ioc_fm_pcd_cc_key_statistics_t {
151964 + uint32_t byte_count; /**< This counter reflects byte count of frames that
151965 + were matched by this key. */
151966 + uint32_t frame_count; /**< This counter reflects count of frames that
151967 + were matched by this key. */
151968 +#if (DPAA_VERSION >= 11)
151969 + uint32_t frame_length_range_count[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
151970 + /**< These counters reflect how many frames matched
151971 + this key in 'RMON' statistics mode:
151972 + Each counter holds the number of frames of a
151973 + specific frames length range, according to the
151974 + ranges provided at initialization. */
151975 +#endif /* (DPAA_VERSION >= 11) */
151976 +} ioc_fm_pcd_cc_key_statistics_t;
151977 +
151978 +
151979 +typedef struct ioc_fm_pcd_cc_tbl_get_stats_t {
151980 + void *id;
151981 + uint16_t key_index;
151982 + ioc_fm_pcd_cc_key_statistics_t statistics;
151983 +} ioc_fm_pcd_cc_tbl_get_stats_t;
151984 +
151985 +/**************************************************************************//**
151986 + @Function FM_PCD_MatchTableGetKeyStatistics
151987 +
151988 + @Description This routine may be used to get statistics counters of specific key
151989 + in a CC Node.
151990 +
151991 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
151992 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
151993 + these counters reflect how many frames passed that were matched
151994 + this key; The total frames count will be returned in the counter
151995 + of the first range (as only one frame length range was defined).
151996 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
151997 + frame count will be separated to frame length counters, based on
151998 + provided frame length ranges.
151999 +
152000 + @Param[in] h_CcNode A handle to the node
152001 + @Param[in] keyIndex Key index for adding
152002 + @Param[out] p_KeyStatistics Key statistics counters
152003 +
152004 + @Return The specific key statistics.
152005 +
152006 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152007 +*//***************************************************************************/
152008 +
152009 +#if defined(CONFIG_COMPAT)
152010 +#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)
152011 +#endif
152012 +#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)
152013 +
152014 +/**************************************************************************//**
152015 + @Function FM_PCD_MatchTableGetMissStatistics
152016 +
152017 + @Description This routine may be used to get statistics counters of miss entry
152018 + in a CC Node.
152019 +
152020 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152021 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152022 + these counters reflect how many frames were not matched to any
152023 + existing key and therefore passed through the miss entry; The
152024 + total frames count will be returned in the counter of the
152025 + first range (as only one frame length range was defined).
152026 +
152027 + @Param[in] h_CcNode A handle to the node
152028 + @Param[out] p_MissStatistics Statistics counters for 'miss'
152029 +
152030 + @Return E_OK on success; Error code otherwise.
152031 +
152032 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152033 +*//***************************************************************************/
152034 +
152035 +#if defined(CONFIG_COMPAT)
152036 +#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)
152037 +#endif
152038 +#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)
152039 +
152040 +/**************************************************************************//**
152041 + @Function FM_PCD_HashTableGetMissStatistics
152042 +
152043 + @Description This routine may be used to get statistics counters of 'miss'
152044 + entry of the a hash table.
152045 +
152046 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152047 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152048 + these counters reflect how many frames were not matched to any
152049 + existing key and therefore passed through the miss entry;
152050 +
152051 + @Param[in] h_HashTbl A handle to a hash table
152052 + @Param[out] p_MissStatistics Statistics counters for 'miss'
152053 +
152054 + @Return E_OK on success; Error code otherwise.
152055 +
152056 + @Cautions Allowed only following FM_PCD_HashTableSet().
152057 +*//***************************************************************************/
152058 +
152059 +#if defined(CONFIG_COMPAT)
152060 +#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)
152061 +#endif
152062 +#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)
152063 +
152064 +
152065 +/**************************************************************************//**
152066 + @Function FM_PCD_NetEnvCharacteristicsSet
152067 +
152068 + @Description Define a set of Network Environment Characteristics.
152069 +
152070 + When setting an environment it is important to understand its
152071 + application. It is not meant to describe the flows that will run
152072 + on the ports using this environment, but what the user means TO DO
152073 + with the PCD mechanisms in order to parse-classify-distribute those
152074 + frames.
152075 + By specifying a distinction unit, the user means it would use that option
152076 + for distinction between frames at either a KeyGen scheme or a coarse
152077 + classification action descriptor. Using interchangeable headers to define a
152078 + unit means that the user is indifferent to which of the interchangeable
152079 + headers is present in the frame, and wants the distinction to be based
152080 + on the presence of either one of them.
152081 +
152082 + Depending on context, there are limitations to the use of environments. A
152083 + port using the PCD functionality is bound to an environment. Some or even
152084 + all ports may share an environment but also an environment per port is
152085 + possible. When initializing a scheme, a classification plan group (see below),
152086 + or a coarse classification tree, one of the initialized environments must be
152087 + stated and related to. When a port is bound to a scheme, a classification
152088 + plan group, or a coarse classification tree, it MUST be bound to the same
152089 + environment.
152090 +
152091 + The different PCD modules, may relate (for flows definition) ONLY on
152092 + distinction units as defined by their environment. When initializing a
152093 + scheme for example, it may not choose to select IPV4 as a match for
152094 + recognizing flows unless it was defined in the relating environment. In
152095 + fact, to guide the user through the configuration of the PCD, each module's
152096 + characterization in terms of flows is not done using protocol names, but using
152097 + environment indexes.
152098 +
152099 + In terms of HW implementation, the list of distinction units sets the LCV vectors
152100 + and later used for match vector, classification plan vectors and coarse classification
152101 + indexing.
152102 +
152103 + @Param[in,out] ioc_fm_pcd_net_env_params_t A structure defining the distiction units for this configuration.
152104 +
152105 + @Return 0 on success; Error code otherwise.
152106 +*//***************************************************************************/
152107 +#if defined(CONFIG_COMPAT)
152108 +#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)
152109 +#endif
152110 +#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)
152111 +
152112 +/**************************************************************************//**
152113 + @Function FM_PCD_NetEnvCharacteristicsDelete
152114 +
152115 + @Description Deletes a set of Network Environment Charecteristics.
152116 +
152117 + @Param[in] ioc_fm_obj_t - The id of a Network Environment object.
152118 +
152119 + @Return 0 on success; Error code otherwise.
152120 +*//***************************************************************************/
152121 +#if defined(CONFIG_COMPAT)
152122 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_compat_fm_obj_t)
152123 +#endif
152124 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_fm_obj_t)
152125 +
152126 +/**************************************************************************//**
152127 + @Function FM_PCD_KgSchemeSet
152128 +
152129 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
152130 + This routine should be called for adding or modifying a scheme.
152131 + When a scheme needs modifying, the API requires that it will be
152132 + rewritten. In such a case 'modify' should be TRUE. If the
152133 + routine is called for a valid scheme and 'modify' is FALSE,
152134 + it will return error.
152135 +
152136 + @Param[in,out] ioc_fm_pcd_kg_scheme_params_t A structure of parameters for defining the scheme
152137 +
152138 + @Return 0 on success; Error code otherwise.
152139 +*//***************************************************************************/
152140 +#if defined(CONFIG_COMPAT)
152141 +#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)
152142 +#endif
152143 +#define FM_PCD_IOC_KG_SCHEME_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_fm_pcd_kg_scheme_params_t)
152144 +
152145 +/**************************************************************************//**
152146 + @Function FM_PCD_KgSchemeDelete
152147 +
152148 + @Description Deleting an initialized scheme.
152149 +
152150 + @Param[in] ioc_fm_obj_t scheme id as initalized by application at FM_PCD_IOC_KG_SET_SCHEME
152151 +
152152 + @Return 0 on success; Error code otherwise.
152153 +*//***************************************************************************/
152154 +#if defined(CONFIG_COMPAT)
152155 +#define FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_compat_fm_obj_t)
152156 +#endif
152157 +#define FM_PCD_IOC_KG_SCHEME_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_fm_obj_t)
152158 +
152159 +/**************************************************************************//**
152160 + @Function FM_PCD_CcRootBuild
152161 +
152162 + @Description This routine must be called to define a complete coarse
152163 + classification tree. This is the way to define coarse
152164 + classification to a certain flow - the KeyGen schemes
152165 + may point only to trees defined in this way.
152166 +
152167 + @Param[in,out] ioc_fm_pcd_cc_tree_params_t A structure of parameters to define the tree.
152168 +
152169 + @Return 0 on success; Error code otherwise.
152170 +*//***************************************************************************/
152171 +#if defined(CONFIG_COMPAT)
152172 +#define FM_PCD_IOC_CC_ROOT_BUILD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), compat_uptr_t)
152173 +#endif
152174 +#define FM_PCD_IOC_CC_ROOT_BUILD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), void *) /* workaround ...*/
152175 +
152176 +/**************************************************************************//**
152177 + @Function FM_PCD_CcRootDelete
152178 +
152179 + @Description Deleting a built tree.
152180 +
152181 + @Param[in] ioc_fm_obj_t - The id of a CC tree.
152182 +*//***************************************************************************/
152183 +#if defined(CONFIG_COMPAT)
152184 +#define FM_PCD_IOC_CC_ROOT_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_compat_fm_obj_t)
152185 +#endif
152186 +#define FM_PCD_IOC_CC_ROOT_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_fm_obj_t)
152187 +
152188 +/**************************************************************************//**
152189 + @Function FM_PCD_MatchTableSet
152190 +
152191 + @Description This routine should be called for each CC (coarse classification)
152192 + node. The whole CC tree should be built bottom up so that each
152193 + node points to already defined nodes. p_NodeId returns the node
152194 + Id to be used by other nodes.
152195 +
152196 + @Param[in,out] ioc_fm_pcd_cc_node_params_t A structure for defining the CC node params
152197 +
152198 + @Return 0 on success; Error code otherwise.
152199 +*//***************************************************************************/
152200 +#if defined(CONFIG_COMPAT)
152201 +#define FM_PCD_IOC_MATCH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), compat_uptr_t)
152202 +#endif
152203 +#define FM_PCD_IOC_MATCH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), void *) /* workaround ...*/
152204 +
152205 +/**************************************************************************//**
152206 + @Function FM_PCD_MatchTableDelete
152207 +
152208 + @Description Deleting a built node.
152209 +
152210 + @Param[in] ioc_fm_obj_t - The id of a CC node.
152211 +
152212 + @Return 0 on success; Error code otherwise.
152213 +*//***************************************************************************/
152214 +#if defined(CONFIG_COMPAT)
152215 +#define FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_compat_fm_obj_t)
152216 +#endif
152217 +#define FM_PCD_IOC_MATCH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_fm_obj_t)
152218 +
152219 +/**************************************************************************//**
152220 + @Function FM_PCD_CcRootModifyNextEngine
152221 +
152222 + @Description Modify the Next Engine Parameters in the entry of the tree.
152223 +
152224 + @Param[in] ioc_fm_pcd_cc_tree_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
152225 +
152226 + @Return 0 on success; Error code otherwise.
152227 +
152228 + @Cautions Allowed only following FM_PCD_CcRootBuild().
152229 +*//***************************************************************************/
152230 +#if defined(CONFIG_COMPAT)
152231 +#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)
152232 +#endif
152233 +#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)
152234 +
152235 +/**************************************************************************//**
152236 + @Function FM_PCD_MatchTableModifyNextEngine
152237 +
152238 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
152239 +
152240 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t A pointer to a structure with the relevant parameters
152241 +
152242 + @Return 0 on success; Error code otherwise.
152243 +
152244 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152245 +*//***************************************************************************/
152246 +#if defined(CONFIG_COMPAT)
152247 +#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)
152248 +#endif
152249 +#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)
152250 +
152251 +/**************************************************************************//**
152252 + @Function FM_PCD_MatchTableModifyMissNextEngine
152253 +
152254 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
152255 +
152256 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
152257 +
152258 + @Return 0 on success; Error code otherwise.
152259 +
152260 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152261 +*//***************************************************************************/
152262 +#if defined(CONFIG_COMPAT)
152263 +#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)
152264 +#endif
152265 +#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)
152266 +
152267 +/**************************************************************************//**
152268 + @Function FM_PCD_MatchTableRemoveKey
152269 +
152270 + @Description Remove the key (including next engine parameters of this key)
152271 + defined by the index of the relevant node.
152272 +
152273 + @Param[in] ioc_fm_pcd_cc_node_remove_key_params_t A pointer to a structure with the relevant parameters
152274 +
152275 + @Return 0 on success; Error code otherwise.
152276 +
152277 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152278 + node and for all of the nodes that lead to it.
152279 +*//***************************************************************************/
152280 +#if defined(CONFIG_COMPAT)
152281 +#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)
152282 +#endif
152283 +#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)
152284 +
152285 +/**************************************************************************//**
152286 + @Function FM_PCD_MatchTableAddKey
152287 +
152288 + @Description Add the key (including next engine parameters of this key in the
152289 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
152290 + may be used when the user doesn't care about the position of the
152291 + key in the table - in that case, the key will be automatically
152292 + added by the driver in the last available entry.
152293 +
152294 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
152295 +
152296 + @Return 0 on success; Error code otherwise.
152297 +
152298 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152299 + node and for all of the nodes that lead to it.
152300 +*//***************************************************************************/
152301 +#if defined(CONFIG_COMPAT)
152302 +#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)
152303 +#endif
152304 +#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)
152305 +
152306 +/**************************************************************************//**
152307 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
152308 +
152309 + @Description Modify the key and Next Engine Parameters of this key in the index defined by key_index.
152310 +
152311 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
152312 +
152313 + @Return 0 on success; Error code otherwise.
152314 +
152315 + @Cautions Allowed only following FM_PCD_MatchTableSet() not only of the relevnt node but also
152316 + the node that points to this node
152317 +*//***************************************************************************/
152318 +#if defined(CONFIG_COMPAT)
152319 +#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)
152320 +#endif
152321 +#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)
152322 +
152323 +/**************************************************************************//**
152324 + @Function FM_PCD_MatchTableModifyKey
152325 +
152326 + @Description Modify the key at the index defined by key_index.
152327 +
152328 + @Param[in] ioc_fm_pcd_cc_node_modify_key_params_t - Pointer to a structure with the relevant parameters
152329 +
152330 + @Return 0 on success; Error code otherwise.
152331 +
152332 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152333 + node and for all of the nodes that lead to it.
152334 +*//***************************************************************************/
152335 +#if defined(CONFIG_COMPAT)
152336 +#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)
152337 +#endif
152338 +#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)
152339 +
152340 +/**************************************************************************//**
152341 + @Function FM_PCD_HashTableSet
152342 +
152343 + @Description This routine initializes a hash table structure.
152344 + KeyGen hash result determines the hash bucket.
152345 + Next, KeyGen key is compared against all keys of this
152346 + bucket (exact match).
152347 + Number of sets (number of buckets) of the hash equals to the
152348 + number of 1-s in 'hash_res_mask' in the provided parameters.
152349 + Number of hash table ways is then calculated by dividing
152350 + 'max_num_of_keys' equally between the hash sets. This is the maximal
152351 + number of keys that a hash bucket may hold.
152352 + The hash table is initialized empty and keys may be
152353 + added to it following the initialization. Keys masks are not
152354 + supported in current hash table implementation.
152355 + The initialized hash table can be integrated as a node in a
152356 + CC tree.
152357 +
152358 + @Param[in,out] ioc_fm_pcd_hash_table_params_t - Pointer to a structure with the relevant parameters
152359 +
152360 + @Return 0 on success; Error code otherwise.
152361 +*//***************************************************************************/
152362 +#if defined(CONFIG_COMPAT)
152363 +#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)
152364 +#endif
152365 +#define FM_PCD_IOC_HASH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_pcd_hash_table_params_t)
152366 +
152367 +
152368 +/**************************************************************************//**
152369 + @Function FM_PCD_HashTableDelete
152370 +
152371 + @Description This routine deletes the provided hash table and released all
152372 + its allocated resources.
152373 +
152374 + @Param[in] ioc_fm_obj_t - The ID of a hash table.
152375 +
152376 + @Return 0 on success; Error code otherwise.
152377 +
152378 + @Cautions Allowed only following FM_PCD_HashTableSet().
152379 +*//***************************************************************************/
152380 +#if defined(CONFIG_COMPAT)
152381 +#define FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_obj_t)
152382 +#endif
152383 +#define FM_PCD_IOC_HASH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_obj_t)
152384 +
152385 +/**************************************************************************//**
152386 + @Function FM_PCD_HashTableAddKey
152387 +
152388 + @Description This routine adds the provided key (including next engine
152389 + parameters of this key) to the hash table.
152390 + The key is added as the last key of the bucket that it is
152391 + mapped to.
152392 +
152393 + @Param[in] ioc_fm_pcd_hash_table_add_key_params_t - Pointer to a structure with the relevant parameters
152394 +
152395 + @Return 0 on success; error code otherwise.
152396 +
152397 + @Cautions Allowed only following FM_PCD_HashTableSet().
152398 +*//***************************************************************************/
152399 +#if defined(CONFIG_COMPAT)
152400 +#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)
152401 +#endif
152402 +#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)
152403 +
152404 +/**************************************************************************//**
152405 + @Function FM_PCD_HashTableRemoveKey
152406 +
152407 + @Description This routine removes the requested key (including next engine
152408 + parameters of this key) from the hash table.
152409 +
152410 + @Param[in] ioc_fm_pcd_hash_table_remove_key_params_t - Pointer to a structure with the relevant parameters
152411 +
152412 + @Return 0 on success; Error code otherwise.
152413 +
152414 + @Cautions Allowed only following FM_PCD_HashTableSet().
152415 +*//***************************************************************************/
152416 +#if defined(CONFIG_COMPAT)
152417 +#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)
152418 +#endif
152419 +#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)
152420 +
152421 +/**************************************************************************//**
152422 + @Function FM_PCD_PlcrProfileSet
152423 +
152424 + @Description Sets a profile entry in the policer profile table.
152425 + The routine overrides any existing value.
152426 +
152427 + @Param[in,out] ioc_fm_pcd_plcr_profile_params_t A structure of parameters for defining a
152428 + policer profile entry.
152429 +
152430 + @Return 0 on success; Error code otherwise.
152431 +*//***************************************************************************/
152432 +#if defined(CONFIG_COMPAT)
152433 +#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)
152434 +#endif
152435 +#define FM_PCD_IOC_PLCR_PROFILE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_pcd_plcr_profile_params_t)
152436 +
152437 +/**************************************************************************//**
152438 + @Function FM_PCD_PlcrProfileDelete
152439 +
152440 + @Description Delete a profile entry in the policer profile table.
152441 + The routine set entry to invalid.
152442 +
152443 + @Param[in] ioc_fm_obj_t The id of a policer profile.
152444 +
152445 + @Return 0 on success; Error code otherwise.
152446 +*//***************************************************************************/
152447 +#if defined(CONFIG_COMPAT)
152448 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_obj_t)
152449 +#endif
152450 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_obj_t)
152451 +
152452 +/**************************************************************************//**
152453 + @Function FM_PCD_ManipNodeSet
152454 +
152455 + @Description This routine should be called for defining a manipulation
152456 + node. A manipulation node must be defined before the CC node
152457 + that precedes it.
152458 +
152459 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
152460 +
152461 + @Return A handle to the initialized object on success; NULL code otherwise.
152462 +*//***************************************************************************/
152463 +#if defined(CONFIG_COMPAT)
152464 +#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)
152465 +#endif
152466 +#define FM_PCD_IOC_MANIP_NODE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_fm_pcd_manip_params_t)
152467 +
152468 +/**************************************************************************//**
152469 + @Function FM_PCD_ManipNodeReplace
152470 +
152471 + @Description Change existing manipulation node to be according to new requirement.
152472 + (Here, it's implemented as a variant of the same IOCTL as for
152473 + FM_PCD_ManipNodeSet(), and one that when called, the 'id' member
152474 + in its 'ioc_fm_pcd_manip_params_t' argument is set to contain
152475 + the manip node's handle)
152476 +
152477 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
152478 +
152479 + @Return 0 on success; error code otherwise.
152480 +
152481 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152482 +*//***************************************************************************/
152483 +#if defined(CONFIG_COMPAT)
152484 +#define FM_PCD_IOC_MANIP_NODE_REPLACE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
152485 +#endif
152486 +#define FM_PCD_IOC_MANIP_NODE_REPLACE FM_PCD_IOC_MANIP_NODE_SET
152487 +
152488 +/**************************************************************************//**
152489 + @Function FM_PCD_ManipNodeDelete
152490 +
152491 + @Description Delete an existing manipulation node.
152492 +
152493 + @Param[in] ioc_fm_obj_t The id of the manipulation node to delete.
152494 +
152495 + @Return 0 on success; error code otherwise.
152496 +
152497 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152498 +*//***************************************************************************/
152499 +#if defined(CONFIG_COMPAT)
152500 +#define FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_compat_fm_obj_t)
152501 +#endif
152502 +#define FM_PCD_IOC_MANIP_NODE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_fm_obj_t)
152503 +
152504 +/**************************************************************************//**
152505 + @Function FM_PCD_ManipGetStatistics
152506 +
152507 + @Description Retrieve the manipulation statistics.
152508 +
152509 + @Param[in] h_ManipNode A handle to a manipulation node.
152510 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
152511 +
152512 + @Return E_OK on success; Error code otherwise.
152513 +
152514 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152515 +*//***************************************************************************/
152516 +#if defined(CONFIG_COMPAT)
152517 +#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)
152518 +#endif
152519 +#define FM_PCD_IOC_MANIP_GET_STATS _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_fm_pcd_manip_get_stats_t)
152520 +
152521 +/**************************************************************************//**
152522 +@Function FM_PCD_SetAdvancedOffloadSupport
152523 +
152524 +@Description This routine must be called in order to support the following features:
152525 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
152526 +
152527 +@Param[in] h_FmPcd FM PCD module descriptor.
152528 +
152529 +@Return 0 on success; error code otherwise.
152530 +
152531 +@Cautions Allowed only when PCD is disabled.
152532 +*//***************************************************************************/
152533 +#define FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45))
152534 +
152535 +#if (DPAA_VERSION >= 11)
152536 +/**************************************************************************//**
152537 + @Function FM_PCD_FrmReplicSetGroup
152538 +
152539 + @Description Initialize a Frame Replicator group.
152540 +
152541 + @Param[in] h_FmPcd FM PCD module descriptor.
152542 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
152543 + the frame replicator group.
152544 +
152545 + @Return A handle to the initialized object on success; NULL code otherwise.
152546 +
152547 + @Cautions Allowed only following FM_PCD_Init().
152548 +*//***************************************************************************/
152549 +#if defined(CONFIG_COMPAT)
152550 +#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)
152551 +#endif
152552 +#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)
152553 +
152554 +/**************************************************************************//**
152555 + @Function FM_PCD_FrmReplicDeleteGroup
152556 +
152557 + @Description Delete a Frame Replicator group.
152558 +
152559 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152560 +
152561 + @Return E_OK on success; Error code otherwise.
152562 +
152563 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
152564 +*//***************************************************************************/
152565 +#if defined(CONFIG_COMPAT)
152566 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_compat_fm_obj_t)
152567 +#endif
152568 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_fm_obj_t)
152569 +
152570 +/**************************************************************************//**
152571 + @Function FM_PCD_FrmReplicAddMember
152572 +
152573 + @Description Add the member in the index defined by the memberIndex.
152574 +
152575 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152576 + @Param[in] memberIndex member index for adding.
152577 + @Param[in] p_MemberParams A pointer to the new member parameters.
152578 +
152579 + @Return E_OK on success; Error code otherwise.
152580 +
152581 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
152582 +*//***************************************************************************/
152583 +#if defined(CONFIG_COMPAT)
152584 +#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)
152585 +#endif
152586 +#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)
152587 +
152588 +/**************************************************************************//**
152589 + @Function FM_PCD_FrmReplicRemoveMember
152590 +
152591 + @Description Remove the member defined by the index from the relevant group.
152592 +
152593 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152594 + @Param[in] memberIndex member index for removing.
152595 +
152596 + @Return E_OK on success; Error code otherwise.
152597 +
152598 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
152599 +*//***************************************************************************/
152600 +#if defined(CONFIG_COMPAT)
152601 +#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)
152602 +#endif
152603 +#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)
152604 +
152605 +#endif
152606 +
152607 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152608 +/**************************************************************************//**
152609 + @Function FM_PCD_StatisticsSetNode
152610 +
152611 + @Description This routine should be called for defining a statistics node.
152612 +
152613 + @Param[in,out] ioc_fm_pcd_stats_params_t A structure of parameters defining the statistics
152614 +
152615 + @Return 0 on success; Error code otherwise.
152616 +*//***************************************************************************/
152617 +#if defined(CONFIG_COMPAT)
152618 +#define FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
152619 +#endif
152620 +#define FM_PCD_IOC_STATISTICS_SET_NODE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
152621 +
152622 +#endif /* FM_CAPWAP_SUPPORT */
152623 +
152624 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
152625 +#if defined(CONFIG_COMPAT)
152626 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS_COMPAT \
152627 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT
152628 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS_COMPAT \
152629 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT
152630 +#define FM_PCD_IOC_KG_SET_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_SET_COMPAT
152631 +#define FM_PCD_IOC_KG_DEL_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT
152632 +#define FM_PCD_IOC_CC_BUILD_TREE_COMPAT FM_PCD_IOC_CC_ROOT_BUILD_COMPAT
152633 +#define FM_PCD_IOC_CC_DELETE_TREE_COMPAT FM_PCD_IOC_CC_ROOT_DELETE_COMPAT
152634 +#define FM_PCD_IOC_CC_DELETE_NODE_COMPAT FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT
152635 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE_COMPAT \
152636 + FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT
152637 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE_COMPAT \
152638 + FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT
152639 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE_COMPAT \
152640 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT
152641 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT
152642 +#define FM_PCD_IOC_CC_NODE_ADD_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT
152643 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT \
152644 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT
152645 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT
152646 +#define FM_PCD_IOC_PLCR_SET_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT
152647 +#define FM_PCD_IOC_PLCR_DEL_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT
152648 +#define FM_PCD_IOC_MANIP_SET_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
152649 +#define FM_PCD_IOC_MANIP_DELETE_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT
152650 +#endif
152651 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET
152652 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS \
152653 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE
152654 +#define FM_PCD_IOC_KG_SET_SCHEME FM_PCD_IOC_KG_SCHEME_SET
152655 +#define FM_PCD_IOC_KG_DEL_SCHEME FM_PCD_IOC_KG_SCHEME_DELETE
152656 +#define FM_PCD_IOC_CC_BUILD_TREE FM_PCD_IOC_CC_ROOT_BUILD
152657 +#define FM_PCD_IOC_CC_DELETE_TREE FM_PCD_IOC_CC_ROOT_DELETE
152658 +#define FM_PCD_IOC_CC_DELETE_NODE FM_PCD_IOC_MATCH_TABLE_DELETE
152659 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE
152660 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE
152661 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE \
152662 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE
152663 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY
152664 +#define FM_PCD_IOC_CC_NODE_ADD_KEY FM_PCD_IOC_MATCH_TABLE_ADD_KEY
152665 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE \
152666 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE
152667 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY
152668 +#define FM_PCD_IOC_PLCR_SET_PROFILE FM_PCD_IOC_PLCR_PROFILE_SET
152669 +#define FM_PCD_IOC_PLCR_DEL_PROFILE FM_PCD_IOC_PLCR_PROFILE_DELETE
152670 +#define FM_PCD_IOC_MANIP_SET_NODE FM_PCD_IOC_MANIP_NODE_SET
152671 +#define FM_PCD_IOC_MANIP_DELETE_NODE FM_PCD_IOC_MANIP_NODE_DELETE
152672 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
152673 +
152674 +#endif /* __FM_PCD_IOCTLS_H */
152675 +/** @} */ /* end of lnx_ioctl_FM_PCD_Runtime_grp group */
152676 +/** @} */ /* end of lnx_ioctl_FM_PCD_grp group */
152677 +/** @} */ /* end of lnx_ioctl_FM_grp group */
152678 --- /dev/null
152679 +++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
152680 @@ -0,0 +1,973 @@
152681 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
152682 + * All rights reserved.
152683 + *
152684 + * Redistribution and use in source and binary forms, with or without
152685 + * modification, are permitted provided that the following conditions are met:
152686 + * * Redistributions of source code must retain the above copyright
152687 + * notice, this list of conditions and the following disclaimer.
152688 + * * Redistributions in binary form must reproduce the above copyright
152689 + * notice, this list of conditions and the following disclaimer in the
152690 + * documentation and/or other materials provided with the distribution.
152691 + * * Neither the name of Freescale Semiconductor nor the
152692 + * names of its contributors may be used to endorse or promote products
152693 + * derived from this software without specific prior written permission.
152694 + *
152695 + *
152696 + * ALTERNATIVELY, this software may be distributed under the terms of the
152697 + * GNU General Public License ("GPL") as published by the Free Software
152698 + * Foundation, either version 2 of that License or (at your option) any
152699 + * later version.
152700 + *
152701 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
152702 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
152703 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
152704 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
152705 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
152706 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
152707 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
152708 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
152709 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
152710 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
152711 + */
152712 +
152713 +/******************************************************************************
152714 + @File fm_port_ioctls.h
152715 +
152716 + @Description FM Port routines
152717 +*//***************************************************************************/
152718 +#ifndef __FM_PORT_IOCTLS_H
152719 +#define __FM_PORT_IOCTLS_H
152720 +
152721 +#include "enet_ext.h"
152722 +#include "net_ioctls.h"
152723 +#include "fm_ioctls.h"
152724 +#include "fm_pcd_ioctls.h"
152725 +
152726 +
152727 +/**************************************************************************//**
152728 +
152729 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
152730 +
152731 + @Description FM Linux ioctls definitions and enums
152732 +
152733 + @{
152734 +*//***************************************************************************/
152735 +
152736 +/**************************************************************************//**
152737 + @Group lnx_ioctl_FM_PORT_grp FM Port
152738 +
152739 + @Description FM Port API
152740 +
152741 + The FM uses a general module called "port" to represent a Tx port
152742 + (MAC), an Rx port (MAC), offline parsing flow or host command
152743 + flow. There may be up to 17 (may change) ports in an FM - 5 Tx
152744 + ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7
152745 + Host command/Offline parsing ports. The SW driver manages these
152746 + ports as sub-modules of the FM, i.e. after an FM is initialized,
152747 + its ports may be initialized and operated upon.
152748 +
152749 + The port is initialized aware of its type, but other functions on
152750 + a port may be indifferent to its type. When necessary, the driver
152751 + verifies coherency and returns error if applicable.
152752 +
152753 + On initialization, user specifies the port type and it's index
152754 + (relative to the port's type). Host command and Offline parsing
152755 + ports share the same id range, I.e user may not initialized host
152756 + command port 0 and offline parsing port 0.
152757 +
152758 + @{
152759 +*//***************************************************************************/
152760 +
152761 +/**************************************************************************//**
152762 + @Description An enum for defining port PCD modes.
152763 + (Must match enum e_FmPortPcdSupport defined in fm_port_ext.h)
152764 +
152765 + This enum defines the superset of PCD engines support - i.e. not
152766 + all engines have to be used, but all have to be enabled. The real
152767 + flow of a specific frame depends on the PCD configuration and the
152768 + frame headers and payload.
152769 + Note: the first engine and the first engine after the parser (if
152770 + exists) should be in order, the order is important as it will
152771 + define the flow of the port. However, as for the rest engines
152772 + (the ones that follows), the order is not important anymore as
152773 + it is defined by the PCD graph itself.
152774 +*//***************************************************************************/
152775 +typedef enum ioc_fm_port_pcd_support {
152776 + e_IOC_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
152777 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
152778 + , e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
152779 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
152780 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
152781 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
152782 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
152783 + /**< Use all PCD engines */
152784 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
152785 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
152786 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
152787 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
152788 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152789 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
152790 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
152791 +#endif /* FM_CAPWAP_SUPPORT */
152792 +} ioc_fm_port_pcd_support;
152793 +
152794 +
152795 +/**************************************************************************//**
152796 + @Collection FM Frame error
152797 +*//***************************************************************************/
152798 +typedef uint32_t ioc_fm_port_frame_err_select_t; /**< typedef for defining Frame Descriptor errors */
152799 +
152800 +/* @} */
152801 +
152802 +
152803 +/**************************************************************************//**
152804 + @Description An enum for defining Dual Tx rate limiting scale.
152805 + (Must match e_FmPortDualRateLimiterScaleDown defined in fm_port_ext.h)
152806 +*//***************************************************************************/
152807 +typedef enum ioc_fm_port_dual_rate_limiter_scale_down {
152808 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
152809 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
152810 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
152811 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
152812 +} ioc_fm_port_dual_rate_limiter_scale_down;
152813 +
152814 +/**************************************************************************//**
152815 + @Description A structure for defining Tx rate limiting
152816 + (Must match struct t_FmPortRateLimit defined in fm_port_ext.h)
152817 +*//***************************************************************************/
152818 +typedef struct ioc_fm_port_rate_limit_t {
152819 + uint16_t max_burst_size; /**< in KBytes for Tx ports, in frames
152820 + for offline parsing ports. (note that
152821 + for early chips burst size is
152822 + rounded up to a multiply of 1000 frames).*/
152823 + uint32_t rate_limit; /**< in Kb/sec for Tx ports, in frame/sec for
152824 + offline parsing ports. Rate limit refers to
152825 + data rate (rather than line rate). */
152826 + ioc_fm_port_dual_rate_limiter_scale_down rate_limit_divider; /**< For offline parsing ports only. Not-valid
152827 + for some earlier chip revisions */
152828 +} ioc_fm_port_rate_limit_t;
152829 +
152830 +
152831 +
152832 +/**************************************************************************//**
152833 + @Group lnx_ioctl_FM_PORT_runtime_control_grp FM Port Runtime Control Unit
152834 +
152835 + @Description FM Port Runtime control unit API functions, definitions and enums.
152836 +
152837 + @{
152838 +*//***************************************************************************/
152839 +
152840 +/**************************************************************************//**
152841 + @Description An enum for defining FM Port counters.
152842 + (Must match enum e_FmPortCounters defined in fm_port_ext.h)
152843 +*//***************************************************************************/
152844 +typedef enum ioc_fm_port_counters {
152845 + e_IOC_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
152846 + e_IOC_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
152847 + e_IOC_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
152848 + e_IOC_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
152849 + e_IOC_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
152850 + e_IOC_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
152851 + e_IOC_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
152852 + e_IOC_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
152853 + e_IOC_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
152854 + e_IOC_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
152855 + e_IOC_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
152856 + e_IOC_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
152857 + e_IOC_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
152858 + e_IOC_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
152859 + e_IOC_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
152860 + e_IOC_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
152861 + e_IOC_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
152862 + e_IOC_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
152863 + e_IOC_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
152864 + e_IOC_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
152865 + e_IOC_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
152866 + e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
152867 +} ioc_fm_port_counters;
152868 +
152869 +typedef struct ioc_fm_port_bmi_stats_t {
152870 + uint32_t cnt_cycle;
152871 + uint32_t cnt_task_util;
152872 + uint32_t cnt_queue_util;
152873 + uint32_t cnt_dma_util;
152874 + uint32_t cnt_fifo_util;
152875 + uint32_t cnt_rx_pause_activation;
152876 + uint32_t cnt_frame;
152877 + uint32_t cnt_discard_frame;
152878 + uint32_t cnt_dealloc_buf;
152879 + uint32_t cnt_rx_bad_frame;
152880 + uint32_t cnt_rx_large_frame;
152881 + uint32_t cnt_rx_filter_frame;
152882 + uint32_t cnt_rx_list_dma_err;
152883 + uint32_t cnt_rx_out_of_buffers_discard;
152884 + uint32_t cnt_wred_discard;
152885 + uint32_t cnt_length_err;
152886 + uint32_t cnt_unsupported_format;
152887 +} ioc_fm_port_bmi_stats_t;
152888 +
152889 +/**************************************************************************//**
152890 + @Description Structure for Port id parameters.
152891 + (Description may be inaccurate;
152892 + must match struct t_FmPortCongestionGrps defined in fm_port_ext.h)
152893 +
152894 + Fields commented 'IN' are passed by the port module to be used
152895 + by the FM module.
152896 + Fields commented 'OUT' will be filled by FM before returning to port.
152897 +*//***************************************************************************/
152898 +typedef struct ioc_fm_port_congestion_groups_t {
152899 + uint16_t num_of_congestion_grps_to_consider; /**< The number of required congestion groups
152900 + to define the size of the following array */
152901 + uint8_t congestion_grps_to_consider [FM_PORT_NUM_OF_CONGESTION_GRPS];
152902 + /**< An array of CG indexes;
152903 + Note that the size of the array should be
152904 + 'num_of_congestion_grps_to_consider'. */
152905 +#if DPAA_VERSION >= 11
152906 + bool pfc_priorities_enable[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
152907 + /**< A matrix that represents the map between the CG ids
152908 + defined in 'congestion_grps_to_consider' to the priorities
152909 + mapping array. */
152910 +#endif /* DPAA_VERSION >= 11 */
152911 +} ioc_fm_port_congestion_groups_t;
152912 +
152913 +
152914 +
152915 +/**************************************************************************//**
152916 + @Function FM_PORT_Disable
152917 +
152918 + @Description Gracefully disable an FM port. The port will not start new tasks after all
152919 + tasks associated with the port are terminated.
152920 +
152921 + @Return 0 on success; error code otherwise.
152922 +
152923 + @Cautions This is a blocking routine, it returns after port is
152924 + gracefully stopped, i.e. the port will not except new frames,
152925 + but it will finish all frames or tasks which were already began
152926 +*//***************************************************************************/
152927 +#define FM_PORT_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(1))
152928 +
152929 +/**************************************************************************//**
152930 + @Function FM_PORT_Enable
152931 +
152932 + @Description A runtime routine provided to allow disable/enable of port.
152933 +
152934 + @Return 0 on success; error code otherwise.
152935 +*//***************************************************************************/
152936 +#define FM_PORT_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(2))
152937 +
152938 +/**************************************************************************//**
152939 + @Function FM_PORT_SetRateLimit
152940 +
152941 + @Description Calling this routine enables rate limit algorithm.
152942 + By default, this functionality is disabled.
152943 + Note that rate-limit mechanism uses the FM time stamp.
152944 + The selected rate limit specified here would be
152945 + rounded DOWN to the nearest 16M.
152946 +
152947 + May be used for Tx and offline parsing ports only
152948 +
152949 + @Param[in] ioc_fm_port_rate_limit A structure of rate limit parameters
152950 +
152951 + @Return 0 on success; error code otherwise.
152952 +*//***************************************************************************/
152953 +#define FM_PORT_IOC_SET_RATE_LIMIT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(3), ioc_fm_port_rate_limit_t)
152954 +
152955 +/**************************************************************************//**
152956 + @Function FM_PORT_DeleteRateLimit
152957 +
152958 + @Description Calling this routine disables the previously enabled rate limit.
152959 +
152960 + May be used for Tx and offline parsing ports only
152961 +
152962 + @Return 0 on success; error code otherwise.
152963 +*//***************************************************************************/
152964 +#define FM_PORT_IOC_DELETE_RATE_LIMIT _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(5))
152965 +#define FM_PORT_IOC_REMOVE_RATE_LIMIT FM_PORT_IOC_DELETE_RATE_LIMIT
152966 +
152967 +
152968 +/**************************************************************************//**
152969 + @Function FM_PORT_AddCongestionGrps
152970 +
152971 + @Description This routine effects the corresponding Tx port.
152972 + It should be called in order to enable pause
152973 + frame transmission in case of congestion in one or more
152974 + of the congestion groups relevant to this port.
152975 + Each call to this routine may add one or more congestion
152976 + groups to be considered relevant to this port.
152977 +
152978 + May be used for Rx, or RX+OP ports only (depending on chip)
152979 +
152980 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
152981 + congestion group ids to consider.
152982 +
152983 + @Return 0 on success; error code otherwise.
152984 +*//***************************************************************************/
152985 +#define FM_PORT_IOC_ADD_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(34), ioc_fm_port_congestion_groups_t)
152986 +
152987 +/**************************************************************************//**
152988 + @Function FM_PORT_RemoveCongestionGrps
152989 +
152990 + @Description This routine effects the corresponding Tx port. It should be
152991 + called when congestion groups were
152992 + defined for this port and are no longer relevant, or pause
152993 + frames transmitting is not required on their behalf.
152994 + Each call to this routine may remove one or more congestion
152995 + groups to be considered relevant to this port.
152996 +
152997 + May be used for Rx, or RX+OP ports only (depending on chip)
152998 +
152999 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
153000 + congestion group ids to consider.
153001 +
153002 + @Return 0 on success; error code otherwise.
153003 +*//***************************************************************************/
153004 +#define FM_PORT_IOC_REMOVE_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(35), ioc_fm_port_congestion_groups_t)
153005 +
153006 +/**************************************************************************//**
153007 + @Function FM_PORT_SetErrorsRoute
153008 +
153009 + @Description Errors selected for this routine will cause a frame with that error
153010 + to be enqueued to error queue.
153011 + Errors not selected for this routine will cause a frame with that error
153012 + to be enqueued to the one of the other port queues.
153013 + By default all errors are defined to be enqueued to error queue.
153014 + Errors that were configured to be discarded (at initialization)
153015 + may not be selected here.
153016 +
153017 + May be used for Rx and offline parsing ports only
153018 +
153019 + @Param[in] ioc_fm_port_frame_err_select_t A list of errors to enqueue to error queue
153020 +
153021 + @Return 0 on success; error code otherwise.
153022 +
153023 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
153024 + (szbs001: How is it possible to have one function that needs to be
153025 + called BEFORE FM_PORT_Init() implemented as an ioctl,
153026 + which will ALWAYS be called AFTER the FM_PORT_Init()
153027 + for that port!?!?!?!???!?!??!?!?)
153028 +*//***************************************************************************/
153029 +#define FM_PORT_IOC_SET_ERRORS_ROUTE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(4), ioc_fm_port_frame_err_select_t)
153030 +
153031 +
153032 +/**************************************************************************//**
153033 + @Group lnx_ioctl_FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
153034 +
153035 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
153036 +
153037 + @{
153038 +*//***************************************************************************/
153039 +
153040 +/**************************************************************************//**
153041 + @Description A structure defining the KG scheme after the parser.
153042 + (Must match struct t_FmPcdKgSchemeSelect defined in fm_port_ext.h)
153043 +
153044 + This is relevant only to change scheme selection mode - from
153045 + direct to indirect and vice versa, or when the scheme is selected directly,
153046 + to select the scheme id.
153047 +
153048 +*//***************************************************************************/
153049 +typedef struct ioc_fm_pcd_kg_scheme_select_t {
153050 + bool direct; /**< TRUE to use 'scheme_id' directly, FALSE to use LCV.*/
153051 + void *scheme_id; /**< Relevant for 'direct'=TRUE only.
153052 + 'scheme_id' selects the scheme after parser. */
153053 +} ioc_fm_pcd_kg_scheme_select_t;
153054 +
153055 +/**************************************************************************//**
153056 + @Description Scheme IDs structure
153057 + (Must match struct t_FmPcdPortSchemesParams defined in fm_port_ext.h)
153058 +*//***************************************************************************/
153059 +typedef struct ioc_fm_pcd_port_schemes_params_t {
153060 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
153061 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'num_of_schemes' schemes for the
153062 + port to be bound to */
153063 +} ioc_fm_pcd_port_schemes_params_t;
153064 +
153065 +/**************************************************************************//**
153066 + @Description A union for defining port protocol parameters for parser
153067 + (Must match union u_FmPcdHdrPrsOpts defined in fm_port_ext.h)
153068 +*//***************************************************************************/
153069 +typedef union ioc_fm_pcd_hdr_prs_opts_u {
153070 + /* MPLS */
153071 + struct {
153072 + bool label_interpretation_enable;/**< When this bit is set, the last MPLS label will be
153073 + interpreted as described in HW spec table. When the bit
153074 + is cleared, the parser will advance to MPLS next parse */
153075 + ioc_net_header_type next_parse; /**< must be equal or higher than IPv4 */
153076 + } mpls_prs_options;
153077 +
153078 + /* VLAN */
153079 + struct {
153080 + uint16_t tag_protocol_id1; /**< User defined Tag Protocol Identifier, to be recognized
153081 + on VLAN TAG on top of 0x8100 and 0x88A8 */
153082 + uint16_t tag_protocol_id2; /**< User defined Tag Protocol Identifier, to be recognized
153083 + on VLAN TAG on top of 0x8100 and 0x88A8 */
153084 + } vlan_prs_options;
153085 +
153086 + /* PPP */
153087 + struct{
153088 + bool enable_mtu_check; /**< Check validity of MTU according to RFC2516 */
153089 + } pppoe_prs_options;
153090 +
153091 + /* IPV6 */
153092 + struct {
153093 + bool routing_hdr_disable; /**< Disable routing header */
153094 + } ipv6_prs_options;
153095 +
153096 + /* UDP */
153097 + struct {
153098 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
153099 + } udp_prs_options;
153100 +
153101 + /* TCP */
153102 + struct {
153103 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
153104 + } tcp_prs_options;
153105 +} ioc_fm_pcd_hdr_prs_opts_u;
153106 +
153107 +/**************************************************************************//**
153108 + @Description A structure for defining each header for the parser
153109 + (must match struct t_FmPcdPrsAdditionalHdrParams defined in fm_port_ext.h)
153110 +*//***************************************************************************/
153111 +typedef struct ioc_fm_pcd_prs_additional_hdr_params_t {
153112 + ioc_net_header_type hdr; /**< Selected header */
153113 + bool err_disable; /**< TRUE to disable error indication */
153114 + bool soft_prs_enable; /**< Enable jump to SW parser when this
153115 + header is recognized by the HW parser. */
153116 + uint8_t index_per_hdr; /**< Normally 0, if more than one sw parser
153117 + attachments exists for the same header,
153118 + (in the main sw parser code) use this
153119 + index to distinguish between them. */
153120 + bool use_prs_opts; /**< TRUE to use parser options. */
153121 + ioc_fm_pcd_hdr_prs_opts_u prs_opts; /**< A unuion according to header type,
153122 + defining the parser options selected.*/
153123 +} ioc_fm_pcd_prs_additional_hdr_params_t;
153124 +
153125 +/**************************************************************************//**
153126 + @Description A structure for defining port PCD parameters
153127 + (Must match t_FmPortPcdPrsParams defined in fm_port_ext.h)
153128 +*//***************************************************************************/
153129 +typedef struct ioc_fm_port_pcd_prs_params_t {
153130 + uint8_t prs_res_priv_info; /**< The private info provides a method of inserting
153131 + port information into the parser result. This information
153132 + may be extracted by KeyGen and be used for frames
153133 + distribution when a per-port distinction is required,
153134 + it may also be used as a port logical id for analyzing
153135 + incoming frames. */
153136 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to start parsing */
153137 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at 'parsing_offset' */
153138 + bool include_in_prs_statistics; /**< TRUE to include this port in the parser statistics */
153139 + uint8_t num_of_hdrs_with_additional_params;
153140 + /**< Normally 0, some headers may get special parameters */
153141 + ioc_fm_pcd_prs_additional_hdr_params_t additional_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
153142 + /**< 'num_of_hdrs_with_additional_params' structures
153143 + additional parameters for each header that requires them */
153144 + bool set_vlan_tpid1; /**< TRUE to configure user selection of Ethertype to
153145 + indicate a VLAN tag (in addition to the TPID values
153146 + 0x8100 and 0x88A8). */
153147 + uint16_t vlan_tpid1; /**< extra tag to use if set_vlan_tpid1=TRUE. */
153148 + bool set_vlan_tpid2; /**< TRUE to configure user selection of Ethertype to
153149 + indicate a VLAN tag (in addition to the TPID values
153150 + 0x8100 and 0x88A8). */
153151 + uint16_t vlan_tpid2; /**< extra tag to use if set_vlan_tpid1=TRUE. */
153152 +} ioc_fm_port_pcd_prs_params_t;
153153 +
153154 +/**************************************************************************//**
153155 + @Description A structure for defining coarse alassification parameters
153156 + (Must match t_FmPortPcdCcParams defined in fm_port_ext.h)
153157 +*//***************************************************************************/
153158 +typedef struct ioc_fm_port_pcd_cc_params_t {
153159 + void *cc_tree_id; /**< CC tree id */
153160 +} ioc_fm_port_pcd_cc_params_t;
153161 +
153162 +/**************************************************************************//**
153163 + @Description A structure for defining keygen parameters
153164 + (Must match t_FmPortPcdKgParams defined in fm_port_ext.h)
153165 +*//***************************************************************************/
153166 +typedef struct ioc_fm_port_pcd_kg_params_t {
153167 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
153168 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
153169 + /**< Array of 'num_of_schemes' schemes for the
153170 + port to be bound to */
153171 + bool direct_scheme; /**< TRUE for going from parser to a specific scheme,
153172 + regardless of parser result */
153173 + void *direct_scheme_id; /**< Scheme id, as returned by FM_PCD_KgSetScheme;
153174 + relevant only if direct=TRUE. */
153175 +} ioc_fm_port_pcd_kg_params_t;
153176 +
153177 +/**************************************************************************//**
153178 + @Description A structure for defining policer parameters
153179 + (Must match t_FmPortPcdPlcrParams defined in fm_port_ext.h)
153180 +*//***************************************************************************/
153181 +typedef struct ioc_fm_port_pcd_plcr_params_t {
153182 + void *plcr_profile_id; /**< Selected profile handle;
153183 + relevant in one of the following cases:
153184 + e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
153185 + e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
153186 + or if any flow uses a KG scheme where policer
153187 + profile is not generated (bypass_plcr_profile_generation selected) */
153188 +} ioc_fm_port_pcd_plcr_params_t;
153189 +
153190 +/**************************************************************************//**
153191 + @Description A structure for defining port PCD parameters
153192 + (Must match struct t_FmPortPcdParams defined in fm_port_ext.h)
153193 +*//***************************************************************************/
153194 +typedef struct ioc_fm_port_pcd_params_t {
153195 + ioc_fm_port_pcd_support pcd_support; /**< Relevant for Rx and offline ports only.
153196 + Describes the active PCD engines for this port. */
153197 + void *net_env_id; /**< HL Unused in PLCR only mode */
153198 + ioc_fm_port_pcd_prs_params_t *p_prs_params; /**< Parser parameters for this port */
153199 + ioc_fm_port_pcd_cc_params_t *p_cc_params; /**< Coarse classification parameters for this port */
153200 + ioc_fm_port_pcd_kg_params_t *p_kg_params; /**< Keygen parameters for this port */
153201 + ioc_fm_port_pcd_plcr_params_t *p_plcr_params; /**< Policer parameters for this port */
153202 + void *p_ip_reassembly_manip;/**< IP Reassembly manipulation */
153203 +#if (DPAA_VERSION >= 11)
153204 + void *p_capwap_reassembly_manip;/**< CAPWAP Reassembly manipulation */
153205 +#endif /* (DPAA_VERSION >= 11) */
153206 +} ioc_fm_port_pcd_params_t;
153207 +
153208 +/**************************************************************************//**
153209 + @Description A structure for defining the Parser starting point
153210 + (Must match struct t_FmPcdPrsStart defined in fm_port_ext.h)
153211 +*//***************************************************************************/
153212 +typedef struct ioc_fm_pcd_prs_start_t {
153213 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to
153214 + start parsing */
153215 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at
153216 + 'parsing_offset' */
153217 +} ioc_fm_pcd_prs_start_t;
153218 +
153219 +
153220 +/**************************************************************************//**
153221 + @Description FQID parameters structure
153222 +*//***************************************************************************/
153223 +typedef struct ioc_fm_port_pcd_fqids_params_t {
153224 + uint32_t num_fqids; /**< Number of fqids to be allocated for the port */
153225 + uint8_t alignment; /**< Alignment required for this port */
153226 + uint32_t base_fqid; /**< output parameter - the base fqid */
153227 +} ioc_fm_port_pcd_fqids_params_t;
153228 +
153229 +
153230 +/**************************************************************************//**
153231 + @Function FM_PORT_IOC_ALLOC_PCD_FQIDS
153232 +
153233 + @Description Allocates FQID's
153234 +
153235 + May be used for Rx and offline parsing ports only
153236 +
153237 + @Param[in,out] ioc_fm_port_pcd_fqids_params_t Parameters for allocating FQID's
153238 +
153239 + @Return 0 on success; error code otherwise.
153240 +*//***************************************************************************/
153241 +#define FM_PORT_IOC_ALLOC_PCD_FQIDS _IOWR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), ioc_fm_port_pcd_fqids_params_t)
153242 +
153243 +/**************************************************************************//**
153244 + @Function FM_PORT_IOC_FREE_PCD_FQIDS
153245 +
153246 + @Description Frees previously-allocated FQIDs
153247 +
153248 + May be used for Rx and offline parsing ports only
153249 +
153250 + @Param[in] uint32_t Base FQID of previously allocated range.
153251 +
153252 + @Return 0 on success; error code otherwise.
153253 +*//***************************************************************************/
153254 +#define FM_PORT_IOC_FREE_PCD_FQIDS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), uint32_t)
153255 +
153256 +
153257 +/**************************************************************************//**
153258 + @Function FM_PORT_SetPCD
153259 +
153260 + @Description Calling this routine defines the port's PCD configuration.
153261 + It changes it from its default configuration which is PCD
153262 + disabled (BMI to BMI) and configures it according to the passed
153263 + parameters.
153264 +
153265 + May be used for Rx and offline parsing ports only
153266 +
153267 + @Param[in] ioc_fm_port_pcd_params_t A Structure of parameters defining the port's PCD
153268 + configuration.
153269 +
153270 + @Return 0 on success; error code otherwise.
153271 +*//***************************************************************************/
153272 +#if defined(CONFIG_COMPAT)
153273 +#define FM_PORT_IOC_SET_PCD_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_compat_fm_port_pcd_params_t)
153274 +#endif
153275 +#define FM_PORT_IOC_SET_PCD _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_fm_port_pcd_params_t)
153276 +
153277 +/**************************************************************************//**
153278 + @Function FM_PORT_DeletePCD
153279 +
153280 + @Description Calling this routine releases the port's PCD configuration.
153281 + The port returns to its default configuration which is PCD
153282 + disabled (BMI to BMI) and all PCD configuration is removed.
153283 +
153284 + May be used for Rx and offline parsing ports which are
153285 + in PCD mode only
153286 +
153287 + @Return 0 on success; error code otherwise.
153288 +*//***************************************************************************/
153289 +#define FM_PORT_IOC_DELETE_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(21))
153290 +
153291 +/**************************************************************************//**
153292 + @Function FM_PORT_AttachPCD
153293 +
153294 + @Description This routine may be called after FM_PORT_DetachPCD was called,
153295 + to return to the originally configured PCD support flow.
153296 + The couple of routines are used to allow PCD configuration changes
153297 + that demand that PCD will not be used while changes take place.
153298 +
153299 + May be used for Rx and offline parsing ports which are
153300 + in PCD mode only
153301 +
153302 + @Return 0 on success; error code otherwise.
153303 +*//***************************************************************************/
153304 +#define FM_PORT_IOC_ATTACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(23))
153305 +
153306 +/**************************************************************************//**
153307 + @Function FM_PORT_DetachPCD
153308 +
153309 + @Description Calling this routine detaches the port from its PCD functionality.
153310 + The port returns to its default flow which is BMI to BMI.
153311 +
153312 + May be used for Rx and offline parsing ports which are
153313 + in PCD mode only
153314 +
153315 + @Return 0 on success; error code otherwise.
153316 +*//***************************************************************************/
153317 +#define FM_PORT_IOC_DETACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(22))
153318 +
153319 +/**************************************************************************//**
153320 + @Function FM_PORT_PcdPlcrAllocProfiles
153321 +
153322 + @Description This routine may be called only for ports that use the Policer in
153323 + order to allocate private policer profiles.
153324 +
153325 + @Param[in] uint16_t The number of required policer profiles
153326 +
153327 + @Return 0 on success; error code otherwise.
153328 +
153329 + @Cautions Allowed before FM_PORT_SetPCD() only.
153330 +*//***************************************************************************/
153331 +#define FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(24), uint16_t)
153332 +
153333 +/**************************************************************************//**
153334 + @Function FM_PORT_PcdPlcrFreeProfiles
153335 +
153336 + @Description This routine should be called for freeing private policer profiles.
153337 +
153338 + @Return 0 on success; error code otherwise.
153339 +
153340 + @Cautions Allowed before FM_PORT_SetPCD() only.
153341 +*//***************************************************************************/
153342 +#define FM_PORT_IOC_PCD_PLCR_FREE_PROFILES _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(25))
153343 +
153344 +/**************************************************************************//**
153345 + @Function FM_PORT_PcdKgModifyInitialScheme
153346 +
153347 + @Description This routine may be called only for ports that use the keygen in
153348 + order to change the initial scheme frame should be routed to.
153349 + The change may be of a scheme id (in case of direct mode),
153350 + from direct to indirect, or from indirect to direct - specifying the scheme id.
153351 +
153352 + @Param[in] ioc_fm_pcd_kg_scheme_select_t A structure of parameters for defining whether
153353 + a scheme is direct/indirect, and if direct - scheme id.
153354 +
153355 + @Return 0 on success; error code otherwise.
153356 +*//***************************************************************************/
153357 +#if defined(CONFIG_COMPAT)
153358 +#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)
153359 +#endif
153360 +#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)
153361 +
153362 +/**************************************************************************//**
153363 + @Function FM_PORT_PcdPlcrModifyInitialProfile
153364 +
153365 + @Description This routine may be called for ports with flows
153366 + e_IOC_FM_PCD_SUPPORT_PLCR_ONLY or e_IOC_FM_PCD_SUPPORT_PRS_AND_PLCR only,
153367 + to change the initial Policer profile frame should be routed to.
153368 + The change may be of a profile and/or absolute/direct mode selection.
153369 +
153370 + @Param[in] ioc_fm_obj_t Policer profile Id as returned from FM_PCD_PlcrSetProfile.
153371 +
153372 + @Return 0 on success; error code otherwise.
153373 +*//***************************************************************************/
153374 +#if defined(CONFIG_COMPAT)
153375 +#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)
153376 +#endif
153377 +#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_fm_obj_t)
153378 +
153379 +/**************************************************************************//**
153380 + @Function FM_PORT_PcdCcModifyTree
153381 +
153382 + @Description This routine may be called to change this port connection to
153383 + a pre-initializes coarse classification Tree.
153384 +
153385 + @Param[in] ioc_fm_obj_t Id of new coarse classification tree selected for this port.
153386 +
153387 + @Return 0 on success; error code otherwise.
153388 +
153389 + @Cautions Allowed only following FM_PORT_SetPCD() and FM_PORT_DetachPCD()
153390 +*//***************************************************************************/
153391 +#if defined(CONFIG_COMPAT)
153392 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_compat_fm_obj_t)
153393 +#endif
153394 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_fm_obj_t)
153395 +
153396 +/**************************************************************************//**
153397 + @Function FM_PORT_PcdKgBindSchemes
153398 +
153399 + @Description These routines may be called for modifying the binding of ports
153400 + to schemes. The scheme itself is not added,
153401 + just this specific port starts using it.
153402 +
153403 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
153404 +
153405 + @Return 0 on success; error code otherwise.
153406 +
153407 + @Cautions Allowed only following FM_PORT_SetPCD().
153408 +*//***************************************************************************/
153409 +#if defined(CONFIG_COMPAT)
153410 +#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)
153411 +#endif
153412 +#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)
153413 +
153414 +/**************************************************************************//**
153415 + @Function FM_PORT_PcdKgUnbindSchemes
153416 +
153417 + @Description These routines may be called for modifying the binding of ports
153418 + to schemes. The scheme itself is not removed or invalidated,
153419 + just this specific port stops using it.
153420 +
153421 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
153422 +
153423 + @Return 0 on success; error code otherwise.
153424 +
153425 + @Cautions Allowed only following FM_PORT_SetPCD().
153426 +*//***************************************************************************/
153427 +#if defined(CONFIG_COMPAT)
153428 +#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)
153429 +#endif
153430 +#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)
153431 +
153432 +typedef struct ioc_fm_port_mac_addr_params_t {
153433 + uint8_t addr[ENET_NUM_OCTETS_PER_ADDRESS];
153434 +} ioc_fm_port_mac_addr_params_t;
153435 +
153436 +/**************************************************************************//**
153437 + @Function FM_MAC_AddHashMacAddr
153438 +
153439 + @Description Add an Address to the hash table. This is for filter purpose only.
153440 +
153441 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
153442 +
153443 + @Return E_OK on success; Error code otherwise.
153444 +
153445 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
153446 + @Cautions Some address need to be filtered out in upper FM blocks.
153447 +*//***************************************************************************/
153448 +#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)
153449 +
153450 +/**************************************************************************//**
153451 + @Function FM_MAC_RemoveHashMacAddr
153452 +
153453 + @Description Delete an Address to the hash table. This is for filter purpose only.
153454 +
153455 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
153456 +
153457 + @Return E_OK on success; Error code otherwise.
153458 +
153459 + @Cautions Allowed only following FM_MAC_Init().
153460 +*//***************************************************************************/
153461 +#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)
153462 +
153463 +typedef struct ioc_fm_port_tx_pause_frames_params_t {
153464 + uint8_t priority;
153465 + uint16_t pause_time;
153466 + uint16_t thresh_time;
153467 +} ioc_fm_port_tx_pause_frames_params_t;
153468 +
153469 +/**************************************************************************//**
153470 + @Function FM_MAC_SetTxPauseFrames
153471 +
153472 + @Description Enable/Disable transmission of Pause-Frames.
153473 + The routine changes the default configuration:
153474 + pause-time - [0xf000]
153475 + threshold-time - [0]
153476 +
153477 + @Param[in] ioc_fm_port_tx_pause_frames_params_t A structure holding the required parameters.
153478 +
153479 + @Return E_OK on success; Error code otherwise.
153480 +
153481 + @Cautions Allowed only following FM_MAC_Init().
153482 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
153483 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
153484 + in the 'priority' field.
153485 +*//***************************************************************************/
153486 +#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)
153487 +
153488 +typedef struct ioc_fm_port_mac_statistics_t {
153489 + /* RMON */
153490 + uint64_t e_stat_pkts_64; /**< r-10G tr-DT 64 byte frame counter */
153491 + uint64_t e_stat_pkts_65_to_127; /**< r-10G 65 to 127 byte frame counter */
153492 + uint64_t e_stat_pkts_128_to_255; /**< r-10G 128 to 255 byte frame counter */
153493 + uint64_t e_stat_pkts_256_to_511; /**< r-10G 256 to 511 byte frame counter */
153494 + uint64_t e_stat_pkts_512_to_1023; /**< r-10G 512 to 1023 byte frame counter */
153495 + uint64_t e_stat_pkts_1024_to_1518; /**< r-10G 1024 to 1518 byte frame counter */
153496 + uint64_t e_stat_pkts_1519_to_1522; /**< r-10G 1519 to 1522 byte good frame count */
153497 + /* */
153498 + uint64_t e_stat_fragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
153499 + uint64_t e_stat_jabbers; /**< Total number of packets longer than valid maximum length octets */
153500 + uint64_t e_stat_drop_events; /**< number of dropped packets due to internal errors of the MAC Client (during recieve). */
153501 + uint64_t e_stat_CRC_align_errors; /**< Incremented when frames of correct length but with CRC error are received.*/
153502 + uint64_t e_stat_undersize_pkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
153503 + This count does not include range length errors */
153504 + uint64_t e_stat_oversize_pkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
153505 + a valid FCS and otherwise well formed */
153506 + /* Pause */
153507 + uint64_t te_stat_pause; /**< Pause MAC Control received */
153508 + uint64_t re_stat_pause; /**< Pause MAC Control sent */
153509 + /* MIB II */
153510 + uint64_t if_in_octets; /**< Total number of byte received. */
153511 + uint64_t if_in_pkts; /**< Total number of packets received.*/
153512 + uint64_t if_in_ucast_pkts; /**< Total number of unicast frame received;
153513 + NOTE: this counter is not supported on dTSEC MAC */
153514 + uint64_t if_in_mcast_pkts; /**< Total number of multicast frame received*/
153515 + uint64_t if_in_bcast_pkts; /**< Total number of broadcast frame received */
153516 + uint64_t if_in_discards; /**< Frames received, but discarded due to problems within the MAC RX. */
153517 + uint64_t if_in_errors; /**< Number of frames received with error:
153518 + - FIFO Overflow Error
153519 + - CRC Error
153520 + - Frame Too Long Error
153521 + - Alignment Error
153522 + - The dedicated Error Code (0xfe, not a code error) was received */
153523 + uint64_t if_out_octets; /**< Total number of byte sent. */
153524 + uint64_t if_out_pkts; /**< Total number of packets sent .*/
153525 + uint64_t if_out_ucast_pkts; /**< Total number of unicast frame sent;
153526 + NOTE: this counter is not supported on dTSEC MAC */
153527 + uint64_t if_out_mcast_pkts; /**< Total number of multicast frame sent */
153528 + uint64_t if_out_bcast_pkts; /**< Total number of multicast frame sent */
153529 + uint64_t if_out_discards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
153530 + uint64_t if_out_errors; /**< Number of frames transmitted with error:
153531 + - FIFO Overflow Error
153532 + - FIFO Underflow Error
153533 + - Other */
153534 +} ioc_fm_port_mac_statistics_t;
153535 +
153536 +/**************************************************************************//**
153537 + @Function FM_MAC_GetStatistics
153538 +
153539 + @Description get all MAC statistics counters
153540 +
153541 + @Param[out] ioc_fm_port_mac_statistics_t A structure holding the statistics
153542 +
153543 + @Return E_OK on success; Error code otherwise.
153544 +
153545 + @Cautions Allowed only following FM_Init().
153546 +*//***************************************************************************/
153547 +#define FM_PORT_IOC_GET_MAC_STATISTICS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(41), ioc_fm_port_mac_statistics_t)
153548 +
153549 +/**************************************************************************//**
153550 + @Function FM_PORT_ConfigBufferPrefixContent
153551 +
153552 + @Description Defines the structure, size and content of the application buffer.
153553 + The prefix will
153554 + In Tx ports, if 'passPrsResult', the application
153555 + should set a value to their offsets in the prefix of
153556 + the FM will save the first 'privDataSize', than,
153557 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
153558 + and timeStamp, and the packet itself (in this order), to the
153559 + application buffer, and to offset.
153560 + Calling this routine changes the buffer margins definitions
153561 + in the internal driver data base from its default
153562 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
153563 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
153564 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
153565 +
153566 + May be used for all ports
153567 +
153568 + @Param[in] ioc_fm_buffer_prefix_content_t A structure holding the required parameters.
153569 +
153570 + @Return E_OK on success; Error code otherwise.
153571 +
153572 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
153573 +*//***************************************************************************/
153574 +#define FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(39), ioc_fm_buffer_prefix_content_t)
153575 +
153576 +#if (DPAA_VERSION >= 11)
153577 +typedef struct ioc_fm_port_vsp_alloc_params_t {
153578 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
153579 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
153580 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
153581 + if relevant function called for Rx port */
153582 + void *p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
153583 +}ioc_fm_port_vsp_alloc_params_t;
153584 +
153585 +/**************************************************************************//**
153586 + @Function FM_PORT_VSPAlloc
153587 +
153588 + @Description This routine allocated VSPs per port and forces the port to work
153589 + in VSP mode. Note that the port is initialized by default with the
153590 + physical-storage-profile only.
153591 +
153592 + @Param[in] h_FmPort A handle to a FM Port module.
153593 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
153594 +
153595 + @Return E_OK on success; Error code otherwise.
153596 +
153597 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
153598 + and also before FM_PORT_Enable() (i.e. the port should be disabled).
153599 +*//***************************************************************************/
153600 +#if defined(CONFIG_COMPAT)
153601 +#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)
153602 +#endif
153603 +#define FM_PORT_IOC_VSP_ALLOC _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_fm_port_vsp_alloc_params_t)
153604 +#endif /* (DPAA_VERSION >= 11) */
153605 +
153606 +/**************************************************************************//**
153607 + @Function FM_PORT_GetBmiCounters
153608 +
153609 + @Description Read port's BMI stat counters and place them into
153610 + a designated structure of counters.
153611 +
153612 + @Param[in] h_FmPort A handle to a FM Port module.
153613 + @Param[out] p_BmiStats counters structure
153614 +
153615 + @Return E_OK on success; Error code otherwise.
153616 +
153617 + @Cautions Allowed only following FM_PORT_Init().
153618 +*//***************************************************************************/
153619 +
153620 +#define FM_PORT_IOC_GET_BMI_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(42), ioc_fm_port_bmi_stats_t)
153621 +
153622 +typedef struct ioc_fm_port_mac_frame_size_counters_t {
153623 +
153624 + e_CommMode type;
153625 + uint64_t count_pkts_64; /**< 64 byte frame counter */
153626 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
153627 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
153628 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
153629 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
153630 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
153631 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
153632 +} ioc_fm_port_mac_frame_size_counters_t;
153633 +
153634 +/**************************************************************************//**
153635 + @Function FM_MAC_GetFrameSizeCounters
153636 +
153637 + @Description get MAC statistics counters for different frame size
153638 +
153639 + @Param[out] ioc_fm_port_mac_frame_size_counters_t A structure holding the counters
153640 +
153641 + @Return E_OK on success; Error code otherwise.
153642 +
153643 + @Cautions Allowed only following FM_Init().
153644 +*//***************************************************************************/
153645 +#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)
153646 +
153647 +
153648 +/** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */
153649 +/** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */
153650 +
153651 +/** @} */ /* end of lnx_ioctl_FM_PORT_grp group */
153652 +/** @} */ /* end of lnx_ioctl_FM_grp group */
153653 +#endif /* __FM_PORT_IOCTLS_H */
153654 --- /dev/null
153655 +++ b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
153656 @@ -0,0 +1,208 @@
153657 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153658 + * All rights reserved.
153659 + *
153660 + * Redistribution and use in source and binary forms, with or without
153661 + * modification, are permitted provided that the following conditions are met:
153662 + * * Redistributions of source code must retain the above copyright
153663 + * notice, this list of conditions and the following disclaimer.
153664 + * * Redistributions in binary form must reproduce the above copyright
153665 + * notice, this list of conditions and the following disclaimer in the
153666 + * documentation and/or other materials provided with the distribution.
153667 + * * Neither the name of Freescale Semiconductor nor the
153668 + * names of its contributors may be used to endorse or promote products
153669 + * derived from this software without specific prior written permission.
153670 + *
153671 + *
153672 + * ALTERNATIVELY, this software may be distributed under the terms of the
153673 + * GNU General Public License ("GPL") as published by the Free Software
153674 + * Foundation, either version 2 of that License or (at your option) any
153675 + * later version.
153676 + *
153677 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153678 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153679 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153680 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153681 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153682 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153683 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153684 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153685 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153686 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153687 + */
153688 +
153689 +/**************************************************************************//**
153690 + @File fm_test_ioctls.h
153691 +
153692 + @Description FM Char device ioctls
153693 +*//***************************************************************************/
153694 +#ifndef __FM_TEST_IOCTLS_H
153695 +#define __FM_TEST_IOCTLS_H
153696 +
153697 +#include "ioctls.h"
153698 +
153699 +
153700 +/**************************************************************************//**
153701 + @Group lnx_ioctl_FMT_grp Frame Manager Test Linux IOCTL API
153702 +
153703 + @Description FM-Test Linux ioctls definitions and enums
153704 +
153705 + @{
153706 +*//***************************************************************************/
153707 +
153708 +#define IOC_FMT_MAX_NUM_OF_PORTS 26
153709 +
153710 +/**************************************************************************//**
153711 + @Collection TEST Parameters
153712 +*//***************************************************************************/
153713 +/**************************************************************************//**
153714 + @Description: Name of the FM-Test chardev
153715 +*//***************************************************************************/
153716 +#define DEV_FM_TEST_NAME "fm-test-port"
153717 +
153718 +#define DEV_FM_TEST_PORTS_MINOR_BASE 0
153719 +#define DEV_FM_TEST_MAX_MINORS (DEV_FM_TEST_PORTS_MINOR_BASE + IOC_FMT_MAX_NUM_OF_PORTS)
153720 +
153721 +#define FMT_PORT_IOC_NUM(n) n
153722 +/* @} */
153723 +
153724 +/**************************************************************************//**
153725 + @Group lnx_ioctl_FMT_lib_grp FM-Test library
153726 +
153727 + @Description TODO
153728 +
153729 + @{
153730 +*//***************************************************************************/
153731 +
153732 +/**************************************************************************//**
153733 + @Description TODO
153734 +*//***************************************************************************/
153735 +typedef uint8_t ioc_fmt_xxx_t;
153736 +
153737 +#define FM_PRS_MAX 32
153738 +#define FM_TIME_STAMP_MAX 8
153739 +
153740 +/**************************************************************************//**
153741 + @Description FM Port buffer content description
153742 +*//***************************************************************************/
153743 +typedef struct ioc_fmt_buff_context_t {
153744 + void *p_user_priv;
153745 + uint8_t fm_prs_res[FM_PRS_MAX];
153746 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
153747 +} ioc_fmt_buff_context_t;
153748 +
153749 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
153750 +typedef struct ioc_fmt_compat_buff_context_t {
153751 + compat_uptr_t p_user_priv;
153752 + uint8_t fm_prs_res[FM_PRS_MAX];
153753 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
153754 +} ioc_fmt_compat_buff_context_t;
153755 +#endif
153756 +
153757 +/**************************************************************************//**
153758 + @Description Buffer descriptor
153759 +*//***************************************************************************/
153760 +typedef struct ioc_fmt_buff_desc_t {
153761 + uint32_t qid;
153762 + void *p_data;
153763 + uint32_t size;
153764 + uint32_t status;
153765 + ioc_fmt_buff_context_t buff_context;
153766 +} ioc_fmt_buff_desc_t;
153767 +
153768 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
153769 +typedef struct ioc_fmt_compat_buff_desc_t {
153770 + uint32_t qid;
153771 + compat_uptr_t p_data;
153772 + uint32_t size;
153773 + uint32_t status;
153774 + ioc_fmt_compat_buff_context_t buff_context;
153775 +} ioc_fmt_compat_buff_desc_t;
153776 +#endif
153777 +
153778 +/**************************************************************************//**
153779 + @Group lnx_ioctl_FMT_runtime_control_grp FM-Test Runtime Control Unit
153780 +
153781 + @Description TODO
153782 + @{
153783 +*//***************************************************************************/
153784 +
153785 +/** @} */ /* end of lnx_ioctl_FMT_runtime_control_grp group */
153786 +
153787 +
153788 +/**************************************************************************//**
153789 + @Group lnx_ioctl_FMTP_lib_grp FM-Port-Test library
153790 +
153791 + @Description TODO
153792 +
153793 + @{
153794 +*//***************************************************************************/
153795 +
153796 +/**************************************************************************//**
153797 + @Description FM-Test FM port type
153798 +*//***************************************************************************/
153799 +typedef enum ioc_fmt_port_type {
153800 + e_IOC_FMT_PORT_T_RXTX, /**< Standard port */
153801 + e_IOC_FMT_PORT_T_OP, /**< Offline-parsing port */
153802 +} ioc_fmt_port_type;
153803 +
153804 +/**************************************************************************//**
153805 + @Description TODO
153806 +*//***************************************************************************/
153807 +typedef struct ioc_fmt_port_param_t {
153808 + uint8_t fm_id;
153809 + ioc_fmt_port_type fm_port_type;
153810 + uint8_t fm_port_id;
153811 + uint32_t num_tx_queues;
153812 +} ioc_fmt_port_param_t;
153813 +
153814 +
153815 +/**************************************************************************//**
153816 + @Function FMT_PORT_IOC_INIT
153817 +
153818 + @Description TODO
153819 +
153820 + @Param[in] ioc_fmt_port_param_t TODO
153821 +
153822 + @Cautions Allowed only after the FM equivalent port is already initialized.
153823 +*//***************************************************************************/
153824 +#define FMT_PORT_IOC_INIT _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(0), ioc_fmt_port_param_t)
153825 +
153826 +/**************************************************************************//**
153827 + @Function FMT_PORT_IOC_SET_DIAG_MODE
153828 +
153829 + @Description TODO
153830 +
153831 + @Param[in] ioc_diag_mode TODO
153832 +
153833 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
153834 +*//***************************************************************************/
153835 +#define FMT_PORT_IOC_SET_DIAG_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(1), ioc_diag_mode)
153836 +
153837 +/**************************************************************************//**
153838 + @Function FMT_PORT_IOC_SET_IP_HEADER_MANIP
153839 +
153840 + @Description Set IP header manipulations for this port.
153841 +
153842 + @Param[in] int 1 to enable; 0 to disable
153843 +
153844 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
153845 +*//***************************************************************************/
153846 +#define FMT_PORT_IOC_SET_IP_HEADER_MANIP _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(2), int)
153847 +
153848 +/**************************************************************************//**
153849 + @Function FMT_PORT_IOC_SET_DPAECHO_MODE
153850 +
153851 + @Description Set DPA in echo mode - all frame are sent back.
153852 +
153853 + @Param[in] int 1 to enable; 0 to disable
153854 +
153855 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
153856 +*//***************************************************************************/
153857 +#define FMT_PORT_IOC_SET_DPAECHO_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(3), int)
153858 +
153859 +/** @} */ /* end of lnx_ioctl_FMTP_lib_grp group */
153860 +/** @} */ /* end of lnx_ioctl_FMT_lib_grp group */
153861 +/** @} */ /* end of lnx_ioctl_FMT_grp */
153862 +
153863 +
153864 +#endif /* __FM_TEST_IOCTLS_H */
153865 --- /dev/null
153866 +++ b/include/uapi/linux/fmd/integrations/Kbuild
153867 @@ -0,0 +1 @@
153868 +header-y += integration_ioctls.h
153869 --- /dev/null
153870 +++ b/include/uapi/linux/fmd/integrations/integration_ioctls.h
153871 @@ -0,0 +1,56 @@
153872 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153873 + * All rights reserved.
153874 + *
153875 + * Redistribution and use in source and binary forms, with or without
153876 + * modification, are permitted provided that the following conditions are met:
153877 + * * Redistributions of source code must retain the above copyright
153878 + * notice, this list of conditions and the following disclaimer.
153879 + * * Redistributions in binary form must reproduce the above copyright
153880 + * notice, this list of conditions and the following disclaimer in the
153881 + * documentation and/or other materials provided with the distribution.
153882 + * * Neither the name of Freescale Semiconductor nor the
153883 + * names of its contributors may be used to endorse or promote products
153884 + * derived from this software without specific prior written permission.
153885 + *
153886 + *
153887 + * ALTERNATIVELY, this software may be distributed under the terms of the
153888 + * GNU General Public License ("GPL") as published by the Free Software
153889 + * Foundation, either version 2 of that License or (at your option) any
153890 + * later version.
153891 + *
153892 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153893 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153894 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153895 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153896 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153897 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153898 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153899 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153900 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153901 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153902 + */
153903 +
153904 +/**************************************************************************//**
153905 + @File integration_ioctls.h
153906 +
153907 + @Description External header file for Integration unit routines.
153908 +*//***************************************************************************/
153909 +
153910 +#ifndef __INTG_IOCTLS_H
153911 +#define __INTG_IOCTLS_H
153912 +
153913 +
153914 +#define FM_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+1)
153915 +#define FMT_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+3)
153916 +
153917 +/*#define FM_IOCTL_DBG*/
153918 +
153919 +#if defined(FM_IOCTL_DBG)
153920 + #define _fm_ioctl_dbg(format, arg...) \
153921 + printk("fm ioctl [%s:%u](cpu:%u) - " format, \
153922 + __func__, __LINE__, smp_processor_id(), ##arg)
153923 +#else
153924 +# define _fm_ioctl_dbg(arg...)
153925 +#endif
153926 +
153927 +#endif /* __INTG_IOCTLS_H */
153928 --- /dev/null
153929 +++ b/include/uapi/linux/fmd/ioctls.h
153930 @@ -0,0 +1,96 @@
153931 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153932 + * All rights reserved.
153933 + *
153934 + * Redistribution and use in source and binary forms, with or without
153935 + * modification, are permitted provided that the following conditions are met:
153936 + * * Redistributions of source code must retain the above copyright
153937 + * notice, this list of conditions and the following disclaimer.
153938 + * * Redistributions in binary form must reproduce the above copyright
153939 + * notice, this list of conditions and the following disclaimer in the
153940 + * documentation and/or other materials provided with the distribution.
153941 + * * Neither the name of Freescale Semiconductor nor the
153942 + * names of its contributors may be used to endorse or promote products
153943 + * derived from this software without specific prior written permission.
153944 + *
153945 + *
153946 + * ALTERNATIVELY, this software may be distributed under the terms of the
153947 + * GNU General Public License ("GPL") as published by the Free Software
153948 + * Foundation, either version 2 of that License or (at your option) any
153949 + * later version.
153950 + *
153951 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153952 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153953 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153954 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153955 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153956 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153957 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153958 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153959 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153960 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153961 + */
153962 +
153963 +/**************************************************************************//**
153964 + @File ioctls.h
153965 +
153966 + @Description Structures and definitions for Command Relay Ioctls
153967 +*//***************************************************************************/
153968 +
153969 +#ifndef __IOCTLS_H__
153970 +#define __IOCTLS_H__
153971 +
153972 +#include <asm/ioctl.h>
153973 +
153974 +#include "integration_ioctls.h"
153975 +
153976 +
153977 +/**************************************************************************//**
153978 + @Group lnx_ioctl_ncsw_grp NetCommSw Linux User-Space (IOCTL) API
153979 + @{
153980 +*//***************************************************************************/
153981 +
153982 +#define NCSW_IOC_TYPE_BASE 0xe0 /**< defines the IOCTL type for all
153983 + the NCSW Linux module commands */
153984 +
153985 +
153986 +/**************************************************************************//**
153987 + @Description IOCTL Memory allocation types.
153988 +*//***************************************************************************/
153989 +typedef enum ioc_mem_type {
153990 + e_IOC_MEM_INVALID = 0x00000000, /**< Invalid memory type (error) */
153991 + e_IOC_MEM_CACHABLE_SYS = 0x00000001, /**< Primary DDR, cacheable segment */
153992 + e_IOC_MEM_NOCACHE_SYS = 0x00000004, /**< Primary DDR, non-cacheable segment */
153993 + e_IOC_MEM_SECONDARY = 0x00000002, /**< Either secondary DDR or SDRAM */
153994 + e_IOC_MEM_PRAM = 0x00000008 /**< Multi-user RAM identifier */
153995 +} ioc_mem_type;
153996 +
153997 +/**************************************************************************//**
153998 + @Description Enumeration (bit flags) of communication modes (Transmit,
153999 + receive or both).
154000 +*//***************************************************************************/
154001 +typedef enum ioc_comm_mode {
154002 + e_IOC_COMM_MODE_NONE = 0 /**< No transmit/receive communication */
154003 + , e_IOC_COMM_MODE_RX = 1 /**< Only receive communication */
154004 + , e_IOC_COMM_MODE_TX = 2 /**< Only transmit communication */
154005 + , e_IOC_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
154006 +} ioc_comm_mode;
154007 +
154008 +/**************************************************************************//**
154009 + @Description General Diagnostic Mode
154010 +*//***************************************************************************/
154011 +typedef enum ioc_diag_mode
154012 +{
154013 + e_IOC_DIAG_MODE_NONE = 0,
154014 + e_IOC_DIAG_MODE_CTRL_LOOPBACK, /**< loopback in the controller; E.g. MAC, TDM, etc. */
154015 + e_IOC_DIAG_MODE_CHIP_LOOPBACK, /**< loopback in the chip but not in controller;
154016 + E.g. IO-pins, SerDes, etc. */
154017 + e_IOC_DIAG_MODE_PHY_LOOPBACK, /**< loopback in the external PHY */
154018 + e_IOC_DIAG_MODE_LINE_LOOPBACK, /**< loopback in the external line */
154019 + e_IOC_DIAG_MODE_CTRL_ECHO, /**< */
154020 + e_IOC_DIAG_MODE_PHY_ECHO /**< */
154021 +} ioc_diag_mode;
154022 +
154023 +/** @} */ /* end of lnx_ioctl_ncsw_grp */
154024 +
154025 +
154026 +#endif /* __IOCTLS_H__ */
154027 --- /dev/null
154028 +++ b/include/uapi/linux/fmd/net_ioctls.h
154029 @@ -0,0 +1,430 @@
154030 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154031 + * All rights reserved.
154032 + *
154033 + * Redistribution and use in source and binary forms, with or without
154034 + * modification, are permitted provided that the following conditions are met:
154035 + * * Redistributions of source code must retain the above copyright
154036 + * notice, this list of conditions and the following disclaimer.
154037 + * * Redistributions in binary form must reproduce the above copyright
154038 + * notice, this list of conditions and the following disclaimer in the
154039 + * documentation and/or other materials provided with the distribution.
154040 + * * Neither the name of Freescale Semiconductor nor the
154041 + * names of its contributors may be used to endorse or promote products
154042 + * derived from this software without specific prior written permission.
154043 + *
154044 + *
154045 + * ALTERNATIVELY, this software may be distributed under the terms of the
154046 + * GNU General Public License ("GPL") as published by the Free Software
154047 + * Foundation, either version 2 of that License or (at your option) any
154048 + * later version.
154049 + *
154050 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154051 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154052 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154053 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154054 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154055 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154056 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154057 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154058 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154059 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154060 + */
154061 +
154062 +
154063 +/**************************************************************************//**
154064 + @File net_ioctls.h
154065 +
154066 + @Description This file contains common and general netcomm headers definitions.
154067 +*//***************************************************************************/
154068 +#ifndef __NET_IOCTLS_H
154069 +#define __NET_IOCTLS_H
154070 +
154071 +#include "ioctls.h"
154072 +
154073 +
154074 +typedef uint8_t ioc_header_field_ppp_t;
154075 +
154076 +#define IOC_NET_HEADER_FIELD_PPP_PID (1)
154077 +#define IOC_NET_HEADER_FIELD_PPP_COMPRESSED (IOC_NET_HEADER_FIELD_PPP_PID << 1)
154078 +#define IOC_NET_HEADER_FIELD_PPP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPP_PID << 2) - 1)
154079 +
154080 +
154081 +typedef uint8_t ioc_header_field_pppoe_t;
154082 +
154083 +#define IOC_NET_HEADER_FIELD_PPPoE_VER (1)
154084 +#define IOC_NET_HEADER_FIELD_PPPoE_TYPE (IOC_NET_HEADER_FIELD_PPPoE_VER << 1)
154085 +#define IOC_NET_HEADER_FIELD_PPPoE_CODE (IOC_NET_HEADER_FIELD_PPPoE_VER << 2)
154086 +#define IOC_NET_HEADER_FIELD_PPPoE_SID (IOC_NET_HEADER_FIELD_PPPoE_VER << 3)
154087 +#define IOC_NET_HEADER_FIELD_PPPoE_LEN (IOC_NET_HEADER_FIELD_PPPoE_VER << 4)
154088 +#define IOC_NET_HEADER_FIELD_PPPoE_SESSION (IOC_NET_HEADER_FIELD_PPPoE_VER << 5)
154089 +#define IOC_NET_HEADER_FIELD_PPPoE_PID (IOC_NET_HEADER_FIELD_PPPoE_VER << 6)
154090 +#define IOC_NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
154091 +
154092 +#define IOC_NET_HEADER_FIELD_PPPMUX_PID (1)
154093 +#define IOC_NET_HEADER_FIELD_PPPMUX_CKSUM (IOC_NET_HEADER_FIELD_PPPMUX_PID << 1)
154094 +#define IOC_NET_HEADER_FIELD_PPPMUX_COMPRESSED (IOC_NET_HEADER_FIELD_PPPMUX_PID << 2)
154095 +#define IOC_NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
154096 +
154097 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
154098 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
154099 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
154100 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
154101 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
154102 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
154103 +
154104 +
154105 +typedef uint8_t ioc_header_field_eth_t;
154106 +
154107 +#define IOC_NET_HEADER_FIELD_ETH_DA (1)
154108 +#define IOC_NET_HEADER_FIELD_ETH_SA (IOC_NET_HEADER_FIELD_ETH_DA << 1)
154109 +#define IOC_NET_HEADER_FIELD_ETH_LENGTH (IOC_NET_HEADER_FIELD_ETH_DA << 2)
154110 +#define IOC_NET_HEADER_FIELD_ETH_TYPE (IOC_NET_HEADER_FIELD_ETH_DA << 3)
154111 +#define IOC_NET_HEADER_FIELD_ETH_FINAL_CKSUM (IOC_NET_HEADER_FIELD_ETH_DA << 4)
154112 +#define IOC_NET_HEADER_FIELD_ETH_PADDING (IOC_NET_HEADER_FIELD_ETH_DA << 5)
154113 +#define IOC_NET_HEADER_FIELD_ETH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ETH_DA << 6) - 1)
154114 +
154115 +#define IOC_NET_HEADER_FIELD_ETH_ADDR_SIZE 6
154116 +
154117 +typedef uint16_t ioc_header_field_ip_t;
154118 +
154119 +#define IOC_NET_HEADER_FIELD_IP_VER (1)
154120 +#define IOC_NET_HEADER_FIELD_IP_DSCP (IOC_NET_HEADER_FIELD_IP_VER << 2)
154121 +#define IOC_NET_HEADER_FIELD_IP_ECN (IOC_NET_HEADER_FIELD_IP_VER << 3)
154122 +#define IOC_NET_HEADER_FIELD_IP_PROTO (IOC_NET_HEADER_FIELD_IP_VER << 4)
154123 +
154124 +#define IOC_NET_HEADER_FIELD_IP_PROTO_SIZE 1
154125 +
154126 +typedef uint16_t ioc_header_field_ipv4_t;
154127 +
154128 +#define IOC_NET_HEADER_FIELD_IPv4_VER (1)
154129 +#define IOC_NET_HEADER_FIELD_IPv4_HDR_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 1)
154130 +#define IOC_NET_HEADER_FIELD_IPv4_TOS (IOC_NET_HEADER_FIELD_IPv4_VER << 2)
154131 +#define IOC_NET_HEADER_FIELD_IPv4_TOTAL_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 3)
154132 +#define IOC_NET_HEADER_FIELD_IPv4_ID (IOC_NET_HEADER_FIELD_IPv4_VER << 4)
154133 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_D (IOC_NET_HEADER_FIELD_IPv4_VER << 5)
154134 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_M (IOC_NET_HEADER_FIELD_IPv4_VER << 6)
154135 +#define IOC_NET_HEADER_FIELD_IPv4_OFFSET (IOC_NET_HEADER_FIELD_IPv4_VER << 7)
154136 +#define IOC_NET_HEADER_FIELD_IPv4_TTL (IOC_NET_HEADER_FIELD_IPv4_VER << 8)
154137 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO (IOC_NET_HEADER_FIELD_IPv4_VER << 9)
154138 +#define IOC_NET_HEADER_FIELD_IPv4_CKSUM (IOC_NET_HEADER_FIELD_IPv4_VER << 10)
154139 +#define IOC_NET_HEADER_FIELD_IPv4_SRC_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 11)
154140 +#define IOC_NET_HEADER_FIELD_IPv4_DST_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 12)
154141 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS (IOC_NET_HEADER_FIELD_IPv4_VER << 13)
154142 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS_COUNT (IOC_NET_HEADER_FIELD_IPv4_VER << 14)
154143 +#define IOC_NET_HEADER_FIELD_IPv4_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv4_VER << 15) - 1)
154144 +
154145 +#define IOC_NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
154146 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
154147 +
154148 +
154149 +typedef uint8_t ioc_header_field_ipv6_t;
154150 +
154151 +#define IOC_NET_HEADER_FIELD_IPv6_VER (1)
154152 +#define IOC_NET_HEADER_FIELD_IPv6_TC (IOC_NET_HEADER_FIELD_IPv6_VER << 1)
154153 +#define IOC_NET_HEADER_FIELD_IPv6_SRC_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 2)
154154 +#define IOC_NET_HEADER_FIELD_IPv6_DST_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 3)
154155 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR (IOC_NET_HEADER_FIELD_IPv6_VER << 4)
154156 +#define IOC_NET_HEADER_FIELD_IPv6_FL (IOC_NET_HEADER_FIELD_IPv6_VER << 5)
154157 +#define IOC_NET_HEADER_FIELD_IPv6_HOP_LIMIT (IOC_NET_HEADER_FIELD_IPv6_VER << 6)
154158 +#define IOC_NET_HEADER_FIELD_IPv6_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv6_VER << 7) - 1)
154159 +
154160 +#define IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
154161 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
154162 +
154163 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE (1)
154164 +#define IOC_NET_HEADER_FIELD_ICMP_CODE (IOC_NET_HEADER_FIELD_ICMP_TYPE << 1)
154165 +#define IOC_NET_HEADER_FIELD_ICMP_CKSUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 2)
154166 +#define IOC_NET_HEADER_FIELD_ICMP_ID (IOC_NET_HEADER_FIELD_ICMP_TYPE << 3)
154167 +#define IOC_NET_HEADER_FIELD_ICMP_SQ_NUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 4)
154168 +#define IOC_NET_HEADER_FIELD_ICMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
154169 +
154170 +#define IOC_NET_HEADER_FIELD_ICMP_CODE_SIZE 1
154171 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
154172 +
154173 +#define IOC_NET_HEADER_FIELD_IGMP_VERSION (1)
154174 +#define IOC_NET_HEADER_FIELD_IGMP_TYPE (IOC_NET_HEADER_FIELD_IGMP_VERSION << 1)
154175 +#define IOC_NET_HEADER_FIELD_IGMP_CKSUM (IOC_NET_HEADER_FIELD_IGMP_VERSION << 2)
154176 +#define IOC_NET_HEADER_FIELD_IGMP_DATA (IOC_NET_HEADER_FIELD_IGMP_VERSION << 3)
154177 +#define IOC_NET_HEADER_FIELD_IGMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
154178 +
154179 +
154180 +typedef uint16_t ioc_header_field_tcp_t;
154181 +
154182 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SRC (1)
154183 +#define IOC_NET_HEADER_FIELD_TCP_PORT_DST (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 1)
154184 +#define IOC_NET_HEADER_FIELD_TCP_SEQ (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 2)
154185 +#define IOC_NET_HEADER_FIELD_TCP_ACK (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 3)
154186 +#define IOC_NET_HEADER_FIELD_TCP_OFFSET (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 4)
154187 +#define IOC_NET_HEADER_FIELD_TCP_FLAGS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 5)
154188 +#define IOC_NET_HEADER_FIELD_TCP_WINDOW (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 6)
154189 +#define IOC_NET_HEADER_FIELD_TCP_CKSUM (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 7)
154190 +#define IOC_NET_HEADER_FIELD_TCP_URGPTR (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 8)
154191 +#define IOC_NET_HEADER_FIELD_TCP_OPTS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 9)
154192 +#define IOC_NET_HEADER_FIELD_TCP_OPTS_COUNT (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 10)
154193 +#define IOC_NET_HEADER_FIELD_TCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
154194 +
154195 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SIZE 2
154196 +
154197 +
154198 +typedef uint8_t ioc_header_field_sctp_t;
154199 +
154200 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SRC (1)
154201 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_DST (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
154202 +#define IOC_NET_HEADER_FIELD_SCTP_VER_TAG (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
154203 +#define IOC_NET_HEADER_FIELD_SCTP_CKSUM (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
154204 +#define IOC_NET_HEADER_FIELD_SCTP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
154205 +
154206 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SIZE 2
154207 +
154208 +typedef uint8_t ioc_header_field_dccp_t;
154209 +
154210 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SRC (1)
154211 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_DST (IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
154212 +#define IOC_NET_HEADER_FIELD_DCCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
154213 +
154214 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SIZE 2
154215 +
154216 +
154217 +typedef uint8_t ioc_header_field_udp_t;
154218 +
154219 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SRC (1)
154220 +#define IOC_NET_HEADER_FIELD_UDP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 1)
154221 +#define IOC_NET_HEADER_FIELD_UDP_LEN (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 2)
154222 +#define IOC_NET_HEADER_FIELD_UDP_CKSUM (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 3)
154223 +#define IOC_NET_HEADER_FIELD_UDP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
154224 +
154225 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SIZE 2
154226 +
154227 +typedef uint8_t ioc_header_field_udp_lite_t;
154228 +
154229 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
154230 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_DST (IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
154231 +#define IOC_NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
154232 +
154233 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
154234 +
154235 +typedef uint8_t ioc_header_field_udp_encap_esp_t;
154236 +
154237 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
154238 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
154239 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
154240 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
154241 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
154242 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
154243 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
154244 +
154245 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
154246 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
154247 +
154248 +#define IOC_NET_HEADER_FIELD_IPHC_CID (1)
154249 +#define IOC_NET_HEADER_FIELD_IPHC_CID_TYPE (IOC_NET_HEADER_FIELD_IPHC_CID << 1)
154250 +#define IOC_NET_HEADER_FIELD_IPHC_HCINDEX (IOC_NET_HEADER_FIELD_IPHC_CID << 2)
154251 +#define IOC_NET_HEADER_FIELD_IPHC_GEN (IOC_NET_HEADER_FIELD_IPHC_CID << 3)
154252 +#define IOC_NET_HEADER_FIELD_IPHC_D_BIT (IOC_NET_HEADER_FIELD_IPHC_CID << 4)
154253 +#define IOC_NET_HEADER_FIELD_IPHC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPHC_CID << 5) - 1)
154254 +
154255 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
154256 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
154257 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
154258 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
154259 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
154260 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
154261 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
154262 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
154263 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
154264 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
154265 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
154266 +
154267 +#define IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
154268 +#define IOC_NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
154269 +#define IOC_NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
154270 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
154271 +#define IOC_NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
154272 +#define IOC_NET_HEADER_FIELD_L2TPv2_VERSION (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
154273 +#define IOC_NET_HEADER_FIELD_L2TPv2_LEN (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
154274 +#define IOC_NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
154275 +#define IOC_NET_HEADER_FIELD_L2TPv2_SESSION_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
154276 +#define IOC_NET_HEADER_FIELD_L2TPv2_NS (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
154277 +#define IOC_NET_HEADER_FIELD_L2TPv2_NR (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
154278 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
154279 +#define IOC_NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
154280 +#define IOC_NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
154281 +
154282 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
154283 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
154284 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
154285 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
154286 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
154287 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
154288 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SENT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
154289 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_RECV (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
154290 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
154291 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
154292 +
154293 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
154294 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
154295 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ID (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
154296 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
154297 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
154298 +
154299 +
154300 +typedef uint8_t ioc_header_field_vlan_t;
154301 +
154302 +#define IOC_NET_HEADER_FIELD_VLAN_VPRI (1)
154303 +#define IOC_NET_HEADER_FIELD_VLAN_CFI (IOC_NET_HEADER_FIELD_VLAN_VPRI << 1)
154304 +#define IOC_NET_HEADER_FIELD_VLAN_VID (IOC_NET_HEADER_FIELD_VLAN_VPRI << 2)
154305 +#define IOC_NET_HEADER_FIELD_VLAN_LENGTH (IOC_NET_HEADER_FIELD_VLAN_VPRI << 3)
154306 +#define IOC_NET_HEADER_FIELD_VLAN_TYPE (IOC_NET_HEADER_FIELD_VLAN_VPRI << 4)
154307 +#define IOC_NET_HEADER_FIELD_VLAN_ALL_FIELDS ((IOC_NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
154308 +
154309 +#define IOC_NET_HEADER_FIELD_VLAN_TCI (IOC_NET_HEADER_FIELD_VLAN_VPRI | \
154310 + IOC_NET_HEADER_FIELD_VLAN_CFI | \
154311 + IOC_NET_HEADER_FIELD_VLAN_VID)
154312 +
154313 +
154314 +typedef uint8_t ioc_header_field_llc_t;
154315 +
154316 +#define IOC_NET_HEADER_FIELD_LLC_DSAP (1)
154317 +#define IOC_NET_HEADER_FIELD_LLC_SSAP (IOC_NET_HEADER_FIELD_LLC_DSAP << 1)
154318 +#define IOC_NET_HEADER_FIELD_LLC_CTRL (IOC_NET_HEADER_FIELD_LLC_DSAP << 2)
154319 +#define IOC_NET_HEADER_FIELD_LLC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
154320 +
154321 +#define IOC_NET_HEADER_FIELD_NLPID_NLPID (1)
154322 +#define IOC_NET_HEADER_FIELD_NLPID_ALL_FIELDS ((IOC_NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
154323 +
154324 +
154325 +typedef uint8_t ioc_header_field_snap_t;
154326 +
154327 +#define IOC_NET_HEADER_FIELD_SNAP_OUI (1)
154328 +#define IOC_NET_HEADER_FIELD_SNAP_PID (IOC_NET_HEADER_FIELD_SNAP_OUI << 1)
154329 +#define IOC_NET_HEADER_FIELD_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
154330 +
154331 +
154332 +typedef uint8_t ioc_header_field_llc_snap_t;
154333 +
154334 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
154335 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
154336 +
154337 +#define IOC_NET_HEADER_FIELD_ARP_HTYPE (1)
154338 +#define IOC_NET_HEADER_FIELD_ARP_PTYPE (IOC_NET_HEADER_FIELD_ARP_HTYPE << 1)
154339 +#define IOC_NET_HEADER_FIELD_ARP_HLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 2)
154340 +#define IOC_NET_HEADER_FIELD_ARP_PLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 3)
154341 +#define IOC_NET_HEADER_FIELD_ARP_OPER (IOC_NET_HEADER_FIELD_ARP_HTYPE << 4)
154342 +#define IOC_NET_HEADER_FIELD_ARP_SHA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 5)
154343 +#define IOC_NET_HEADER_FIELD_ARP_SPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 6)
154344 +#define IOC_NET_HEADER_FIELD_ARP_THA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 7)
154345 +#define IOC_NET_HEADER_FIELD_ARP_TPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 8)
154346 +#define IOC_NET_HEADER_FIELD_ARP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
154347 +
154348 +#define IOC_NET_HEADER_FIELD_RFC2684_LLC (1)
154349 +#define IOC_NET_HEADER_FIELD_RFC2684_NLPID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 1)
154350 +#define IOC_NET_HEADER_FIELD_RFC2684_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 2)
154351 +#define IOC_NET_HEADER_FIELD_RFC2684_PID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 3)
154352 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 4)
154353 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_IDX (IOC_NET_HEADER_FIELD_RFC2684_LLC << 5)
154354 +#define IOC_NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((IOC_NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
154355 +
154356 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
154357 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_PCDID (IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
154358 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
154359 +
154360 +#define IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
154361 +#define IOC_NET_HEADER_FIELD_PAYLOAD_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
154362 +#define IOC_NET_HEADER_FIELD_MAX_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
154363 +#define IOC_NET_HEADER_FIELD_MIN_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
154364 +#define IOC_NET_HEADER_FIELD_PAYLOAD_TYPE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
154365 +#define IOC_NET_HEADER_FIELD_FRAME_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
154366 +#define IOC_NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
154367 +
154368 +
154369 +typedef uint8_t ioc_header_field_gre_t;
154370 +
154371 +#define IOC_NET_HEADER_FIELD_GRE_TYPE (1)
154372 +#define IOC_NET_HEADER_FIELD_GRE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
154373 +
154374 +
154375 +typedef uint8_t ioc_header_field_minencap_t;
154376 +
154377 +#define IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
154378 +#define IOC_NET_HEADER_FIELD_MINENCAP_DST_IP (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
154379 +#define IOC_NET_HEADER_FIELD_MINENCAP_TYPE (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
154380 +#define IOC_NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
154381 +
154382 +
154383 +typedef uint8_t ioc_header_field_ipsec_ah_t;
154384 +
154385 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_SPI (1)
154386 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_NH (IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
154387 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
154388 +
154389 +
154390 +typedef uint8_t ioc_header_field_ipsec_esp_t;
154391 +
154392 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
154393 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
154394 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
154395 +
154396 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
154397 +
154398 +
154399 +typedef uint8_t ioc_header_field_mpls_t;
154400 +
154401 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
154402 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
154403 +
154404 +
154405 +typedef uint8_t ioc_header_field_macsec_t;
154406 +
154407 +#define IOC_NET_HEADER_FIELD_MACSEC_SECTAG (1)
154408 +#define IOC_NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
154409 +
154410 +
154411 +typedef enum {
154412 + e_IOC_NET_HEADER_TYPE_NONE = 0,
154413 + e_IOC_NET_HEADER_TYPE_PAYLOAD,
154414 + e_IOC_NET_HEADER_TYPE_ETH,
154415 + e_IOC_NET_HEADER_TYPE_VLAN,
154416 + e_IOC_NET_HEADER_TYPE_IPv4,
154417 + e_IOC_NET_HEADER_TYPE_IPv6,
154418 + e_IOC_NET_HEADER_TYPE_IP,
154419 + e_IOC_NET_HEADER_TYPE_TCP,
154420 + e_IOC_NET_HEADER_TYPE_UDP,
154421 + e_IOC_NET_HEADER_TYPE_UDP_LITE,
154422 + e_IOC_NET_HEADER_TYPE_IPHC,
154423 + e_IOC_NET_HEADER_TYPE_SCTP,
154424 + e_IOC_NET_HEADER_TYPE_SCTP_CHUNK_DATA,
154425 + e_IOC_NET_HEADER_TYPE_PPPoE,
154426 + e_IOC_NET_HEADER_TYPE_PPP,
154427 + e_IOC_NET_HEADER_TYPE_PPPMUX,
154428 + e_IOC_NET_HEADER_TYPE_PPPMUX_SUBFRAME,
154429 + e_IOC_NET_HEADER_TYPE_L2TPv2,
154430 + e_IOC_NET_HEADER_TYPE_L2TPv3_CTRL,
154431 + e_IOC_NET_HEADER_TYPE_L2TPv3_SESS,
154432 + e_IOC_NET_HEADER_TYPE_LLC,
154433 + e_IOC_NET_HEADER_TYPE_LLC_SNAP,
154434 + e_IOC_NET_HEADER_TYPE_NLPID,
154435 + e_IOC_NET_HEADER_TYPE_SNAP,
154436 + e_IOC_NET_HEADER_TYPE_MPLS,
154437 + e_IOC_NET_HEADER_TYPE_IPSEC_AH,
154438 + e_IOC_NET_HEADER_TYPE_IPSEC_ESP,
154439 + e_IOC_NET_HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
154440 + e_IOC_NET_HEADER_TYPE_MACSEC,
154441 + e_IOC_NET_HEADER_TYPE_GRE,
154442 + e_IOC_NET_HEADER_TYPE_MINENCAP,
154443 + e_IOC_NET_HEADER_TYPE_DCCP,
154444 + e_IOC_NET_HEADER_TYPE_ICMP,
154445 + e_IOC_NET_HEADER_TYPE_IGMP,
154446 + e_IOC_NET_HEADER_TYPE_ARP,
154447 + e_IOC_NET_HEADER_TYPE_CAPWAP,
154448 + e_IOC_NET_HEADER_TYPE_CAPWAP_DTLS,
154449 + e_IOC_NET_HEADER_TYPE_RFC2684,
154450 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L2,
154451 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L3,
154452 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L4,
154453 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM1,
154454 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM2,
154455 + e_IOC_NET_MAX_HEADER_TYPE_COUNT
154456 +} ioc_net_header_type;
154457 +
154458 +
154459 +#endif /* __NET_IOCTLS_H */